core: Handle redirection changes in and out of ClutterGrab grabs

Wayland event processing and WM operations are themselves outside the
ClutterGrab loop so far. Until this is sorted out, these pieces of
event handling have got to learn to stay aside while there is a
ClutterGrab going on.

So, synchronize foci and other state when grabs come in or out, and
make it sure that Wayland event processing does not happen while
grabs happen.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2099>
This commit is contained in:
Carlos Garnacho 2021-11-17 23:31:11 +01:00 committed by Marge Bot
parent 0e234d76f4
commit a840c039a0
7 changed files with 67 additions and 5 deletions

View File

@ -3677,6 +3677,7 @@ clutter_stage_notify_grab_on_pointer_entry (ClutterStage *stage,
grab_actor : old_grab_actor, grab_actor : old_grab_actor,
entry->coords, entry->coords,
CLUTTER_CURRENT_TIME); CLUTTER_CURRENT_TIME);
if (!_clutter_event_process_filters (event))
_clutter_actor_handle_event (deepmost, topmost, event); _clutter_actor_handle_event (deepmost, topmost, event);
clutter_event_free (event); clutter_event_free (event);
} }

View File

@ -82,6 +82,9 @@ gboolean meta_compositor_is_switching_workspace (MetaCompositor *compositor);
MetaLaters * meta_compositor_get_laters (MetaCompositor *compositor); MetaLaters * meta_compositor_get_laters (MetaCompositor *compositor);
void meta_compositor_grab_begin (MetaCompositor *compositor);
void meta_compositor_grab_end (MetaCompositor *compositor);
/* /*
* This function takes a 64 bit time stamp from the monotonic clock, and clamps * This function takes a 64 bit time stamp from the monotonic clock, and clamps
* it to the scope of the X server clock, without losing the granularity. * it to the scope of the X server clock, without losing the granularity.

View File

@ -374,13 +374,13 @@ grab_devices (MetaModalOptions options,
return FALSE; return FALSE;
} }
static void void
meta_compositor_grab_begin (MetaCompositor *compositor) meta_compositor_grab_begin (MetaCompositor *compositor)
{ {
META_COMPOSITOR_GET_CLASS (compositor)->grab_begin (compositor); META_COMPOSITOR_GET_CLASS (compositor)->grab_begin (compositor);
} }
static void void
meta_compositor_grab_end (MetaCompositor *compositor) meta_compositor_grab_end (MetaCompositor *compositor)
{ {
META_COMPOSITOR_GET_CLASS (compositor)->grab_end (compositor); META_COMPOSITOR_GET_CLASS (compositor)->grab_end (compositor);

View File

@ -197,6 +197,7 @@ struct _MetaDisplay
/* Opening the display */ /* Opening the display */
unsigned int display_opening : 1; unsigned int display_opening : 1;
unsigned int grabbed_in_clutter : 1;
/* Closing down the display */ /* Closing down the display */
int closing; int closing;

View File

