Restore original window geometry after tiling

Fixes #391
This commit is contained in:
Consolatis 2022-06-19 01:28:52 +02:00
parent ca56357b5f
commit 172e757cea
3 changed files with 60 additions and 20 deletions

View file

@ -306,6 +306,7 @@ struct view {
bool been_mapped; bool been_mapped;
bool minimized; bool minimized;
bool maximized; bool maximized;
bool is_tiled;
struct wlr_output *fullscreen; struct wlr_output *fullscreen;
/* geometry of the wlr_surface contained within the view */ /* geometry of the wlr_surface contained within the view */
@ -314,6 +315,9 @@ struct view {
/* geometry before maximize */ /* geometry before maximize */
struct wlr_box unmaximized_geometry; struct wlr_box unmaximized_geometry;
/* geometry before tiling */
struct wlr_box untiled_geometry;
/* /*
* margin refers to the space between the extremities of the * margin refers to the space between the extremities of the
* wlr_surface and the max extents of the server-side decorations. * wlr_surface and the max extents of the server-side decorations.

View file

@ -17,28 +17,46 @@ max_move_scale(double pos_cursor, double pos_current,
void void
interactive_begin(struct view *view, enum input_mode mode, uint32_t edges) interactive_begin(struct view *view, enum input_mode mode, uint32_t edges)
{ {
if (view->maximized) { if (mode == LAB_INPUT_STATE_RESIZE && view->maximized) {
if (mode == LAB_INPUT_STATE_MOVE) {
int new_x = max_move_scale(view->server->seat.cursor->x,
view->x, view->w, view->unmaximized_geometry.width);
int new_y = max_move_scale(view->server->seat.cursor->y,
view->y, view->h, view->unmaximized_geometry.height);
view->unmaximized_geometry.x = new_x;
view->unmaximized_geometry.y = new_y;
view_maximize(view, false);
/*
* view_maximize() indirectly calls view->impl->configure
* which is async but we are using the current values in
* server->grab_box. We pretend the configure already
* happened by setting them manually.
*/
view->x = new_x;
view->y = new_y;
view->w = view->unmaximized_geometry.width;
view->h = view->unmaximized_geometry.height;
} else {
return; return;
} }
if (mode == LAB_INPUT_STATE_MOVE && (view->maximized || view->is_tiled)) {
/**
* Disable tiling or maximized mode by resizing to the old size
* but modifying the x and y coordinates to match the cursor.
*/
/* Order of branches matter, a view may be maximized and tiled */
struct wlr_box *old_geo;
if (view->is_tiled) {
old_geo = &view->untiled_geometry;
} else {
old_geo = &view->unmaximized_geometry;
}
/* Recalculate x and y based on cursor position */
old_geo->x = max_move_scale(view->server->seat.cursor->x,
view->x, view->w, old_geo->width);
old_geo->y = max_move_scale(view->server->seat.cursor->y,
view->y, view->h, old_geo->height);
if (view->is_tiled) {
view_move_resize(view, *old_geo);
view->is_tiled = false;
view->maximized = false;
} else {
view_maximize(view, false);
}
/**
* view_move_resize() / view_maximize() indirectly calls
* view->impl->configure which is async but we are using
* the current values in server->grab_box. We pretend the
* configure already happened by setting them manually.
*/
view->x = old_geo->x;
view->y = old_geo->y;
view->w = old_geo->width;
view->h = old_geo->height;
} }
/* /*
@ -65,6 +83,7 @@ interactive_begin(struct view *view, enum input_mode mode, uint32_t edges)
cursor_set(&server->seat, "grab"); cursor_set(&server->seat, "grab");
break; break;
case LAB_INPUT_STATE_RESIZE: case LAB_INPUT_STATE_RESIZE:
view->is_tiled = false;
cursor_set(&server->seat, wlr_xcursor_get_resize_name(edges)); cursor_set(&server->seat, wlr_xcursor_get_resize_name(edges));
break; break;
default: default:

View file

@ -668,6 +668,23 @@ view_snap_to_edge(struct view *view, const char *direction)
view_edge_invert(edge)); view_edge_invert(edge));
} }
/* Remember old geometry */
if (!view->is_tiled) {
if (!view->maximized) {
/* Store current geometry */
view->untiled_geometry.x = view->x;
view->untiled_geometry.y = view->y;
view->untiled_geometry.width = view->w;
view->untiled_geometry.height = view->h;
} else {
/* Reuse unmaximized geometry */
memcpy(&view->untiled_geometry, &view->unmaximized_geometry,
sizeof(view->untiled_geometry));
}
view->is_tiled = true;
}
view->maximized = false;
if (view->w == dst.width && view->h == dst.height) { if (view->w == dst.width && view->h == dst.height) {
/* move horizontally/vertically without changing size */ /* move horizontally/vertically without changing size */
view_move(view, dst.x, dst.y); view_move(view, dst.x, dst.y);