backends: Dissociate visibility from current cursor sprite

Just like X11/XFixes behaves, the current cursor is not affected
by its visibility, so it can be queried while invisible (possibly
to be replaced).

For this, keep an extra effective_cursor pointer that will be
either equal to displayed_cursor (maybe a bit of a misnomer now)
or NULL if the cursor is invisible. The MetaCursorRenderer
management is tied to the former, and the ::cursor-changed signal
emission to the latter.

https://bugzilla.gnome.org/show_bug.cgi?id=754806
This commit is contained in:
Carlos Garnacho 2017-11-16 19:23:09 +01:00
parent 6c18bae83c
commit b1a0bf8916
2 changed files with 40 additions and 22 deletions

View File

@ -32,6 +32,7 @@ struct _MetaCursorTracker {
gboolean is_showing; gboolean is_showing;
MetaCursorSprite *effective_cursor; /* May be NULL when hidden */
MetaCursorSprite *displayed_cursor; MetaCursorSprite *displayed_cursor;
/* Wayland clients can set a NULL buffer as their cursor /* Wayland clients can set a NULL buffer as their cursor

View File

@ -53,47 +53,57 @@ enum {
static guint signals[LAST_SIGNAL]; static guint signals[LAST_SIGNAL];
static MetaCursorSprite * static gboolean
get_displayed_cursor (MetaCursorTracker *tracker) update_displayed_cursor (MetaCursorTracker *tracker)
{ {
MetaDisplay *display = meta_get_display (); MetaDisplay *display = meta_get_display ();
MetaCursorSprite *cursor = NULL;
if (!tracker->is_showing) if (display && meta_display_windows_are_interactable (display))
return NULL;
if (meta_display_windows_are_interactable (display))
{ {
if (tracker->has_window_cursor) if (tracker->has_window_cursor)
return tracker->window_cursor; cursor = tracker->window_cursor;
} }
return tracker->root_cursor; if (!cursor)
cursor = tracker->root_cursor;
if (tracker->displayed_cursor == cursor)
return FALSE;
g_set_object (&tracker->displayed_cursor, cursor);
return TRUE;
}
static gboolean
update_effective_cursor (MetaCursorTracker *tracker)
{
MetaCursorSprite *cursor = NULL;
if (tracker->is_showing)
cursor = tracker->displayed_cursor;
return g_set_object (&tracker->effective_cursor, cursor);
} }
static void static void
update_displayed_cursor (MetaCursorTracker *tracker) change_cursor_renderer (MetaCursorTracker *tracker)
{ {
MetaBackend *backend = meta_get_backend (); MetaBackend *backend = meta_get_backend ();
MetaCursorRenderer *cursor_renderer = MetaCursorRenderer *cursor_renderer =
meta_backend_get_cursor_renderer (backend); meta_backend_get_cursor_renderer (backend);
meta_cursor_renderer_set_cursor (cursor_renderer, tracker->displayed_cursor); meta_cursor_renderer_set_cursor (cursor_renderer, tracker->effective_cursor);
} }
static void static void
sync_cursor (MetaCursorTracker *tracker) sync_cursor (MetaCursorTracker *tracker)
{ {
MetaCursorSprite *displayed_cursor = get_displayed_cursor (tracker); if (update_displayed_cursor (tracker))
g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
if (tracker->displayed_cursor == displayed_cursor) if (update_effective_cursor (tracker))
return; change_cursor_renderer (tracker);
g_clear_object (&tracker->displayed_cursor);
if (displayed_cursor)
tracker->displayed_cursor = g_object_ref (displayed_cursor);
update_displayed_cursor (tracker);
g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
} }
static void static void
@ -107,6 +117,8 @@ meta_cursor_tracker_finalize (GObject *object)
{ {
MetaCursorTracker *self = META_CURSOR_TRACKER (object); MetaCursorTracker *self = META_CURSOR_TRACKER (object);
if (self->effective_cursor)
g_object_unref (self->effective_cursor);
if (self->displayed_cursor) if (self->displayed_cursor)
g_object_unref (self->displayed_cursor); g_object_unref (self->displayed_cursor);
if (self->root_cursor) if (self->root_cursor)
@ -282,9 +294,14 @@ meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker)
} }
if (cursor_sprite) if (cursor_sprite)
return meta_cursor_sprite_get_cogl_texture (cursor_sprite); {
meta_cursor_sprite_realize_texture (cursor_sprite);
return meta_cursor_sprite_get_cogl_texture (cursor_sprite);
}
else else
return NULL; {
return NULL;
}
} }
/** /**