@ -28,6 +28,7 @@
#include "backends/meta-idle-manager.h" #include "backends/meta-idle-manager.h"
#include "backends/x11/meta-backend-x11.h" #include "backends/x11/meta-backend-x11.h"
#include "backends/x11/meta-input-device-x11.h" #include "backends/x11/meta-input-device-x11.h"
#include "compositor/compositor-private.h"
#include "compositor/meta-window-actor-private.h" #include "compositor/meta-window-actor-private.h"
#include "core/display-private.h" #include "core/display-private.h"
#include "core/window-private.h" #include "core/window-private.h"
@ -67,6 +68,16 @@ stage_has_key_focus (void)
return clutter_stage_get_key_focus (CLUTTER_STAGE (stage)) == stage; return clutter_stage_get_key_focus (CLUTTER_STAGE (stage)) == stage;
} }
static gboolean
stage_has_grab (MetaDisplay *display)
{
MetaContext *context = meta_display_get_context (display);
MetaBackend *backend = meta_context_get_backend (context);
ClutterActor *stage = meta_backend_get_stage (backend);
return clutter_stage_get_grab_actor (CLUTTER_STAGE (stage)) != NULL;
}
static MetaWindow * static MetaWindow *
get_window_for_event (MetaDisplay *display, get_window_for_event (MetaDisplay *display,
const ClutterEvent *event) const ClutterEvent *event)
@ -207,6 +218,31 @@ meta_display_handle_event (MetaDisplay *display,
G_GNUC_UNUSED gboolean bypass_wayland = FALSE; G_GNUC_UNUSED gboolean bypass_wayland = FALSE;
MetaGestureTracker *gesture_tracker; MetaGestureTracker *gesture_tracker;
ClutterEventSequence *sequence; ClutterEventSequence *sequence;
gboolean has_grab;
has_grab = stage_has_grab (display);
if (display->grabbed_in_clutter != has_grab)
{
MetaCompositor *compositor = meta_display_get_compositor (display);
#ifdef HAVE_WAYLAND
if (meta_is_wayland_compositor ())
meta_display_sync_wayland_input_focus (display);
#endif
if (!display->grabbed_in_clutter && has_grab)
{
display->grabbed_in_clutter = TRUE;
meta_display_cancel_touch (display);
meta_compositor_grab_begin (compositor);
}
else if (display->grabbed_in_clutter && !has_grab)
{
display->grabbed_in_clutter = FALSE;
meta_compositor_grab_end (compositor);
}
}
sequence = clutter_event_get_event_sequence (event); sequence = clutter_event_get_event_sequence (event);
@ -394,6 +430,13 @@ meta_display_handle_event (MetaDisplay *display,
goto out; goto out;
} }
if (stage_has_grab (display))
{
bypass_wayland = TRUE;
bypass_clutter = FALSE;
goto out;
}
if (window) if (window)
{ {
/* Events that are likely to trigger compositor gestures should /* Events that are likely to trigger compositor gestures should

View File

@ -268,9 +268,11 @@ sync_focus_surface (MetaWaylandPointer *pointer)
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
ClutterBackend *clutter_backend = clutter_get_default_backend (); ClutterBackend *clutter_backend = clutter_get_default_backend ();
ClutterSeat *clutter_seat = clutter_backend_get_default_seat (clutter_backend); ClutterSeat *clutter_seat = clutter_backend_get_default_seat (clutter_backend);
ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
if (!meta_cursor_tracker_get_pointer_visible (cursor_tracker) && if (clutter_stage_get_grab_actor (stage) != NULL ||
!clutter_seat_is_unfocus_inhibited (clutter_seat)) (!meta_cursor_tracker_get_pointer_visible (cursor_tracker) &&
!clutter_seat_is_unfocus_inhibited (clutter_seat)))
{ {
meta_wayland_pointer_set_focus (pointer, NULL); meta_wayland_pointer_set_focus (pointer, NULL);
return; return;
@ -441,10 +443,14 @@ default_grab_focus (MetaWaylandPointerGrab *grab,
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
ClutterBackend *clutter_backend = clutter_get_default_backend (); ClutterBackend *clutter_backend = clutter_get_default_backend ();
ClutterSeat *clutter_seat = clutter_backend_get_default_seat (clutter_backend); ClutterSeat *clutter_seat = clutter_backend_get_default_seat (clutter_backend);
ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
if (!meta_wayland_seat_has_pointer (seat)) if (!meta_wayland_seat_has_pointer (seat))
return; return;
if (clutter_stage_get_grab_actor (stage) != NULL)
return;
if (!meta_cursor_tracker_get_pointer_visible (cursor_tracker) && if (!meta_cursor_tracker_get_pointer_visible (cursor_tracker) &&
!clutter_seat_is_unfocus_inhibited (clutter_seat)) !clutter_seat_is_unfocus_inhibited (clutter_seat))
return; return;

View File

@ -553,6 +553,14 @@ sync_focus_surface (MetaWaylandTabletTool *tool,
const ClutterEvent *event) const ClutterEvent *event)
{ {
MetaDisplay *display = meta_get_display (); MetaDisplay *display = meta_get_display ();
MetaBackend *backend = meta_get_backend ();
ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
if (clutter_stage_get_grab_actor (stage))
{
meta_wayland_tablet_tool_set_focus (tool, NULL, event);
return;
}
switch (display->event_route) switch (display->event_route)
{ {