From 22362378ea2fba38f54cc28eca5c61215e66cf48 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 6 Aug 2024 15:31:08 +0200 Subject: [PATCH] wayland: Track pressed mouse buttons for popup grabs through modifiers Move away from tracking presses/releases directly, since there might be other event handlers on top that might prevent the popup event handler to fully track all events. The replacement is using event state modifiers, which will use information set from the backend, and is enough to determine there's no more pressed buttons without tracking prior event history. This makes the popup event handler able to interact with other event handlers that might be on top, and consume button release events for themselves (e.g. DnD), no longer resulting in a stuck popup grab. Part-of: --- src/wayland/meta-wayland-popup.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/wayland/meta-wayland-popup.c b/src/wayland/meta-wayland-popup.c index edd0407bc..dfd757990 100644 --- a/src/wayland/meta-wayland-popup.c +++ b/src/wayland/meta-wayland-popup.c @@ -56,8 +56,6 @@ struct _MetaWaylandPopupGrab MetaWaylandSeat *seat; MetaWaylandEventHandler *handler; - int press_count; - struct wl_client *grab_client; struct wl_list all_popups; }; @@ -140,18 +138,6 @@ popup_grab_focus (MetaWaylandEventHandler *handler, meta_wayland_event_handler_chain_up_focus (handler, device, sequence, surface); } -static gboolean -popup_grab_press (MetaWaylandEventHandler *handler, - const ClutterEvent *event, - gpointer user_data) -{ - MetaWaylandPopupGrab *popup_grab = user_data; - - popup_grab->press_count++; - - return CLUTTER_EVENT_PROPAGATE; -} - static gboolean popup_grab_release (MetaWaylandEventHandler *handler, const ClutterEvent *event, @@ -162,9 +148,12 @@ popup_grab_release (MetaWaylandEventHandler *handler, ClutterEventSequence *sequence = clutter_event_get_event_sequence (event); gboolean close_popup; - close_popup = popup_grab->press_count == 1; - - popup_grab->press_count = MAX (0, popup_grab->press_count - 1); + close_popup = __builtin_popcount (clutter_event_get_state (event) & + (CLUTTER_BUTTON1_MASK | + CLUTTER_BUTTON2_MASK | + CLUTTER_BUTTON3_MASK | + CLUTTER_BUTTON4_MASK | + CLUTTER_BUTTON5_MASK)) <= 1; if (close_popup) { @@ -188,7 +177,7 @@ static MetaWaylandEventInterface popup_event_interface = { popup_grab_get_focus_surface, popup_grab_focus, NULL, /* motion */ - popup_grab_press, + NULL, /* press */ popup_grab_release, };