1
0
Fork 0

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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3937>
(cherry picked from commit 22362378ea)
This commit is contained in:
Carlos Garnacho 2024-08-06 15:31:08 +02:00 committed by Jonas Ådahl
parent 081b918bac
commit 99808a3365

View file

@ -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,
};