[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