[virt-tools-list] [PATCH virt-viewer] Monitor config at startup sometimes leaves additional monitors enabled

Jonathon Jongsma jjongsma at redhat.com
Tue Mar 17 19:50:58 UTC 2015


When using the configuration file to specify which remote monitors
should be enabled when using the --full-screen option, it sometimes left
additional displays enabled, or didn't place the displays on the right
monitor, or didn't fullscreen them. This was especially true when not
enabling the first display on the remote host. For example:

  monitor-mapping=2:2;3:3

(note that configuration file uses 1-based indexes, rather than 0-based
indexes, so the numbers used below will be 1 less than those above)

There were several issues that contributed to this bug. The first is
that when performing fullscreen auto-conf, we were configuring displays
starting at #0 and ending at ndisplays. So for the previous
configuration, we looped from i = 0 to i < 2 (i.e. display #0 and #1)
even though we should have configured display #1 and #2.

The other issue is that we were creating the first display window before
the loading the monitor mapping configuration from the settings file. So
even if the first display was disabled in the configuration, the first
window will still be created with an id of 0, and therefore didn't get
set to fullscreen. Moving the main window creation to the 'constructed'
vfunc instead of the object init func ensures that the configuration is
all loaded before we attempt to do any fullscreen autoconf.

I also took this opportunity to change the 'constructor' vfunc to a
'constructed' vfunc, since we don't need the added complexity of
'constructor'.

Resolves: rhbz#1200750
---
 src/virt-viewer-app.c           | 62 +++++++++++++++++++++++++----------------
 src/virt-viewer-app.h           |  2 +-
 src/virt-viewer-session-spice.c | 13 +++++----
 3 files changed, 47 insertions(+), 30 deletions(-)

diff --git a/src/virt-viewer-app.c b/src/virt-viewer-app.c
index 8bf728f..c0c980f 100644
--- a/src/virt-viewer-app.c
+++ b/src/virt-viewer-app.c
@@ -301,12 +301,35 @@ virt_viewer_app_quit(VirtViewerApp *self)
     gtk_main_quit();
 }
 
-gint virt_viewer_app_get_n_initial_displays(VirtViewerApp* self)
+GList* virt_viewer_app_get_initial_displays(VirtViewerApp* self)
 {
-    if (self->priv->initial_display_map)
-        return g_hash_table_size(self->priv->initial_display_map);
+    if (!self->priv->initial_display_map) {
+        GList *l = NULL;
+        gint i, n = gdk_screen_get_n_monitors(gdk_screen_get_default());
 
-    return gdk_screen_get_n_monitors(gdk_screen_get_default());
+        for (i = 0; i < n; i++) {
+            l = g_list_append(l, GINT_TO_POINTER(i));
+        }
+        return l;
+    }
+    return g_hash_table_get_keys(self->priv->initial_display_map);
+}
+
+static gint virt_viewer_app_get_first_monitor(VirtViewerApp *self)
+{
+    g_print("%s: initial_display_map = %p\n", G_STRFUNC, self->priv->initial_display_map);
+    if (self->priv->fullscreen && self->priv->initial_display_map) {
+        gint first = G_MAXINT;
+        GHashTableIter iter;
+        gpointer key, value;
+        g_hash_table_iter_init(&iter, self->priv->initial_display_map);
+        while (g_hash_table_iter_next(&iter, &key, &value)) {
+            gint monitor = GPOINTER_TO_INT(value);
+            first = MIN(first, monitor);
+        }
+        return first;
+    }
+    return 0;
 }
 
 gint virt_viewer_app_get_initial_monitor_for_display(VirtViewerApp* self, gint display)
@@ -1723,9 +1746,6 @@ virt_viewer_app_init (VirtViewerApp *self)
     self->priv->config = g_key_file_new();
     self->priv->config_file = g_build_filename(g_get_user_config_dir(),
                                                "virt-viewer", "settings", NULL);
-    self->priv->main_window = virt_viewer_app_window_new(self, 0);
-    self->priv->main_notebook = GTK_WIDGET(virt_viewer_window_get_notebook(self->priv->main_window));
-
     g_key_file_load_from_file(self->priv->config, self->priv->config_file,
                     G_KEY_FILE_KEEP_COMMENTS|G_KEY_FILE_KEEP_TRANSLATIONS, &error);
 
@@ -1747,8 +1767,6 @@ virt_viewer_app_init (VirtViewerApp *self)
     g_signal_connect(self, "notify::guest-name", G_CALLBACK(title_maybe_changed), NULL);
     g_signal_connect(self, "notify::title", G_CALLBACK(title_maybe_changed), NULL);
     g_signal_connect(self, "notify::guri", G_CALLBACK(title_maybe_changed), NULL);
-
-    virt_viewer_window_set_zoom_level(self->priv->main_window, opt_zoom);
 }
 
 static void
@@ -1803,16 +1821,18 @@ virt_viewer_update_smartcard_accels(VirtViewerApp *self)
     }
 }
 
