diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index 793597104..26dba059c 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -1626,6 +1626,13 @@ clutter_stage_class_init (ClutterStageClass *klass) klass->deactivate = clutter_stage_real_deactivate; } +static void +on_seat_unfocus_inhibited_changed (ClutterStage *stage, + ClutterSeat *seat) +{ + clutter_stage_repick_device (stage, clutter_seat_get_pointer (seat)); +} + static void clutter_stage_init (ClutterStage *self) { @@ -1633,6 +1640,7 @@ clutter_stage_init (ClutterStage *self) ClutterStagePrivate *priv; ClutterStageWindow *impl; ClutterBackend *backend; + ClutterSeat *seat; GError *error; /* a stage is a top-level object */ @@ -1686,6 +1694,12 @@ clutter_stage_init (ClutterStage *self) clutter_stage_set_title (self, g_get_prgname ()); clutter_stage_set_key_focus (self, NULL); clutter_stage_set_viewport (self, geom.width, geom.height); + + seat = clutter_backend_get_default_seat (backend); + g_signal_connect_object (seat, "is-unfocus-inhibited-changed", + G_CALLBACK (on_seat_unfocus_inhibited_changed), + self, + G_CONNECT_SWAPPED); } static void @@ -3568,29 +3582,37 @@ clutter_stage_pick_and_update_device (ClutterStage *stage, graphene_point_t point, uint32_t time_ms) { - ClutterActor *new_actor; + ClutterActor *new_actor = NULL; MtkRegion *clear_area = NULL; + ClutterSeat *seat; - if ((flags & CLUTTER_DEVICE_UPDATE_IGNORE_CACHE) == 0) + seat = clutter_input_device_get_seat (device); + + if (sequence || + device != clutter_seat_get_pointer (seat) || + clutter_seat_is_unfocus_inhibited (seat)) { - if (clutter_stage_check_in_clear_area (stage, device, - sequence, point)) + if ((flags & CLUTTER_DEVICE_UPDATE_IGNORE_CACHE) == 0) { - clutter_stage_set_device_coords (stage, device, - sequence, point); - return clutter_stage_get_device_actor (stage, device, sequence); + if (clutter_stage_check_in_clear_area (stage, device, + sequence, point)) + { + clutter_stage_set_device_coords (stage, device, + sequence, point); + return clutter_stage_get_device_actor (stage, device, sequence); + } } + + new_actor = _clutter_stage_do_pick (stage, + point.x, + point.y, + CLUTTER_PICK_REACTIVE, + &clear_area); + + /* Picking should never fail, but if it does, we bail out here */ + g_return_val_if_fail (new_actor != NULL, NULL); } - new_actor = _clutter_stage_do_pick (stage, - point.x, - point.y, - CLUTTER_PICK_REACTIVE, - &clear_area); - - /* Picking should never fail, but if it does, we bail out here */ - g_return_val_if_fail (new_actor != NULL, NULL); - clutter_stage_update_device (stage, device, sequence, source_device, @@ -4393,7 +4415,9 @@ clutter_stage_emit_event (ClutterStage *self, } } - g_assert (target_actor != NULL); + if (!target_actor) + return; + seat_grab_actor = priv->topmost_grab ? priv->topmost_grab->actor : CLUTTER_ACTOR (self); is_sequence_begin = diff --git a/src/backends/meta-cursor-tracker.c b/src/backends/meta-cursor-tracker.c index 99c4c5f3f..cea4fae7b 100644 --- a/src/backends/meta-cursor-tracker.c +++ b/src/backends/meta-cursor-tracker.c @@ -55,6 +55,7 @@ typedef struct _MetaCursorTrackerPrivate MetaBackend *backend; gboolean is_showing; + gboolean pointer_focus; int track_position_count; @@ -531,6 +532,7 @@ meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker, { MetaCursorTrackerPrivate *priv = meta_cursor_tracker_get_instance_private (tracker); + ClutterSeat *seat; if (visible == priv->is_showing) return; @@ -539,6 +541,13 @@ meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker, sync_cursor (tracker); g_signal_emit (tracker, signals[VISIBILITY_CHANGED], 0); + + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + + if (priv->is_showing) + clutter_seat_inhibit_unfocus (seat); + else + clutter_seat_uninhibit_unfocus (seat); } MetaBackend * diff --git a/src/tests/clutter/conform/grab.c b/src/tests/clutter/conform/grab.c index 21524fc4a..1eb239832 100644 --- a/src/tests/clutter/conform/grab.c +++ b/src/tests/clutter/conform/grab.c @@ -662,6 +662,7 @@ grab_input_only (void) } CLUTTER_TEST_SUITE ( + CLUTTER_TEST_UNIT ("/grab/input-only", grab_input_only); CLUTTER_TEST_UNIT ("/grab/grab-under-pointer", grab_under_pointer) CLUTTER_TEST_UNIT ("/grab/grab-under-pointers-parent", grab_under_pointers_parent) CLUTTER_TEST_UNIT ("/grab/grab-outside-pointer", grab_outside_pointer) @@ -672,5 +673,4 @@ CLUTTER_TEST_SUITE ( CLUTTER_TEST_UNIT ("/grab/grab-unordered-ungrab-2", grab_unordered_ungrab_2) CLUTTER_TEST_UNIT ("/grab/key-focus-in-grab", grab_key_focus_in_grab); CLUTTER_TEST_UNIT ("/grab/key-focus-outside-grab", grab_key_focus_outside_grab); - CLUTTER_TEST_UNIT ("/grab/input-only", grab_input_only); ) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 9969c75f5..c4da3681d 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -302,14 +302,9 @@ static void sync_focus_surface (MetaWaylandPointer *pointer) { MetaBackend *backend = backend_from_pointer (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 (clutter_stage_get_grab_actor (stage) != NULL || - (!meta_cursor_tracker_get_pointer_visible (cursor_tracker) && - !clutter_seat_is_unfocus_inhibited (clutter_seat))) + if (clutter_stage_get_grab_actor (stage) != NULL) { meta_wayland_pointer_set_focus (pointer, NULL); return; @@ -457,9 +452,6 @@ default_grab_focus (MetaWaylandPointerGrab *grab, MetaWaylandPointer *pointer = grab->pointer; MetaWaylandSeat *seat = meta_wayland_pointer_get_seat (pointer); MetaBackend *backend = backend_from_pointer (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_wayland_seat_has_pointer (seat)) @@ -468,10 +460,6 @@ default_grab_focus (MetaWaylandPointerGrab *grab, 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; - if (pointer->button_count > 0) return; @@ -537,16 +525,6 @@ meta_wayland_pointer_enable (MetaWaylandPointer *pointer) "cursor-changed", G_CALLBACK (meta_wayland_pointer_on_cursor_changed), pointer); - - g_signal_connect_swapped (cursor_tracker, - "visibility-changed", - G_CALLBACK (sync_focus_surface), - pointer); - - g_signal_connect_swapped (clutter_seat, - "is-unfocus-inhibited-changed", - G_CALLBACK (sync_focus_surface), - pointer); } void @@ -554,8 +532,6 @@ meta_wayland_pointer_disable (MetaWaylandPointer *pointer) { MetaBackend *backend = backend_from_pointer (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); g_hash_table_foreach (pointer->pointer_clients, make_resources_inert_foreach, @@ -565,14 +541,6 @@ meta_wayland_pointer_disable (MetaWaylandPointer *pointer) (gpointer) meta_wayland_pointer_on_cursor_changed, pointer); - g_signal_handlers_disconnect_by_func (cursor_tracker, - sync_focus_surface, - pointer); - - g_signal_handlers_disconnect_by_func (clutter_seat, - sync_focus_surface, - pointer); - if (pointer->cursor_surface) { g_clear_signal_handler (&pointer->cursor_surface_destroy_id,