From b1a0bf89162c0f2ecb444d1801766ea15d7c9312 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 16 Nov 2017 19:23:09 +0100 Subject: [PATCH] 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 --- src/backends/meta-cursor-tracker-private.h | 1 + src/backends/meta-cursor-tracker.c | 61 ++++++++++++++-------- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/src/backends/meta-cursor-tracker-private.h b/src/backends/meta-cursor-tracker-private.h index 3c19b4397..2ec946847 100644 --- a/src/backends/meta-cursor-tracker-private.h +++ b/src/backends/meta-cursor-tracker-private.h @@ -32,6 +32,7 @@ struct _MetaCursorTracker { gboolean is_showing; + MetaCursorSprite *effective_cursor; /* May be NULL when hidden */ MetaCursorSprite *displayed_cursor; /* Wayland clients can set a NULL buffer as their cursor diff --git a/src/backends/meta-cursor-tracker.c b/src/backends/meta-cursor-tracker.c index 59e242b9f..3cdab8389 100644 --- a/src/backends/meta-cursor-tracker.c +++ b/src/backends/meta-cursor-tracker.c @@ -53,47 +53,57 @@ enum { static guint signals[LAST_SIGNAL]; -static MetaCursorSprite * -get_displayed_cursor (MetaCursorTracker *tracker) +static gboolean +update_displayed_cursor (MetaCursorTracker *tracker) { MetaDisplay *display = meta_get_display (); + MetaCursorSprite *cursor = NULL; - if (!tracker->is_showing) - return NULL; - - if (meta_display_windows_are_interactable (display)) + if (display && meta_display_windows_are_interactable (display)) { 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 -update_displayed_cursor (MetaCursorTracker *tracker) +change_cursor_renderer (MetaCursorTracker *tracker) { MetaBackend *backend = meta_get_backend (); MetaCursorRenderer *cursor_renderer = 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 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) - return; - - 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); + if (update_effective_cursor (tracker)) + change_cursor_renderer (tracker); } static void @@ -107,6 +117,8 @@ meta_cursor_tracker_finalize (GObject *object) { MetaCursorTracker *self = META_CURSOR_TRACKER (object); + if (self->effective_cursor) + g_object_unref (self->effective_cursor); if (self->displayed_cursor) g_object_unref (self->displayed_cursor); if (self->root_cursor) @@ -282,9 +294,14 @@ meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker) } 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 - return NULL; + { + return NULL; + } } /**