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