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

Fabiano Fidêncio fidencio at redhat.com
Mon Mar 14 08:22:10 UTC 2016


On Fri, Mar 11, 2016 at 9:50 PM, Marc-André Lureau
<marcandre.lureau at gmail.com> wrote:
> Move the GtkDrawingArea in a GtkStack, so other widgets can be switched
> to for the display.

Can you elaborate a bit more here, please?

>
> 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
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/spice-devel


More information about the Spice-devel mailing list