-static GObject *
-virt_viewer_app_constructor (GType gtype,
-                             guint n_properties,
-                             GObjectConstructParam *properties)
+static void
+virt_viewer_app_constructed (GObject *object)
 {
-    GObject *obj;
-    VirtViewerApp *self;
+    VirtViewerApp *self = VIRT_VIEWER_APP(object);
 
-    obj = G_OBJECT_CLASS (virt_viewer_app_parent_class)->constructor (gtype, n_properties, properties);
-    self = VIRT_VIEWER_APP(obj);
+    self->priv->main_window = virt_viewer_app_window_new(self, virt_viewer_app_get_first_monitor(self));
+    self->priv->main_notebook = GTK_WIDGET(virt_viewer_window_get_notebook(self->priv->main_window));
+
+    virt_viewer_app_set_fullscreen(self, opt_fullscreen);
+    virt_viewer_app_set_hotkeys(self, opt_hotkeys);
+    virt_viewer_app_set_kiosk(self, opt_kiosk);
+    virt_viewer_window_set_zoom_level(self->priv->main_window, opt_zoom);
 
     virt_viewer_set_insert_smartcard_accel(self, GDK_F8, GDK_SHIFT_MASK);
     virt_viewer_set_remove_smartcard_accel(self, GDK_F9, GDK_SHIFT_MASK);
@@ -1822,12 +1842,6 @@ virt_viewer_app_constructor (GType gtype,
     gtk_accel_map_add_entry("<virt-viewer>/view/zoom-out", GDK_minus, GDK_CONTROL_MASK);
     gtk_accel_map_add_entry("<virt-viewer>/view/zoom-in", GDK_plus, GDK_CONTROL_MASK);
     gtk_accel_map_add_entry("<virt-viewer>/send/secure-attention", GDK_End, GDK_CONTROL_MASK | GDK_MOD1_MASK);
-
-    virt_viewer_app_set_fullscreen(self, opt_fullscreen);
-    virt_viewer_app_set_hotkeys(self, opt_hotkeys);
-    virt_viewer_app_set_kiosk(self, opt_kiosk);
-
-    return obj;
 }
 
 static void
@@ -1837,7 +1851,7 @@ virt_viewer_app_class_init (VirtViewerAppClass *klass)
 
     g_type_class_add_private (klass, sizeof (VirtViewerAppPrivate));
 
-    object_class->constructor = virt_viewer_app_constructor;
+    object_class->constructed = virt_viewer_app_constructed;
     object_class->get_property = virt_viewer_app_get_property;
     object_class->set_property = virt_viewer_app_set_property;
     object_class->dispose = virt_viewer_app_dispose;
diff --git a/src/virt-viewer-app.h b/src/virt-viewer-app.h
index d214279..c6449be 100644
--- a/src/virt-viewer-app.h
+++ b/src/virt-viewer-app.h
@@ -97,7 +97,7 @@ VirtViewerSession* virt_viewer_app_get_session(VirtViewerApp *self);
 gboolean virt_viewer_app_get_fullscreen(VirtViewerApp *app);
 GOptionGroup* virt_viewer_app_get_option_group(void);
 void virt_viewer_app_clear_hotkeys(VirtViewerApp *app);
-gint virt_viewer_app_get_n_initial_displays(VirtViewerApp* self);
+GList* virt_viewer_app_get_initial_displays(VirtViewerApp* self);
 gint virt_viewer_app_get_initial_monitor_for_display(VirtViewerApp* self, gint display);
 void virt_viewer_app_set_enable_accel(VirtViewerApp *app, gboolean enable);
 void virt_viewer_app_show_preferences(VirtViewerApp *app, GtkWidget *parent);
diff --git a/src/virt-viewer-session-spice.c b/src/virt-viewer-session-spice.c
index 5eb7234..4fdab2b 100644
--- a/src/virt-viewer-session-spice.c
+++ b/src/virt-viewer-session-spice.c
@@ -824,7 +824,8 @@ virt_viewer_session_spice_fullscreen_auto_conf(VirtViewerSessionSpice *self)
     GdkRectangle *displays;
     gboolean agent_connected;
     gint i;
-    gsize ndisplays = 0;
+    GList *initial_displays, *l;
+    guint ndisplays;
 
     /* only do auto-conf once at startup. Avoid repeating auto-conf later due to
      * agent disconnection/re-connection, etc */
@@ -854,18 +855,20 @@ virt_viewer_session_spice_fullscreen_auto_conf(VirtViewerSessionSpice *self)
 
     spice_main_set_display_enabled(cmain, -1, FALSE);
 
-    ndisplays = virt_viewer_app_get_n_initial_displays(app);
-    g_debug("Performing full screen auto-conf, %" G_GSIZE_FORMAT " host monitors", ndisplays);
+    initial_displays = virt_viewer_app_get_initial_displays(app);
+    ndisplays = g_list_length(initial_displays);
+    g_debug("Performing full screen auto-conf, %u host monitors", ndisplays);
     displays = g_new0(GdkRectangle, ndisplays);
 
-    for (i = 0; i < ndisplays; i++) {
+    for (i = 0, l = initial_displays; l != NULL; l = l->next, i++) {
         GdkRectangle* rect = &displays[i];
-        gint j = virt_viewer_app_get_initial_monitor_for_display(app, i);
+        gint j = virt_viewer_app_get_initial_monitor_for_display(app, GPOINTER_TO_INT(l->data));
         if (j == -1)
             continue;
 
         gdk_screen_get_monitor_geometry(screen, j, rect);
     }
+    g_list_free(initial_displays);
 
     virt_viewer_shift_monitors_to_origin(displays, ndisplays);
 
-- 
2.1.0




More information about the virt-tools-list mailing list