[Spice-devel] [PATCH spice-gtk] Hide cursor when it is on a different screen in server mode

Marc-André Lureau marcandre.lureau at gmail.com
Mon Mar 19 11:53:57 PDT 2012


When the cursor shape is changed, all the cursor channels are
updated. The current code assumed that the "set" of the shape should
show the cursor, but it should stay hidden instead.

Also, when the cursor is hidden, we must invalidate its current
region to redraw display.

Fix: https://bugzilla.redhat.com/show_bug.cgi?id=804308
---
 gtk/spice-widget-cairo.c |    3 ++-
 gtk/spice-widget.c       |   30 +++++++++++++++---------------
 2 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/gtk/spice-widget-cairo.c b/gtk/spice-widget-cairo.c
index 3fc2a22..2f1ef75 100644
--- a/gtk/spice-widget-cairo.c
+++ b/gtk/spice-widget-cairo.c
@@ -103,7 +103,8 @@ void spicex_draw_event(SpiceDisplay *display, cairo_t *cr)
         }
         cairo_paint(cr);
 
-        if (d->mouse_mode == SPICE_MOUSE_MODE_SERVER) {
+        if (d->mouse_mode == SPICE_MOUSE_MODE_SERVER &&
+            !d->show_cursor) {
             GdkPixbuf *image = d->mouse_pixbuf;
             if (image != NULL) {
                 gdk_cairo_set_source_pixbuf(cr, image,
diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
index 850fd5b..2e5ce41 100644
--- a/gtk/spice-widget.c
+++ b/gtk/spice-widget.c
@@ -1594,19 +1594,10 @@ static void cursor_set(SpiceCursorChannel *channel,
 {
     SpiceDisplay *display = data;
     SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
+    GdkCursor *cursor = NULL;
 
     cursor_invalidate(display);
 
-    if (d->show_cursor) {
-        gdk_cursor_unref(d->show_cursor);
-        d->show_cursor = NULL;
-    }
-
-    if (d->mouse_cursor) {
-        gdk_cursor_unref(d->mouse_cursor);
-        d->mouse_cursor = NULL;
-    }
-
     if (d->mouse_pixbuf) {
         g_object_unref(d->mouse_pixbuf);
         d->mouse_pixbuf = NULL;
@@ -1622,15 +1613,23 @@ static void cursor_set(SpiceCursorChannel *channel,
                                                    (GdkPixbufDestroyNotify)g_free, NULL);
         d->mouse_hotspot.x = hot_x;
         d->mouse_hotspot.y = hot_y;
+        cursor = gdk_cursor_new_from_pixbuf(gtk_widget_get_display(GTK_WIDGET(display)),
+                                            d->mouse_pixbuf, hot_x, hot_y);
+    } else
+        g_warn_if_reached();
 
-        /* gdk_cursor_new_from_pixbuf() will copy pixbuf data on
-           x11/win32/macos. No worries if rgba pointer is freed
-           after. */
-        d->mouse_cursor = gdk_cursor_new_from_pixbuf(gtk_widget_get_display(GTK_WIDGET(display)),
-                                                     d->mouse_pixbuf, hot_x, hot_y);
+    if (d->show_cursor) {
+        /* keep hidden cursor */
+        gdk_cursor_unref(d->show_cursor);
+        d->show_cursor = cursor;
+    } else {
+        gdk_cursor_unref(d->mouse_cursor);
+        d->mouse_cursor = cursor;
     }
 
     update_mouse_pointer(display);
+
+    cursor_invalidate(display);
 }
 
 static void cursor_hide(SpiceCursorChannel *channel, gpointer data)
@@ -1641,6 +1640,7 @@ static void cursor_hide(SpiceCursorChannel *channel, gpointer data)
     if (d->show_cursor != NULL) /* then we are already hidden */
         return;
 
+    cursor_invalidate(display);
     d->show_cursor = d->mouse_cursor;
     d->mouse_cursor = get_blank_cursor();
     update_mouse_pointer(display);
-- 
1.7.7.6



More information about the Spice-devel mailing list