[Spice-devel] [PATCH spice-gtk 1/2] widget: offset draw updates by widget allocation if necessary

Marc-André Lureau marcandre.lureau at gmail.com
Tue Mar 22 18:27:39 UTC 2016


According to gtk_widget_queue_draw_area() documentation:

"The region here is specified in widget coordinates. Widget coordinates
are a bit odd; for historical reasons, they are defined as
widget->window coordinates for widgets that return TRUE for
gtk_widget_get_has_window(), and are relative to widget->allocation.x ,
widget->allocation.y otherwise."

Since spice-gtk 57df040cc, the SpiceDisplay no longer forces its own
window. During gtk+ 3.19.8, gtk stack also no longer use its own
window (commit 9d0e8401). In order to make drawing update resilient to
such changes, add a function applying offset if necessary.

This solves drawing glitches with spice-gtk git and gtk+ >= 3.19.8.

Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
---
 src/spice-widget.c | 30 ++++++++++++++++++++++--------
 1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/src/spice-widget.c b/src/spice-widget.c
index 4b7e202..e45513e 100644
--- a/src/spice-widget.c
+++ b/src/spice-widget.c
@@ -2267,6 +2267,21 @@ static void primary_destroy(SpiceChannel *channel, gpointer data)
     set_monitor_ready(display, false);
 }
 
+static void queue_draw_area(SpiceDisplay *display, gint x, gint y,
+                            gint width, gint height)
+{
+    if (!gtk_widget_get_has_window(GTK_WIDGET(display))) {
+        GtkAllocation allocation;
+
+        gtk_widget_get_allocation(GTK_WIDGET(display), &allocation);
+        x += allocation.x;
+        y += allocation.y;
+    }
+
+    gtk_widget_queue_draw_area(GTK_WIDGET(display),
+                               x, y, width, height);
+}
+
 static void invalidate(SpiceChannel *channel,
                        gint x, gint y, gint w, gint h, gpointer data)
 {
@@ -2304,9 +2319,8 @@ static void invalidate(SpiceChannel *channel,
     x2 = ceil ((rect.x - d->area.x + rect.width) * s);
     y2 = ceil ((rect.y - d->area.y + rect.height) * s);
 
-    gtk_widget_queue_draw_area(GTK_WIDGET(display),
-                               display_x + x1, display_y + y1,
-                               x2 - x1, y2-y1);
+    queue_draw_area(display, display_x + x1, display_y + y1,
+                    x2 - x1, y2 - y1);
 }
 
 static void mark(SpiceDisplay *display, gint mark)
@@ -2457,11 +2471,11 @@ static void cursor_invalidate(SpiceDisplay *display)
 
     spice_display_get_scaling(display, &s, &x, &y, NULL, NULL);
 
-    gtk_widget_queue_draw_area(GTK_WIDGET(display),
-                               floor ((d->mouse_guest_x - d->mouse_hotspot.x - d->area.x) * s) + x,
-                               floor ((d->mouse_guest_y - d->mouse_hotspot.y - d->area.y) * s) + y,
-                               ceil (gdk_pixbuf_get_width(d->mouse_pixbuf) * s),
-                               ceil (gdk_pixbuf_get_height(d->mouse_pixbuf) * s));
+    queue_draw_area(display,
+                    floor ((d->mouse_guest_x - d->mouse_hotspot.x - d->area.x) * s) + x,
+                    floor ((d->mouse_guest_y - d->mouse_hotspot.y - d->area.y) * s) + y,
+                    ceil (gdk_pixbuf_get_width(d->mouse_pixbuf) * s),
+                    ceil (gdk_pixbuf_get_height(d->mouse_pixbuf) * s));
 }
 
 static void cursor_move(SpiceCursorChannel *channel, gint x, gint y, gpointer data)
-- 
2.5.5



More information about the Spice-devel mailing list