sway

i3-compatible Wayland compositor
git clone https://git.awy.one/sway
Log | Files | Refs | README | LICENSE

commit 69b430201cb19c666f102586b18f1dfbda7c44a3
parent 518e18a54b9fc07682b46f6bb3bb848ff8760a7f
Author: Tuomas Yrjölä <mail@yrhki.fi>
Date:   Mon, 17 Jan 2022 19:47:42 +0200

xwayland: listen to `request_activate` event

When REAPER submenu is closed `XCB_CLIENT_MESSAGE` with type
`NET_ACTIVE_WINDOW` is sent to set focus to parent menu.

Closes: https://github.com/swaywm/sway/issues/6324

Diffstat:
Minclude/sway/tree/view.h | 1+
Msway/desktop/xwayland.c | 17+++++++++++++++++
2 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h @@ -169,6 +169,7 @@ struct sway_xwayland_unmanaged { int lx, ly; + struct wl_listener request_activate; struct wl_listener request_configure; struct wl_listener request_fullscreen; struct wl_listener commit; diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c @@ -121,6 +121,20 @@ static void unmanaged_handle_unmap(struct wl_listener *listener, void *data) { } } +static void unmanaged_handle_request_activate(struct wl_listener *listener, void *data) { + struct wlr_xwayland_surface *xsurface = data; + if (!xsurface->mapped) { + return; + } + struct sway_seat *seat = input_manager_current_seat(); + struct sway_container *focus = seat_get_focused_container(seat); + if (focus && focus->view && focus->view->pid != xsurface->pid) { + return; + } + + seat_set_focus_surface(seat, xsurface->surface, false); +} + static void unmanaged_handle_destroy(struct wl_listener *listener, void *data) { struct sway_xwayland_unmanaged *surface = wl_container_of(listener, surface, destroy); @@ -129,6 +143,7 @@ static void unmanaged_handle_destroy(struct wl_listener *listener, void *data) { wl_list_remove(&surface->unmap.link); wl_list_remove(&surface->destroy.link); wl_list_remove(&surface->override_redirect.link); + wl_list_remove(&surface->request_activate.link); free(surface); } @@ -176,6 +191,8 @@ static struct sway_xwayland_unmanaged *create_unmanaged( surface->destroy.notify = unmanaged_handle_destroy; wl_signal_add(&xsurface->events.set_override_redirect, &surface->override_redirect); surface->override_redirect.notify = unmanaged_handle_override_redirect; + wl_signal_add(&xsurface->events.request_activate, &surface->request_activate); + surface->request_activate.notify = unmanaged_handle_request_activate; return surface; }