[Spice-devel] [PATCH v2 09/10] gtk: use GtkStack

Marc-André Lureau marcandre.lureau at gmail.com
Fri Mar 11 20:50:40 UTC 2016


Move the GtkDrawingArea in a GtkStack, so other widgets can be switched
to for the display.

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

diff --git a/src/spice-widget-priv.h b/src/spice-widget-priv.h
index cbedfc7..cf055d3 100644
--- a/src/spice-widget-priv.h
+++ b/src/spice-widget-priv.h
@@ -35,12 +35,12 @@ G_BEGIN_DECLS
 typedef struct _SpiceDisplayPrivate SpiceDisplayPrivate;
 
 struct _SpiceDisplay {
-    GtkDrawingArea parent;
+    GtkStack parent;
     SpiceDisplayPrivate *priv;
 };
 
 struct _SpiceDisplayClass {
-    GtkDrawingAreaClass parent_class;
+    GtkStackClass parent_class;
 
     /* signals */
     void (*mouse_grab)(SpiceChannel *channel, gint grabbed);
diff --git a/src/spice-widget.c b/src/spice-widget.c
index 74060ed..286eeca 100644
--- a/src/spice-widget.c
+++ b/src/spice-widget.c
@@ -71,7 +71,7 @@
  * save to disk).
  */
 
-G_DEFINE_TYPE(SpiceDisplay, spice_display, GTK_TYPE_DRAWING_AREA)
+G_DEFINE_TYPE(SpiceDisplay, spice_display, GTK_TYPE_STACK)
 
 /* Properties */
 enum {
@@ -117,6 +117,7 @@ static void cursor_invalidate(SpiceDisplay *display);
 static void update_area(SpiceDisplay *display, gint x, gint y, gint width, gint height);
 static void release_keys(SpiceDisplay *display);
 static void size_allocate(GtkWidget *widget, GtkAllocation *conf, gpointer data);
+static gboolean draw_event(GtkWidget *widget, cairo_t *cr, gpointer data);
 
 /* ---------------------------------------------------------------- */
 
@@ -538,15 +539,41 @@ static void grab_notify(SpiceDisplay *display, gboolean was_grabbed)
         release_keys(display);
 }
 
+static void
+drawing_area_realize(GtkWidget *area, gpointer user_data)
+{
+    SpiceDisplay *display = SPICE_DISPLAY(user_data);
+    GError *err = NULL;
+
+    if (!spice_egl_init(display, &err)) {
+        g_critical("egl init failed: %s", err->message);
+        g_clear_error(&err);
+    }
+
+    if (!spice_egl_realize_display(display, gtk_widget_get_window(area), &err)) {
+        g_critical("egl realize failed: %s", err->message);
+        g_clear_error(&err);
+    }
+}
+
 static void spice_display_init(SpiceDisplay *display)
 {
     GtkWidget *widget = GTK_WIDGET(display);
+    GtkWidget *area;
     SpiceDisplayPrivate *d;
     GtkTargetEntry targets = { "text/uri-list", 0, 0 };
-    GError *err = NULL;
 
     d = display->priv = SPICE_DISPLAY_GET_PRIVATE(display);
 
+    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_widget_set_double_buffered(area, true);
+    gtk_stack_set_visible_child(GTK_STACK(widget), area);
+
     g_signal_connect(display, "grab-broken-event", G_CALLBACK(grab_broken), NULL);
     g_signal_connect(display, "grab-notify", G_CALLBACK(grab_notify), NULL);
 
@@ -564,17 +591,10 @@ static void spice_display_init(SpiceDisplay *display)
                           GDK_LEAVE_NOTIFY_MASK |
                           GDK_KEY_PRESS_MASK |
                           GDK_SCROLL_MASK);
-    gtk_widget_set_double_buffered(widget, true);
     gtk_widget_set_can_focus(widget, true);
     d->grabseq = spice_grab_sequence_new_from_string("Control_L+Alt_L");
     d->activeseq = g_new0(gboolean, d->grabseq->nkeysyms);
-
     d->mouse_cursor = get_blank_cursor();
-
-    if (!spice_egl_init(display, &err)) {
-        g_critical("egl init failed: %s", err->message);
-        g_clear_error(&err);
-    }
 }
 
 static GObject *
@@ -1127,19 +1147,27 @@ static gboolean do_color_convert(SpiceDisplay *display, GdkRectangle *r)
 static void set_egl_enabled(SpiceDisplay *display, bool enabled)
 {
     SpiceDisplayPrivate *d = display->priv;
+    GtkWidget *area;
 
-    if (d->egl.enabled != enabled) {
-        d->egl.enabled = enabled;
-        /* even though the function is marked as deprecated, it's the
-         * only way I found to prevent glitches when the window is
-         * resized. */
-        gtk_widget_set_double_buffered(GTK_WIDGET(display), !enabled);
+    if (d->egl.enabled == enabled)
+        return;
+
+    /* 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");
+    gtk_widget_set_double_buffered(GTK_WIDGET(area), !enabled);
+
+    if (enabled) {
+        spice_egl_resize_display(display, d->ww, d->wh);
     }
+
+    d->egl.enabled = enabled;
 }
 
-static gboolean draw_event(GtkWidget *widget, cairo_t *cr)
+static gboolean draw_event(GtkWidget *widget, cairo_t *cr, gpointer data)
 {
-    SpiceDisplay *display = SPICE_DISPLAY(widget);
+    SpiceDisplay *display = SPICE_DISPLAY(data);
     SpiceDisplayPrivate *d = display->priv;
     g_return_val_if_fail(d != NULL, false);
 
@@ -1778,7 +1806,6 @@ static void realize(GtkWidget *widget)
 {
     SpiceDisplay *display = SPICE_DISPLAY(widget);
     SpiceDisplayPrivate *d = display->priv;
-    GError *err = NULL;
 
     GTK_WIDGET_CLASS(spice_display_parent_class)->realize(widget);
 
@@ -1786,11 +1813,6 @@ static void realize(GtkWidget *widget)
         vnc_display_keymap_gdk2xtkbd_table(gtk_widget_get_window(widget),
                                            &d->keycode_maplen);
 
-    if (!spice_egl_realize_display(display, gtk_widget_get_window(GTK_WIDGET(display)), &err)) {
-        g_critical("egl realize failed: %s", err->message);
-        g_clear_error(&err);
-    }
-
     update_image(display);
 }
 
@@ -1810,7 +1832,6 @@ static void spice_display_class_init(SpiceDisplayClass *klass)
     GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
     GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS(klass);
 
-    gtkwidget_class->draw = draw_event;
     gtkwidget_class->key_press_event = key_event;
     gtkwidget_class->key_release_event = key_event;
     gtkwidget_class->enter_notify_event = enter_event;
-- 
2.5.0



More information about the Spice-devel mailing list