[Spice-devel] [PATCH spice-gtk] gtk: fix server-mode mouse

Marc-André Lureau marcandre.lureau at gmail.com
Tue May 3 17:36:34 UTC 2016


Since switching to gtkstack, server-side mouse mode has some issues with
grabs. There seems to be some grab gtk+ issue, but it seems to fall
under the API user responsability to have its own window when dealing
with pointer grabs. And gtk+ commit 9d0e8401c (Turn stack into no-window
widget) made things worse.

Making the widget an eventbox solves the grab issue.

Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=94764

Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
---
 src/spice-widget-priv.h |  5 +++--
 src/spice-widget.c      | 24 +++++++++++++-----------
 2 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/spice-widget-priv.h b/src/spice-widget-priv.h
index 95bca8a..50d5ea1 100644
--- a/src/spice-widget-priv.h
+++ b/src/spice-widget-priv.h
@@ -37,12 +37,12 @@ G_BEGIN_DECLS
 typedef struct _SpiceDisplayPrivate SpiceDisplayPrivate;
 
 struct _SpiceDisplay {
-    GtkStack parent;
+    GtkEventBox parent;
     SpiceDisplayPrivate *priv;
 };
 
 struct _SpiceDisplayClass {
-    GtkStackClass parent_class;
+    GtkEventBoxClass parent_class;
 
     /* signals */
     void (*mouse_grab)(SpiceChannel *channel, gint grabbed);
@@ -53,6 +53,7 @@ struct _SpiceDisplayClass {
     (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_DISPLAY, SpiceDisplayPrivate))
 
 struct _SpiceDisplayPrivate {
+    GtkStack                *stack;
     gint                    channel_id;
     gint                    monitor_id;
 
diff --git a/src/spice-widget.c b/src/spice-widget.c
index b458909..c7e8984 100644
--- a/src/spice-widget.c
+++ b/src/spice-widget.c
@@ -70,7 +70,7 @@
  * save to disk).
  */
 
-G_DEFINE_TYPE(SpiceDisplay, spice_display, GTK_TYPE_STACK)
+G_DEFINE_TYPE(SpiceDisplay, spice_display, GTK_TYPE_EVENT_BOX)
 
 /* Properties */
 enum {
@@ -588,15 +588,17 @@ static void spice_display_init(SpiceDisplay *display)
     GtkTargetEntry targets = { "text/uri-list", 0, 0 };
 
     d = display->priv = SPICE_DISPLAY_GET_PRIVATE(display);
-
+    d->stack = GTK_STACK(gtk_stack_new());
+    gtk_container_add(GTK_CONTAINER(display), d->stack);
     area = gtk_drawing_area_new();
+
     g_object_connect(area,
                      "signal::draw", draw_event, display,
                      "signal::realize", drawing_area_realize, display,
                      NULL);
-    gtk_stack_add_named(GTK_STACK(widget), area, "draw-area");
+    gtk_stack_add_named(d->stack, area, "draw-area");
     gtk_widget_set_double_buffered(area, true);
-    gtk_stack_set_visible_child(GTK_STACK(widget), area);
+    gtk_stack_set_visible_child(d->stack, area);
 
 #if GTK_CHECK_VERSION(3,16,0)
 #ifndef G_OS_WIN32
@@ -607,7 +609,7 @@ static void spice_display_init(SpiceDisplay *display)
                      "signal::render", gl_area_render, display,
                      "signal::realize", gl_area_realize, display,
                      NULL);
-    gtk_stack_add_named(GTK_STACK(widget), area, "gl-area");
+    gtk_stack_add_named(d->stack, area, "gl-area");
     gtk_widget_show_all(widget);
 #endif
 #endif
@@ -1190,13 +1192,13 @@ static void set_egl_enabled(SpiceDisplay *display, bool enabled)
         /* even though the function is marked as deprecated, it's the
          * only way I found to prevent glitches when the window is
          * resized. */
-        area = gtk_stack_get_child_by_name(GTK_STACK(display), "draw-area");
+        area = gtk_stack_get_child_by_name(d->stack, "draw-area");
         gtk_widget_set_double_buffered(GTK_WIDGET(area), !enabled);
     } else
 #endif
     {
-        area = gtk_stack_get_child_by_name(GTK_STACK(display), "gl-area");
-        gtk_stack_set_visible_child_name(GTK_STACK(display),
+        area = gtk_stack_get_child_by_name(d->stack, "gl-area");
+        gtk_stack_set_visible_child_name(d->stack,
                                          enabled ? "gl-area" : "draw-area");
     }
 
@@ -1216,7 +1218,7 @@ static gboolean draw_event(GtkWidget *widget, cairo_t *cr, gpointer data)
 
 #ifndef G_OS_WIN32
     if (d->egl.enabled &&
-        g_str_equal(gtk_stack_get_visible_child_name(GTK_STACK(display)), "draw-area")) {
+        g_str_equal(gtk_stack_get_visible_child_name(d->stack), "draw-area")) {
         spice_egl_update_display(display);
         return false;
     }
@@ -2625,9 +2627,9 @@ static void gl_draw(SpiceDisplay *display,
     g_return_if_fail(d->egl.context_ready);
 
 #if GTK_CHECK_VERSION(3,16,0)
-    GtkWidget *gl = gtk_stack_get_child_by_name(GTK_STACK(display), "gl-area");
+    GtkWidget *gl = gtk_stack_get_child_by_name(d->stack, "gl-area");
 
-    if (gtk_stack_get_visible_child(GTK_STACK(display)) == gl) {
+    if (gtk_stack_get_visible_child(d->stack) == gl) {
         gtk_gl_area_queue_render(GTK_GL_AREA(gl));
         d->egl.call_draw_done = TRUE;
     } else
-- 
2.7.4



More information about the Spice-devel mailing list