From 9b914538926c039bf4cb8af82b4dbebc9d8b546b Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Sat, 19 Feb 2022 19:51:39 -0500 Subject: [PATCH] Implement cursor input for unmanaged XWayland surfaces This is necessary for menus in X11 apps to work properly. Otherwise, any region of the menu that extended out beyond the main application window was not receiving any mouse input. Adapted from sway's code. --- src/cursor.c | 20 ++++++++++++++++++-- src/desktop.c | 16 ++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/cursor.c b/src/cursor.c index 8e3227c7..03117baf 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -642,8 +642,16 @@ cursor_button(struct wl_listener *listener, void *data) cursor_rebase(&server->seat, event->time_msec); } - /* Handle _release_ on root window */ if (!view) { +#if HAVE_XWAYLAND + /* Handle _release_ on unmanaged surface */ + if (surface && wlr_surface_is_xwayland_surface(surface)) { + wlr_seat_pointer_notify_button(seat->seat, + event->time_msec, event->button, event->state); + return; + } +#endif + /* Handle _release_ on root window */ handle_release_mousebinding(NULL, server, event->button, modifiers, LAB_SSD_ROOT, 0); } @@ -661,8 +669,16 @@ cursor_button(struct wl_listener *listener, void *data) return; } - /* Handle _press_ on a layer surface */ if (!view && surface) { +#if HAVE_XWAYLAND + /* Handle _press_ on unmanaged surface */ + if (wlr_surface_is_xwayland_surface(surface)) { + wlr_seat_pointer_notify_button(seat->seat, + event->time_msec, event->button, event->state); + return; + } +#endif + /* Handle _press_ on a layer surface */ if (!wlr_surface_is_layer_surface(surface)) { return; } diff --git a/src/desktop.c b/src/desktop.c index 9d80da0f..93875507 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -365,6 +365,22 @@ desktop_surface_and_view_at(struct server *server, double lx, double ly, return NULL; } + /* Check for unmanaged surfaces */ +#if HAVE_XWAYLAND + struct xwayland_unmanaged *unmanaged_surface; + wl_list_for_each_reverse(unmanaged_surface, &server->unmanaged_surfaces, link) { + double _sx = lx - unmanaged_surface->lx; + double _sy = ly - unmanaged_surface->ly; + if (wlr_surface_point_accepts_input(unmanaged_surface-> + xwayland_surface->surface, _sx, _sy)) { + *surface = unmanaged_surface->xwayland_surface->surface; + *sx = _sx; + *sy = _sy; + return NULL; + } + } +#endif + /* Check all layer popups */ *surface = layer_surface_popup_at(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],