There are several condition to meet in order to have a widget ready to be displayed: the monitor must exist, the area must intersect, and the display mark must be reached. This property will help clients to know when the widget display is ready. Until now, it was relying on the channel mark signal only, and had to deal with the rest of the conditions without much help. --- gtk/spice-widget-priv.h | 2 ++ gtk/spice-widget.c | 51 +++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/gtk/spice-widget-priv.h b/gtk/spice-widget-priv.h index a44e5fe..87cf34e 100644 --- a/gtk/spice-widget-priv.h +++ b/gtk/spice-widget-priv.h @@ -52,6 +52,8 @@ struct _SpiceDisplayPrivate { bool resize_guest_enable; /* state */ + gboolean ready; + gboolean monitor_ready; enum SpiceSurfaceFmt format; gint width, height, stride; gint shmid; diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c index 75efa7e..a874fd4 100644 --- a/gtk/spice-widget.c +++ b/gtk/spice-widget.c @@ -102,7 +102,8 @@ enum { PROP_SCALING, PROP_DISABLE_INPUTS, PROP_ZOOM_LEVEL, - PROP_MONITOR_ID + PROP_MONITOR_ID, + PROP_READY }; /* Signals */ @@ -175,6 +176,9 @@ static void spice_display_get_property(GObject *object, case PROP_ZOOM_LEVEL: g_value_set_int(value, d->zoom_level); break; + case PROP_READY: + g_value_set_boolean(value, d->ready); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -227,6 +231,31 @@ static void update_keyboard_focus(SpiceDisplay *display, gboolean state) spice_gtk_session_request_auto_usbredir(d->gtk_session, state); } +static void update_ready(SpiceDisplay *display) +{ + SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); + gboolean ready; + + ready = d->mark != 0 && d->monitor_ready; + + if (d->ready == ready) + return; + + if (ready && gtk_widget_get_window(GTK_WIDGET(display))) + gtk_widget_queue_draw(GTK_WIDGET(display)); + + d->ready = ready; + g_object_notify(G_OBJECT(display), "ready"); +} + +static void set_monitor_ready(SpiceDisplay *self, gboolean ready) +{ + SpiceDisplayPrivate *d = self->priv; + + d->monitor_ready = ready; + update_ready(self); +} + static void update_monitor_area(SpiceDisplay *display) { SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display); @@ -240,11 +269,11 @@ static void update_monitor_area(SpiceDisplay *display) g_object_get(d->display, "monitors", &monitors, NULL); if (monitors == NULL || d->monitor_id >= monitors->len) { SPICE_DEBUG("update monitor: no monitor %d", d->monitor_id); + set_monitor_ready(display, false); if (spice_channel_test_capability(d->display, SPICE_DISPLAY_CAP_MONITORS_CONFIG)) { SPICE_DEBUG("waiting until MonitorsConfig is received"); return; } - /* FIXME: mark false */ goto whole; } @@ -263,6 +292,7 @@ static void update_monitor_area(SpiceDisplay *display) whole: /* by display whole surface */ update_area(display, 0, 0, d->width, d->height); + set_monitor_ready(display, true); } static void spice_display_set_property(GObject *object, @@ -1476,6 +1506,15 @@ static void spice_display_class_init(SpiceDisplayClass *klass) G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (gobject_class, PROP_READY, + g_param_spec_boolean("ready", + "Ready", + "Ready to display", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + /** * SpiceDisplay:auto-clipboard: * @@ -1660,7 +1699,7 @@ static void update_area(SpiceDisplay *display, if (!gdk_rectangle_intersect(&primary, &area, &area)) { SPICE_DEBUG("The monitor area is not intersecting primary surface"); memset(&d->area, '\0', sizeof(d->area)); - /* FIXME mark false? */ + set_monitor_ready(display, false); return; } @@ -1669,7 +1708,7 @@ static void update_area(SpiceDisplay *display, spicex_image_create(display); update_size_request(display); - gtk_widget_queue_draw(GTK_WIDGET(display)); + set_monitor_ready(display, true); } static void primary_create(SpiceChannel *channel, gint format, @@ -1701,6 +1740,7 @@ static void primary_destroy(SpiceChannel *channel, gpointer data) d->shmid = 0; d->data = NULL; d->data_origin = NULL; + set_monitor_ready(display, false); } static void invalidate(SpiceChannel *channel, @@ -1742,8 +1782,7 @@ static void mark(SpiceDisplay *display, gint mark) SPICE_DEBUG("widget mark: %d, %d:%d %p", mark, d->channel_id, d->monitor_id, display); d->mark = mark; spice_main_set_display_enabled(d->main, get_display_id(display), d->mark != 0); - if (mark != 0 && gtk_widget_get_window(GTK_WIDGET(display))) - gtk_widget_queue_draw(GTK_WIDGET(display)); + update_ready(display); } static void cursor_set(SpiceCursorChannel *channel, -- 1.7.10.4 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel