1
0
Fork 0

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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3623>
This commit is contained in:
Jonas Dreßler 2024-02-27 19:09:53 +01:00 committed by Marge Bot
parent 6a31664a42
commit 58290cca57
3 changed files with 38 additions and 42 deletions

View file

@ -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
{

View file

@ -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);

View file

@ -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