[Spice-devel] [spice-gtk PATCH] Keep internal monitor config up-to-date

Jonathon Jongsma jjongsma at redhat.com
Thu Apr 9 14:40:05 PDT 2015


When the server sends a new monitors config message to the client, it
comes through the display channel. However, when the client wants to
change the monitor config on the server, it does so via the main channel
(i.e. the agent). The main channel keeps a set of structs that represent
the current state each display. An application can update a single
display by calling spice_main_update_display(). The main channel will
update that particular struct and then schedule a new MonitorsConfig
message based on the values of all of these structs. This generally
works fine, but it relies on the application to remember to update each
display properly. It would be less error-prone if spice-gtk tracked
incoming display updates from the server rather than having spice-gtk
pass them up to the application and have the application pass them back
down.

Note that when spice-gtk updates its internal state, it does not trigger
a new monitor configuration to be sent down to the server. If the
application wants to send down a new configuration, it still has to call
spice_main_update_display() as before. This change simply means that the
application won't need to call this function in response to
informational updates from the server.
---

** NOTE: this is not intended to fix any existing bug. It was prompted by a
regression that was introduced in a different work-in-progress patch. Is it
worth doing? Or is there a scenario I'm not thinking of where this wouldn't be
beneficial?


 gtk/spice-session.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 1a68d7d..d94427c 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -2149,6 +2149,30 @@ GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceC
     return open_host.connection;
 }
 
+static void
+spice_session_display_monitors_changed(SpiceChannel *channel,
+                                       GParamSpec *pspec G_GNUC_UNUSED,
+                                       SpiceSession *session)
+{
+    GArray *monitors = NULL;
+    SpiceSessionPrivate *s = session->priv;
+    guint i, monitors_max;
+
+    g_return_if_fail(s->cmain != NULL);
+
+    g_object_get(channel,
+                 "monitors", &monitors,
+                 "monitors-max", &monitors_max,
+                 NULL);
+
+    for (i = 0; i < monitors->len; i++) {
+        SpiceDisplayMonitorConfig *monitor = &g_array_index(monitors, SpiceDisplayMonitorConfig, i);
+
+        spice_main_update_display(SPICE_MAIN_CHANNEL(s->cmain), monitor->id,
+                                  monitor->x, monitor->y, monitor->width,
+                                  monitor->height, FALSE);
+    }
+}
 
 G_GNUC_INTERNAL
 void spice_session_channel_new(SpiceSession *session, SpiceChannel *channel)
@@ -2180,6 +2204,9 @@ void spice_session_channel_new(SpiceSession *session, SpiceChannel *channel)
     } else if (SPICE_IS_PLAYBACK_CHANNEL(channel)) {
         g_warn_if_fail(s->playback_channel == NULL);
         s->playback_channel = SPICE_PLAYBACK_CHANNEL(channel);
+    } else if (SPICE_IS_DISPLAY_CHANNEL(channel)) {
+        g_signal_connect(channel, "notify::monitors",
+                         G_CALLBACK(spice_session_display_monitors_changed), session);
     }
 
     g_signal_emit(session, signals[SPICE_SESSION_CHANNEL_NEW], 0, channel);
-- 
2.1.0



More information about the Spice-devel mailing list