From d19c795bd5067b37a9b2db795af3ff2b1c1b8fe0 Mon Sep 17 00:00:00 2001 From: Erik Reider Date: Mon, 20 Mar 2023 22:18:13 +0100 Subject: [PATCH] Extend minimize logic --- include/sway/tree/view.h | 1 + sway/desktop/xdg_shell.c | 24 ++++++++++++++++++++++++ sway/desktop/xwayland.c | 24 +++++++++++++++++++++--- sway/tree/root.c | 17 +++++++++++++++++ 4 files changed, 63 insertions(+), 3 deletions(-) diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 684d13a0..9d468612 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -134,6 +134,7 @@ struct sway_xdg_shell_view { struct wl_listener request_move; struct wl_listener request_resize; struct wl_listener request_maximize; + struct wl_listener request_minimize; struct wl_listener request_fullscreen; struct wl_listener set_title; struct wl_listener set_app_id; diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 8da922d5..0f9d3868 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -332,6 +332,25 @@ static void handle_request_maximize(struct wl_listener *listener, void *data) { wlr_xdg_surface_schedule_configure(toplevel->base); } +/* Minimize to scratchpad */ +static void handle_request_minimize(struct wl_listener *listener, void *data) { + struct sway_xdg_shell_view *xdg_shell_view = + wl_container_of(listener, xdg_shell_view, request_minimize); + + struct sway_container *container = xdg_shell_view->view.container; + if (!container->pending.workspace) { + while (container->pending.parent) { + container = container->pending.parent; + } + } + if (!container->scratchpad) { + root_scratchpad_add_container(container, NULL); + } else if (container->pending.workspace) { + root_scratchpad_hide(container); + } + transaction_commit_dirty(); +} + static void handle_request_fullscreen(struct wl_listener *listener, void *data) { struct sway_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, request_fullscreen); @@ -406,6 +425,7 @@ static void handle_unmap(struct wl_listener *listener, void *data) { wl_list_remove(&xdg_shell_view->commit.link); wl_list_remove(&xdg_shell_view->new_popup.link); wl_list_remove(&xdg_shell_view->request_maximize.link); + wl_list_remove(&xdg_shell_view->request_minimize.link); wl_list_remove(&xdg_shell_view->request_fullscreen.link); wl_list_remove(&xdg_shell_view->request_move.link); wl_list_remove(&xdg_shell_view->request_resize.link); @@ -458,6 +478,10 @@ static void handle_map(struct wl_listener *listener, void *data) { wl_signal_add(&toplevel->events.request_maximize, &xdg_shell_view->request_maximize); + xdg_shell_view->request_minimize.notify = handle_request_minimize; + wl_signal_add(&toplevel->events.request_minimize, + &xdg_shell_view->request_minimize); + xdg_shell_view->request_fullscreen.notify = handle_request_fullscreen; wl_signal_add(&toplevel->events.request_fullscreen, &xdg_shell_view->request_fullscreen); diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index e15a3341..3352c993 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c @@ -575,6 +575,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) transaction_commit_dirty(); } +/* Minimize to scratchpad */ static void handle_request_minimize(struct wl_listener *listener, void *data) { struct sway_xwayland_view *xwayland_view = wl_container_of(listener, xwayland_view, request_minimize); @@ -585,9 +586,26 @@ static void handle_request_minimize(struct wl_listener *listener, void *data) { } struct wlr_xwayland_minimize_event *e = data; - struct sway_seat *seat = input_manager_current_seat(); - bool focused = seat_get_focus(seat) == &view->container->node; - wlr_xwayland_surface_set_minimized(xsurface, !focused && e->minimize); + struct sway_container *container = view->container; + if (!container->pending.workspace) { + while (container->pending.parent) { + container = container->pending.parent; + } + } + if(e->minimize) { + if (!container->scratchpad) { + root_scratchpad_add_container(container, NULL); + } else if (container->pending.workspace) { + root_scratchpad_hide(container); + } + wlr_xwayland_surface_set_minimized(xsurface, true); + } else { + if(container->scratchpad) { + root_scratchpad_show(container); + wlr_xwayland_surface_set_minimized(xsurface, false); + } + } + transaction_commit_dirty(); } static void handle_request_move(struct wl_listener *listener, void *data) { diff --git a/sway/tree/root.c b/sway/tree/root.c index 8934721f..89ea171e 100644 --- a/sway/tree/root.c +++ b/sway/tree/root.c @@ -111,6 +111,17 @@ void root_scratchpad_remove_container(struct sway_container *con) { } } +/* Set minimized state from scratchpad container `show` state */ +static void root_handle_container(struct sway_container *con, bool show) { + struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel = con->view->foreign_toplevel; + struct wlr_xwayland_surface *xsurface = con->view->wlr_xwayland_surface; + if (xsurface) { + wlr_xwayland_surface_set_minimized(xsurface, !show); + } else if (foreign_toplevel) { + wlr_foreign_toplevel_handle_v1_set_minimized(foreign_toplevel, !show); + } +} + void root_scratchpad_show(struct sway_container *con) { struct sway_seat *seat = input_manager_current_seat(); struct sway_workspace *new_ws = seat_get_focused_workspace(seat); @@ -141,6 +152,9 @@ void root_scratchpad_show(struct sway_container *con) { } workspace_add_floating(new_ws, con); + // Set minimize state to normalized + root_handle_container(con, true); + // Make sure the container's center point overlaps this workspace double center_lx = con->pending.x + con->pending.width / 2; double center_ly = con->pending.y + con->pending.height / 2; @@ -172,6 +186,9 @@ void root_scratchpad_hide(struct sway_container *con) { return; } + // Set minimize state to minimized + root_handle_container(con, false); + disable_fullscreen(con, NULL); container_for_each_child(con, disable_fullscreen, NULL); container_detach(con);