diff --git a/src/interactive.c b/src/interactive.c index c4dde0cc..d0d8f808 100644 --- a/src/interactive.c +++ b/src/interactive.c @@ -17,29 +17,49 @@ max_move_scale(double pos_cursor, double pos_current, void interactive_begin(struct view *view, enum input_mode mode, uint32_t edges) { - if (view->maximized) { + if (mode == LAB_INPUT_STATE_MOVE && view->fullscreen) { + /** + * We don't allow moving fullscreen windows. + * + * If you think there is a good reason to allow it + * feel free to open an issue explaining your use-case. + */ + return; + } + if (mode == LAB_INPUT_STATE_RESIZE + && (view->fullscreen || view->maximized)) { + /* We don't allow resizing while in maximized or fullscreen state */ + return; + } + if (view->maximized || view->tiled) { if (mode == LAB_INPUT_STATE_MOVE) { + /* Exit maximized or tiled mode */ int new_x = max_move_scale(view->server->seat.cursor->x, view->x, view->w, view->natural_geometry.width); int new_y = max_move_scale(view->server->seat.cursor->y, view->y, view->h, view->natural_geometry.height); view->natural_geometry.x = new_x; view->natural_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. + if (view->maximized) { + view_maximize(view, false); + } + if (view->tiled) { + view_move_resize(view, view->natural_geometry); + } + /** + * view_maximize() / view_move_resize() 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->natural_geometry.width; view->h = view->natural_geometry.height; - } else { - return; } } + + /* Moving or resizing always resets tiled state */ view->tiled = 0; /* diff --git a/src/view.c b/src/view.c index af291228..b833c372 100644 --- a/src/view.c +++ b/src/view.c @@ -215,6 +215,15 @@ view_wlr_output(struct view *view) return wlr_output; } +static void +view_store_natural_geometry(struct view *view) +{ + view->natural_geometry.x = view->x; + view->natural_geometry.y = view->y; + view->natural_geometry.width = view->w; + view->natural_geometry.height = view->h; +} + static struct output * view_output(struct view *view) { @@ -398,11 +407,9 @@ view_maximize(struct view *view, bool maximize) } if (maximize) { interactive_end(view); - view->natural_geometry.x = view->x; - view->natural_geometry.y = view->y; - view->natural_geometry.width = view->w; - view->natural_geometry.height = view->h; - + if (!view->tiled) { + view_store_natural_geometry(view); + } view_apply_maximized_geometry(view); view->maximized = true; } else { @@ -493,11 +500,8 @@ view_set_fullscreen(struct view *view, bool fullscreen, wlr_output = view_wlr_output(view); } if (fullscreen) { - if (!view->maximized) { - view->natural_geometry.x = view->x; - view->natural_geometry.y = view->y; - view->natural_geometry.width = view->w; - view->natural_geometry.height = view->h; + if (!view->maximized && !view->tiled) { + view_store_natural_geometry(view); } view->fullscreen = wlr_output; view_apply_fullscreen_geometry(view, view->fullscreen); @@ -710,10 +714,12 @@ view_snap_to_edge(struct view *view, const char *direction) } if (view->maximized) { + /* Unmaximize + keep using existing natural_geometry */ view_maximize(view, false); + } else if (!view->tiled) { + /* store current geometry as new natural_geometry */ + view_store_natural_geometry(view); } - - /* TODO: store old geometry if !maximized && !fullscreen && !tiled */ view->tiled = edge; view_apply_tiled_geometry(view, output); }