From 58290cca57f2116e9390b9e6129b142b77c61af3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= Date: Tue, 27 Feb 2024 19:09:53 +0100 Subject: [PATCH] window: Stop event propagation for drag and window-menu triggering events meta_window_handle_ungrabbed_event() triggers the show of the window menu in gnome-shell via meta_window_show_menu() on hold of Meta + right mouse button click. Since meta_display_handle_event() was refactored lately and now forwards a lot more events to Clutter (including the one triggering the window menu), gnome-shell now sees this event after the menu has opened, figures that the source-actor is outside of the menu, and immediately closes the menu again. This is the correct behavior from the PopupMenuManager on the gnome-shell side, it is the responsibility of the event handler that opens the menu (aka meta_window_handle_ungrabbed_event()) to return CLUTTER_EVENT_STOP and stop event propagation. So fix this issue by adding a return value to meta_window_handle_ungrabbed_event() and stopping event propagation in case the event opened the window menu. While at it, also return CLUTTER_EVENT_STOP for events triggering window drags, so we can drop the extra check for that in meta_display_handle_event(). Part-of: --- src/core/events.c | 33 ++++++++++-------------------- src/core/window-private.h | 4 ++-- src/core/window.c | 43 +++++++++++++++++++++++---------------- 3 files changed, 38 insertions(+), 42 deletions(-) diff --git a/src/core/events.c b/src/core/events.c index ff7299e37..f766b806d 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -426,31 +426,20 @@ meta_display_handle_event (MetaDisplay *display, if (window) { - meta_window_handle_ungrabbed_event (window, event); + if (meta_window_handle_ungrabbed_event (window, event)) + return CLUTTER_EVENT_STOP; - /* This might start a grab op. If it does, then filter out the - * event, and if it doesn't, replay the event to release our - * own sync grab. */ - - if (meta_compositor_get_current_window_drag (compositor)) - { - return CLUTTER_EVENT_STOP; - } - else - { - /* Only replay button press events, since that's where we - * have the synchronous grab. */ #ifdef HAVE_X11_CLIENT - maybe_unfreeze_pointer_events (backend, event, EVENTS_UNFREEZE_REPLAY); + /* Now replay the button press event to release our own sync grab. */ + maybe_unfreeze_pointer_events (backend, event, EVENTS_UNFREEZE_REPLAY); #endif - /* If the focus window has an active close dialog let clutter - * events go through, so fancy clutter dialogs can get to handle - * all events. - */ - if (window->close_dialog && - meta_close_dialog_is_visible (window->close_dialog)) - return CLUTTER_EVENT_PROPAGATE; - } + /* If the focus window has an active close dialog let clutter + * events go through, so fancy clutter dialogs can get to handle + * all events. + */ + if (window->close_dialog && + meta_close_dialog_is_visible (window->close_dialog)) + return CLUTTER_EVENT_PROPAGATE; } else { diff --git a/src/core/window-private.h b/src/core/window-private.h index 2a6c6a799..3c6d94ef3 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -797,8 +797,8 @@ void meta_window_set_transient_for (MetaWindow *window, void meta_window_set_opacity (MetaWindow *window, guint8 opacity); -void meta_window_handle_ungrabbed_event (MetaWindow *window, - const ClutterEvent *event); +gboolean meta_window_handle_ungrabbed_event (MetaWindow *window, + const ClutterEvent *event); void meta_window_get_client_area_rect (const MetaWindow *window, MtkRectangle *rect); diff --git a/src/core/window.c b/src/core/window.c index 198cc09cf..62a98e070 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -7339,7 +7339,7 @@ meta_window_has_pointer (MetaWindow *window) #endif } -void +gboolean meta_window_handle_ungrabbed_event (MetaWindow *window, const ClutterEvent *event) { @@ -7355,14 +7355,14 @@ meta_window_handle_ungrabbed_event (MetaWindow *window, guint button; if (window->unmanaging) - return; + return CLUTTER_EVENT_PROPAGATE; event_type = clutter_event_type (event); time_ms = clutter_event_get_time (event); if (event_type != CLUTTER_BUTTON_PRESS && event_type != CLUTTER_TOUCH_BEGIN) - return; + return CLUTTER_EVENT_PROPAGATE; if (event_type == CLUTTER_TOUCH_BEGIN) { @@ -7371,7 +7371,7 @@ meta_window_handle_ungrabbed_event (MetaWindow *window, button = 1; sequence = clutter_event_get_event_sequence (event); if (!meta_display_is_pointer_emulating_sequence (window->display, sequence)) - return; + return CLUTTER_EVENT_PROPAGATE; } else button = clutter_event_get_button (event); @@ -7381,7 +7381,7 @@ meta_window_handle_ungrabbed_event (MetaWindow *window, * we have to take special care not to act for an override-redirect window. */ if (window->override_redirect) - return; + return CLUTTER_EVENT_PROPAGATE; /* Don't focus panels--they must explicitly request focus. * See bug 160470 @@ -7462,12 +7462,13 @@ meta_window_handle_ungrabbed_event (MetaWindow *window, if (op != META_GRAB_OP_WINDOW_BASE) { op |= META_GRAB_OP_WINDOW_FLAG_UNCONSTRAINED; - meta_window_begin_grab_op (window, - op, - clutter_event_get_device (event), - clutter_event_get_event_sequence (event), - time_ms, - NULL); + if (meta_window_begin_grab_op (window, + op, + clutter_event_get_device (event), + clutter_event_get_event_sequence (event), + time_ms, + NULL)) + return CLUTTER_EVENT_STOP; } } } @@ -7475,23 +7476,29 @@ meta_window_handle_ungrabbed_event (MetaWindow *window, { if (meta_prefs_get_raise_on_click ()) meta_window_raise (window); + meta_window_show_menu (window, META_WINDOW_MENU_WM, x, y); + + return CLUTTER_EVENT_STOP; } else if (is_window_grab && (int) button == 1) { if (window->has_move_func) { - meta_window_begin_grab_op (window, - META_GRAB_OP_MOVING | - META_GRAB_OP_WINDOW_FLAG_UNCONSTRAINED, - clutter_event_get_device (event), - clutter_event_get_event_sequence (event), - time_ms, - NULL); + if (meta_window_begin_grab_op (window, + META_GRAB_OP_MOVING | + META_GRAB_OP_WINDOW_FLAG_UNCONSTRAINED, + clutter_event_get_device (event), + clutter_event_get_event_sequence (event), + time_ms, + NULL)) + return CLUTTER_EVENT_STOP; } } + + return CLUTTER_EVENT_PROPAGATE; } gboolean