diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index 67f5f6a65..de3315b42 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -3677,7 +3677,8 @@ clutter_stage_notify_grab_on_pointer_entry (ClutterStage *stage, grab_actor : old_grab_actor, entry->coords, CLUTTER_CURRENT_TIME); - _clutter_actor_handle_event (deepmost, topmost, event); + if (!_clutter_event_process_filters (event)) + _clutter_actor_handle_event (deepmost, topmost, event); clutter_event_free (event); } } diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h index 580618e48..4e4194f12 100644 --- a/src/compositor/compositor-private.h +++ b/src/compositor/compositor-private.h @@ -82,6 +82,9 @@ gboolean meta_compositor_is_switching_workspace (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 * it to the scope of the X server clock, without losing the granularity. diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 7d14068fd..f6aaf028c 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -374,13 +374,13 @@ grab_devices (MetaModalOptions options, return FALSE; } -static void +void meta_compositor_grab_begin (MetaCompositor *compositor) { META_COMPOSITOR_GET_CLASS (compositor)->grab_begin (compositor); } -static void +void meta_compositor_grab_end (MetaCompositor *compositor) { META_COMPOSITOR_GET_CLASS (compositor)->grab_end (compositor); diff --git a/src/core/display-private.h b/src/core/display-private.h index 8efac0b49..6b7821412 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -197,6 +197,7 @@ struct _MetaDisplay /* Opening the display */ unsigned int display_opening : 1; + unsigned int grabbed_in_clutter : 1; /* Closing down the display */ int closing; diff --git a/src/core/events.c b/src/core/events.c index a8f854a02..4d5f0ba30 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -28,6 +28,7 @@ #include "backends/meta-idle-manager.h" #include "backends/x11/meta-backend-x11.h" #include "backends/x11/meta-input-device-x11.h" +#include "compositor/compositor-private.h" #include "compositor/meta-window-actor-private.h" #include "core/display-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; } +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 * get_window_for_event (MetaDisplay *display, const ClutterEvent *event) @@ -207,6 +218,31 @@ meta_display_handle_event (MetaDisplay *display, G_GNUC_UNUSED gboolean bypass_wayland = FALSE; MetaGestureTracker *gesture_tracker; 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); @@ -394,6 +430,13 @@ meta_display_handle_event (MetaDisplay *display, goto out; } + if (stage_has_grab (display)) + { + bypass_wayland = TRUE; + bypass_clutter = FALSE; + goto out; + } + if (window) { /* Events that are likely to trigger compositor gestures should diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 3ae907a54..7e74b9e9e 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -268,9 +268,11 @@ sync_focus_surface (MetaWaylandPointer *pointer) MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); ClutterBackend *clutter_backend = clutter_get_default_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) && - !clutter_seat_is_unfocus_inhibited (clutter_seat)) + if (clutter_stage_get_grab_actor (stage) != NULL || + (!meta_cursor_tracker_get_pointer_visible (cursor_tracker) && + !clutter_seat_is_unfocus_inhibited (clutter_seat))) { meta_wayland_pointer_set_focus (pointer, NULL); return; @@ -441,10 +443,14 @@ default_grab_focus (MetaWaylandPointerGrab *grab, MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); ClutterBackend *clutter_backend = clutter_get_default_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)) return; + if (clutter_stage_get_grab_actor (stage) != NULL) + return; + if (!meta_cursor_tracker_get_pointer_visible (cursor_tracker) && !clutter_seat_is_unfocus_inhibited (clutter_seat)) return; diff --git a/src/wayland/meta-wayland-tablet-tool.c b/src/wayland/meta-wayland-tablet-tool.c index eeacd9bf9..cb32168a5 100644 --- a/src/wayland/meta-wayland-tablet-tool.c +++ b/src/wayland/meta-wayland-tablet-tool.c @@ -553,6 +553,14 @@ sync_focus_surface (MetaWaylandTabletTool *tool, const ClutterEvent *event) { 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) {