From d902088bfc9678bbd4a57eec64703869fe28d9db Mon Sep 17 00:00:00 2001 From: Hideyuki Nagase Date: Thu, 10 Mar 2022 12:34:17 -0600 Subject: [PATCH] xwayland: support minimizing Allow minimizing xwayland windows. Co-authored-by: Steve Pronovost Co-authored-by: Brenton DeGeer Signed-off-by: Hideyuki Nagase Signed-off-by: Steve Pronovost Signed-off-by: Brenton DeGeer --- libweston-desktop/xwayland.c | 8 +++++++ shared/xcb-xwayland.c | 1 + shared/xcb-xwayland.h | 1 + xwayland/window-manager.c | 33 ++++++++++++++++++++++++++ xwayland/xwayland-internal-interface.h | 1 + 5 files changed, 44 insertions(+) diff --git a/libweston-desktop/xwayland.c b/libweston-desktop/xwayland.c index ae6a92e4..f40bb5db 100644 --- a/libweston-desktop/xwayland.c +++ b/libweston-desktop/xwayland.c @@ -400,6 +400,13 @@ set_maximized(struct weston_desktop_xwayland_surface *surface) surface->surface, true); } +static void +set_minimized(struct weston_desktop_xwayland_surface *surface) +{ + weston_desktop_api_minimized_requested(surface->desktop, + surface->surface); +} + static void set_pid(struct weston_desktop_xwayland_surface *surface, pid_t pid) { @@ -419,6 +426,7 @@ static const struct weston_desktop_xwayland_interface weston_desktop_xwayland_in .set_title = set_title, .set_window_geometry = set_window_geometry, .set_maximized = set_maximized, + .set_minimized = set_minimized, .set_pid = set_pid, }; diff --git a/shared/xcb-xwayland.c b/shared/xcb-xwayland.c index fe801198..737c82a5 100644 --- a/shared/xcb-xwayland.c +++ b/shared/xcb-xwayland.c @@ -77,6 +77,7 @@ x11_get_atoms(xcb_connection_t *connection, struct atom_x11 *atom) { "WM_STATE", F(wm_state) }, { "WM_S0", F(wm_s0) }, { "WM_CLIENT_MACHINE", F(wm_client_machine) }, + { "WM_CHANGE_STATE", F(wm_change_state) }, { "_NET_WM_CM_S0", F(net_wm_cm_s0) }, { "_NET_WM_NAME", F(net_wm_name) }, { "_NET_WM_PID", F(net_wm_pid) }, diff --git a/shared/xcb-xwayland.h b/shared/xcb-xwayland.h index f4f03954..7b233ede 100644 --- a/shared/xcb-xwayland.h +++ b/shared/xcb-xwayland.h @@ -39,6 +39,7 @@ struct atom_x11 { xcb_atom_t wm_state; xcb_atom_t wm_s0; xcb_atom_t wm_client_machine; + xcb_atom_t wm_change_state; xcb_atom_t net_wm_cm_s0; xcb_atom_t net_wm_name; xcb_atom_t net_wm_pid; diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c index ff9eddf7..c75e0102 100644 --- a/xwayland/window-manager.c +++ b/xwayland/window-manager.c @@ -1057,6 +1057,9 @@ weston_wm_window_create_frame(struct weston_wm_window *window) if (window->decorate & MWM_DECOR_MAXIMIZE) buttons |= FRAME_BUTTON_MAXIMIZE; + if (window->decorate & MWM_DECOR_MINIMIZE) + buttons |= FRAME_BUTTON_MINIMIZE; + window->frame = frame_create(window->wm->theme, window->width, window->height, buttons, window->name, NULL); @@ -1803,6 +1806,27 @@ weston_wm_window_handle_state(struct weston_wm_window *window, } } +static void +weston_wm_window_handle_iconic_state(struct weston_wm_window *window, + xcb_client_message_event_t *client_message) +{ + struct weston_wm *wm = window->wm; + const struct weston_desktop_xwayland_interface *xwayland_interface = + wm->server->compositor->xwayland_interface; + uint32_t iconic_state; + + if (!window->shsurf) + return; + + iconic_state = client_message->data.data32[0]; + + if (iconic_state == ICCCM_ICONIC_STATE) { + window->saved_height = window->height; + window->saved_width = window->width; + xwayland_interface->set_minimized(window->shsurf); + } +} + static void surface_destroy(struct wl_listener *listener, void *data) { @@ -1880,6 +1904,8 @@ weston_wm_handle_client_message(struct weston_wm *wm, weston_wm_window_handle_state(window, client_message); else if (client_message->type == wm->atom.wl_surface_id) weston_wm_window_handle_surface_id(window, client_message); + else if (client_message->type == wm->atom.wm_change_state) + weston_wm_window_handle_iconic_state(window, client_message); } enum cursor_type { @@ -2163,6 +2189,13 @@ weston_wm_handle_button(struct weston_wm *wm, xcb_generic_event_t *event) } frame_status_clear(window->frame, FRAME_STATUS_MAXIMIZE); } + + if (frame_status(window->frame) & FRAME_STATUS_MINIMIZE) { + window->saved_width = window->width; + window->saved_height = window->height; + xwayland_interface->set_minimized(window->shsurf); + frame_status_clear(window->frame, FRAME_STATUS_MINIMIZE); + } } static void diff --git a/xwayland/xwayland-internal-interface.h b/xwayland/xwayland-internal-interface.h index c7dfd19b..a97d13bc 100644 --- a/xwayland/xwayland-internal-interface.h +++ b/xwayland/xwayland-internal-interface.h @@ -59,6 +59,7 @@ struct weston_desktop_xwayland_interface { int32_t x, int32_t y, int32_t width, int32_t height); void (*set_maximized)(struct weston_desktop_xwayland_surface *shsurf); + void (*set_minimized)(struct weston_desktop_xwayland_surface *shsurf); void (*set_pid)(struct weston_desktop_xwayland_surface *shsurf, pid_t pid); };