wayland/pointer: Set focus to NULL when the cursor is hidden

This is important when using a touchscreen or stylus instead of a mouse
or touchpad. If the cursor only gets hidden and the focus stays the
same, the window will still send hover events to the UI element under
the cursor causing unexpected distractions while interacting with the
touchscreen.

Fix this by emitting a visibility-changed signal from the cursor tracker
which then triggers a focus surface sync and always set the focus
surface to NULL when it's synced while the cursor is hidden.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/448
This commit is contained in:
Jonas Dreßler 2019-02-16 22:48:17 +01:00 committed by Carlos Garnacho
parent faa7b2d4e5
commit a2a8f0cdaa
2 changed files with 34 additions and 0 deletions

View File

@ -50,6 +50,7 @@ enum
{ {
CURSOR_CHANGED, CURSOR_CHANGED,
CURSOR_MOVED, CURSOR_MOVED,
VISIBILITY_CHANGED,
LAST_SIGNAL LAST_SIGNAL
}; };
@ -173,6 +174,13 @@ meta_cursor_tracker_class_init (MetaCursorTrackerClass *klass)
G_TYPE_NONE, 2, G_TYPE_NONE, 2,
G_TYPE_FLOAT, G_TYPE_FLOAT,
G_TYPE_FLOAT); G_TYPE_FLOAT);
signals[VISIBILITY_CHANGED] = g_signal_new ("visibility-changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
} }
/** /**
@ -433,6 +441,8 @@ meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker,
tracker->is_showing = visible; tracker->is_showing = visible;
sync_cursor (tracker); sync_cursor (tracker);
g_signal_emit (tracker, signals[VISIBILITY_CHANGED], 0);
} }
MetaCursorSprite * MetaCursorSprite *

View File

@ -226,6 +226,14 @@ static void
sync_focus_surface (MetaWaylandPointer *pointer) sync_focus_surface (MetaWaylandPointer *pointer)
{ {
MetaDisplay *display = meta_get_display (); MetaDisplay *display = meta_get_display ();
MetaBackend *backend = meta_get_backend ();
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
if (!meta_cursor_tracker_get_pointer_visible (cursor_tracker))
{
meta_wayland_pointer_set_focus (pointer, NULL);
return;
}
switch (display->event_route) switch (display->event_route)
{ {
@ -473,6 +481,13 @@ meta_wayland_pointer_on_cursor_changed (MetaCursorTracker *cursor_tracker,
meta_wayland_surface_update_outputs (pointer->cursor_surface); meta_wayland_surface_update_outputs (pointer->cursor_surface);
} }
static void
meta_wayland_pointer_on_cursor_visibility_changed (MetaCursorTracker *cursor_tracker,
MetaWaylandPointer *pointer)
{
sync_focus_surface (pointer);
}
void void
meta_wayland_pointer_enable (MetaWaylandPointer *pointer) meta_wayland_pointer_enable (MetaWaylandPointer *pointer)
{ {
@ -493,6 +508,11 @@ meta_wayland_pointer_enable (MetaWaylandPointer *pointer)
"cursor-changed", "cursor-changed",
G_CALLBACK (meta_wayland_pointer_on_cursor_changed), G_CALLBACK (meta_wayland_pointer_on_cursor_changed),
pointer); pointer);
g_signal_connect (cursor_tracker,
"visibility-changed",
G_CALLBACK (meta_wayland_pointer_on_cursor_visibility_changed),
pointer);
} }
void void
@ -505,6 +525,10 @@ meta_wayland_pointer_disable (MetaWaylandPointer *pointer)
(gpointer) meta_wayland_pointer_on_cursor_changed, (gpointer) meta_wayland_pointer_on_cursor_changed,
pointer); pointer);
g_signal_handlers_disconnect_by_func (cursor_tracker,
meta_wayland_pointer_on_cursor_visibility_changed,
pointer);
if (pointer->cursor_surface && pointer->cursor_surface_destroy_id) if (pointer->cursor_surface && pointer->cursor_surface_destroy_id)
{ {
g_signal_handler_disconnect (pointer->cursor_surface, g_signal_handler_disconnect (pointer->cursor_surface,