summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk/spice-widget-priv.h2
-rw-r--r--gtk/spice-widget.c60
2 files changed, 56 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 048770c..5c12db9 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,
@@ -1477,6 +1507,24 @@ static void spice_display_class_init(SpiceDisplayClass *klass)
G_PARAM_STATIC_STRINGS));
/**
+ * SpiceDisplay:ready:
+ *
+ * Indicate whether the display is ready to be shown. It takes
+ * into account several conditions, such as the channel display
+ * "mark" state, whether the monitor area is visible..
+ *
+ * Since: 0.13
+ **/
+ 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:
*
* When this is true the clipboard gets automatically shared between host
@@ -1660,7 +1708,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 +1717,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 +1749,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 +1791,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,