[virt-tools-list] [PATCH virt-viewer 17/19] Make display submenu insensitive if they can't be modified

Marc-André Lureau marcandre.lureau at gmail.com
Mon Jul 16 16:57:52 UTC 2012


Only when the agent is running may a display be enabled/disabled.
---
 src/virt-viewer-app.c           |   28 ++++++++++++++++++++++++++-
 src/virt-viewer-display-spice.c |   40 ++++++++++++++++++++++++++++++++-------
 src/virt-viewer-display.c       |   23 ++++++++++++++++++++++
 src/virt-viewer-display.h       |    2 ++
 src/virt-viewer-session-spice.c |   18 ++++++++++++++----
 src/virt-viewer-session.c       |   10 ++++++++++
 src/virt-viewer-session.h       |    1 +
 src/virt-viewer-window.c        |   13 +++++++++++--
 src/virt-viewer-window.h        |    1 +
 9 files changed, 122 insertions(+), 14 deletions(-)

diff --git a/src/virt-viewer-app.c b/src/virt-viewer-app.c
index f590641..def52c5 100644
--- a/src/virt-viewer-app.c
+++ b/src/virt-viewer-app.c
@@ -661,6 +661,7 @@ virt_viewer_app_display_added(VirtViewerSession *session G_GNUC_UNUSED,
     }
 
     virt_viewer_window_set_display(window, display);
+    virt_viewer_app_update_menu_displays(self);
     virt_viewer_signal_connect_object(display, "notify::show-hint",
                                       G_CALLBACK(display_show_hint), window, 0);
     g_object_notify(G_OBJECT(display), "show-hint"); /* call display_show_hint */
@@ -684,6 +685,13 @@ virt_viewer_app_display_removed(VirtViewerSession *session G_GNUC_UNUSED,
         virt_viewer_app_remove_nth_window(self, nth);
 }
 
+static void
+virt_viewer_app_display_updated(VirtViewerSession *session G_GNUC_UNUSED,
+                                VirtViewerApp *self)
+{
+    virt_viewer_app_update_menu_displays(self);
+}
+
 int
 virt_viewer_app_create_session(VirtViewerApp *self, const gchar *type)
 {
@@ -734,6 +742,8 @@ virt_viewer_app_create_session(VirtViewerApp *self, const gchar *type)
                      G_CALLBACK(virt_viewer_app_display_added), self);
     g_signal_connect(priv->session, "session-display-removed",
                      G_CALLBACK(virt_viewer_app_display_removed), self);
+    g_signal_connect(priv->session, "session-display-updated",
+                     G_CALLBACK(virt_viewer_app_display_updated), self);
 
     g_signal_connect(priv->session, "session-cut-text",
                      G_CALLBACK(virt_viewer_app_server_cut_text), self);
@@ -1634,15 +1644,31 @@ window_update_menu_displays_cb(gpointer key G_GNUC_UNUSED,
     while (tmp) {
         int *nth = tmp->data;
         VirtViewerWindow *vwin = VIRT_VIEWER_WINDOW(g_hash_table_lookup(self->priv->windows, nth));
+        VirtViewerDisplay *display = virt_viewer_window_get_display(vwin);
         GtkWidget *item;
-        gboolean visible;
+        gboolean visible, sensitive = FALSE;
         gchar *label;
 
         label = g_strdup_printf(_("Display %d"), *nth + 1);
         item = gtk_check_menu_item_new_with_label(label);
         g_free(label);
+
         visible = gtk_widget_get_visible(GTK_WIDGET(virt_viewer_window_get_window(vwin)));
         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), visible);
+
+        if (display) {
+            guint hint = virt_viewer_display_get_show_hint(display);
+
+            if (hint & VIRT_VIEWER_DISPLAY_SHOW_HINT_READY)
+                sensitive = TRUE;
+
+            if ((hint & VIRT_VIEWER_DISPLAY_SHOW_HINT_DISABLED) &&
+                virt_viewer_display_get_selectable(display))
+                sensitive = TRUE;
+        }
+
+        gtk_widget_set_sensitive(item, sensitive);
+
         g_signal_connect(G_OBJECT(item),
                          "toggled", G_CALLBACK(menu_display_visible_toggled_cb), vwin);
         gtk_menu_shell_append(submenu, item);
diff --git a/src/virt-viewer-display-spice.c b/src/virt-viewer-display-spice.c
index ca74c1a..a91d73e 100644
--- a/src/virt-viewer-display-spice.c
+++ b/src/virt-viewer-display-spice.c
@@ -47,6 +47,7 @@ static void virt_viewer_display_spice_send_keys(VirtViewerDisplay *display,
 static GdkPixbuf *virt_viewer_display_spice_get_pixbuf(VirtViewerDisplay *display);
 static void virt_viewer_display_spice_release_cursor(VirtViewerDisplay *display);
 static void virt_viewer_display_spice_close(VirtViewerDisplay *display G_GNUC_UNUSED);
+static gboolean virt_viewer_display_spice_selectable(VirtViewerDisplay *display);
 
 static void
 virt_viewer_display_spice_finalize(GObject *obj)
@@ -70,23 +71,36 @@ virt_viewer_display_spice_class_init(VirtViewerDisplaySpiceClass *klass)
     dclass->get_pixbuf = virt_viewer_display_spice_get_pixbuf;
     dclass->release_cursor = virt_viewer_display_spice_release_cursor;
     dclass->close = virt_viewer_display_spice_close;
+    dclass->selectable = virt_viewer_display_spice_selectable;
 
     g_type_class_add_private(klass, sizeof(VirtViewerDisplaySpicePrivate));
 }
 
+static SpiceMainChannel*
+get_main(VirtViewerDisplay *self)
+{
+    VirtViewerSessionSpice *session;
+
+    session = VIRT_VIEWER_SESSION_SPICE(virt_viewer_display_get_session(self));
+
+    return virt_viewer_session_spice_get_main_channel(session);
+}
+
 static void
 show_hint_changed(VirtViewerDisplay *self)
 {
-    SpiceMainChannel *main_channel = virt_viewer_session_spice_get_main_channel(
-        VIRT_VIEWER_SESSION_SPICE(virt_viewer_display_get_session(self)));
+    SpiceMainChannel *cmain = get_main(self);
     guint enabled = TRUE;
     guint nth;
 
+    if (!cmain)
+        return;
+
     g_object_get(self, "nth-display", &nth, NULL);
     if (virt_viewer_display_get_show_hint(self) & VIRT_VIEWER_DISPLAY_SHOW_HINT_DISABLED)
         enabled = FALSE;
 
-    spice_main_set_display_enabled(main_channel, nth, enabled);
+    spice_main_set_display_enabled(cmain, nth, enabled);
 }
 
 static void
@@ -189,9 +203,8 @@ virt_viewer_display_spice_size_allocate(VirtViewerDisplaySpice *self,
 
     g_object_get(self, "nth-display", &nth, NULL);
 
-    SpiceMainChannel *main_channel = virt_viewer_session_spice_get_main_channel(
-        VIRT_VIEWER_SESSION_SPICE(virt_viewer_display_get_session(VIRT_VIEWER_DISPLAY(self))));
-    spice_main_set_display(main_channel, nth, 0, 0, dw, dh);
+    spice_main_set_display(get_main(VIRT_VIEWER_DISPLAY(self)),
+                           nth, 0, 0, dw, dh);
 }
 
 static void
@@ -270,12 +283,25 @@ virt_viewer_display_spice_release_cursor(VirtViewerDisplay *display)
     spice_display_mouse_ungrab(self->priv->display);
 }
 
-
 static void
 virt_viewer_display_spice_close(VirtViewerDisplay *display G_GNUC_UNUSED)
 {
 }
 
+static gboolean
+virt_viewer_display_spice_selectable(VirtViewerDisplay *self)
+{
+    gboolean agent_connected;
+    SpiceMainChannel *mainc;
+
+    mainc = get_main(self);
+    g_object_get(mainc,
+                 "agent-connected", &agent_connected,
+                 NULL);
+
+    return agent_connected;
+}
+
 
 /*
  * Local variables:
diff --git a/src/virt-viewer-display.c b/src/virt-viewer-display.c
index 004f027..4612970 100644
--- a/src/virt-viewer-display.c
+++ b/src/virt-viewer-display.c
@@ -80,6 +80,7 @@ enum {
     PROP_ZOOM_LEVEL,
     PROP_SHOW_HINT,
     PROP_SESSION,
+    PROP_SELECTABLE,
 };
 
 static void
@@ -167,6 +168,13 @@ virt_viewer_display_class_init(VirtViewerDisplayClass *class)
                                                         G_PARAM_READWRITE |
                                                         G_PARAM_CONSTRUCT_ONLY));
 
+    g_object_class_install_property(object_class,
+                                    PROP_SELECTABLE,
+                                    g_param_spec_boolean("selectable",
+                                                         "Selectable",
+                                                         "Selectable",
+                                                         FALSE,
+                                                         G_PARAM_READABLE));
 
     g_signal_new("display-pointer-grab",
                  G_OBJECT_CLASS_TYPE(object_class),
@@ -302,6 +310,9 @@ virt_viewer_display_get_property(GObject *object,
     case PROP_SESSION:
         g_value_set_object(value, virt_viewer_display_get_session(display));
         break;
+    case PROP_SELECTABLE:
+        g_value_set_boolean(value, virt_viewer_display_get_selectable(display));
+        break;
 
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -601,6 +612,18 @@ void virt_viewer_display_release_cursor(VirtViewerDisplay *self)
     klass->release_cursor(self);
 }
 
+gboolean virt_viewer_display_get_selectable(VirtViewerDisplay *self)
+{
+    VirtViewerDisplayClass *klass;
+
+    g_return_val_if_fail(VIRT_VIEWER_IS_DISPLAY(self), FALSE);
+
+    klass = VIRT_VIEWER_DISPLAY_GET_CLASS(self);
+    if (klass->selectable)
+        return klass->selectable(self);
+
+    return FALSE;
+}
 
 void virt_viewer_display_close(VirtViewerDisplay *self)
 {
diff --git a/src/virt-viewer-display.h b/src/virt-viewer-display.h
index 89b4817..4247570 100644
--- a/src/virt-viewer-display.h
+++ b/src/virt-viewer-display.h
@@ -77,6 +77,7 @@ struct _VirtViewerDisplayClass {
     void (*release_cursor)(VirtViewerDisplay *display);
 
     void (*close)(VirtViewerDisplay *display);
+    gboolean (*selectable)(VirtViewerDisplay *display);
 
     /* signals */
     void (*display_pointer_grab)(VirtViewerDisplay *display);
@@ -118,6 +119,7 @@ void virt_viewer_display_release_cursor(VirtViewerDisplay *display);
 
 void virt_viewer_display_close(VirtViewerDisplay *display);
 void virt_viewer_display_set_enabled(VirtViewerDisplay *display, gboolean enabled);
+gboolean virt_viewer_display_get_selectable(VirtViewerDisplay *display);
 
 G_END_DECLS
 
diff --git a/src/virt-viewer-session-spice.c b/src/virt-viewer-session-spice.c
index 0df11ef..6e9c03d 100644
--- a/src/virt-viewer-session-spice.c
+++ b/src/virt-viewer-session-spice.c
@@ -405,12 +405,21 @@ virt_viewer_session_spice_usb_device_selection(VirtViewerSession *session,
 }
 
 static void
-agent_connected_changed(SpiceChannel *cmain,
+agent_connected_changed(SpiceChannel *cmain G_GNUC_UNUSED,
                         GParamSpec *pspec G_GNUC_UNUSED,
                         VirtViewerSessionSpice *self)
 {
+    // this will force refresh of application menu
+    g_signal_emit_by_name(self, "session-display-updated");
+}
+
+static void
+agent_connected_fullscreen_auto_conf(SpiceChannel *cmain,
+                                     GParamSpec *pspec G_GNUC_UNUSED,
+                                     VirtViewerSessionSpice *self)
+{
     if (virt_viewer_session_spice_fullscreen_auto_conf(self))
-        g_signal_handlers_disconnect_by_func(cmain, agent_connected_changed, self);
+        g_signal_handlers_disconnect_by_func(cmain, agent_connected_fullscreen_auto_conf, self);
 }
 
 static void
@@ -513,8 +522,9 @@ virt_viewer_session_spice_channel_new(SpiceSession *s,
                          G_CALLBACK(virt_viewer_session_spice_main_channel_event), self);
         self->priv->main_channel = SPICE_MAIN_CHANNEL(channel);
 
-        g_signal_connect(channel, "notify::agent-connected", G_CALLBACK(agent_connected_changed),  self);
-        agent_connected_changed(channel, NULL, self);
+        g_signal_connect(channel, "notify::agent-connected", G_CALLBACK(agent_connected_changed), self);
+        g_signal_connect(channel, "notify::agent-connected", G_CALLBACK(agent_connected_fullscreen_auto_conf), self);
+        agent_connected_fullscreen_auto_conf(channel, NULL, self);
 
         g_signal_emit_by_name(session, "session-connected");
     }
diff --git a/src/virt-viewer-session.c b/src/virt-viewer-session.c
index 9249a1f..a1d96c2 100644
--- a/src/virt-viewer-session.c
+++ b/src/virt-viewer-session.c
@@ -233,6 +233,16 @@ virt_viewer_session_class_init(VirtViewerSessionClass *class)
                  1,
                  VIRT_VIEWER_TYPE_DISPLAY);
 
+    g_signal_new("session-display-updated",
+                 G_OBJECT_CLASS_TYPE(object_class),
+                 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS,
+                 G_STRUCT_OFFSET(VirtViewerSessionClass, session_display_updated),
+                 NULL,
+                 NULL,
+                 g_cclosure_marshal_VOID__VOID,
+                 G_TYPE_NONE,
+                 0);
+
     g_signal_new("session-cut-text",
                  G_OBJECT_CLASS_TYPE(object_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS,
diff --git a/src/virt-viewer-session.h b/src/virt-viewer-session.h
index 44e4674..38ed988 100644
--- a/src/virt-viewer-session.h
+++ b/src/virt-viewer-session.h
@@ -88,6 +88,7 @@ struct _VirtViewerSessionClass {
                                   VirtViewerDisplay *display);
     void (*session_display_removed)(VirtViewerSession *session,
                                     VirtViewerDisplay *display);
+    void (*session_display_updated)(VirtViewerSession *session);
 
     void (*session_cut_text)(VirtViewerSession *session, const gchar *str);
     void (*session_bell)(VirtViewerSession *session);
diff --git a/src/virt-viewer-window.c b/src/virt-viewer-window.c
index 46e44be..4bc427a 100644
--- a/src/virt-viewer-window.c
+++ b/src/virt-viewer-window.c
@@ -112,7 +112,8 @@ static void
 virt_viewer_window_get_property (GObject *object, guint property_id,
                                  GValue *value, GParamSpec *pspec)
 {
-    VirtViewerWindowPrivate *priv = VIRT_VIEWER_WINDOW(object)->priv;
+    VirtViewerWindow *self = VIRT_VIEWER_WINDOW(object);
+    VirtViewerWindowPrivate *priv = self->priv;
 
     switch (property_id) {
     case PROP_SUBTITLE:
@@ -124,7 +125,7 @@ virt_viewer_window_get_property (GObject *object, guint property_id,
         break;
 
     case PROP_DISPLAY:
-        g_value_set_object(value, priv->display);
+        g_value_set_object(value, virt_viewer_window_get_display(self));
         break;
 
     case PROP_CONTAINER:
@@ -1117,6 +1118,14 @@ virt_viewer_window_get_builder(VirtViewerWindow *self)
     return self->priv->builder;
 }
 
+VirtViewerDisplay*
+virt_viewer_window_get_display(VirtViewerWindow *self)
+{
+    g_return_val_if_fail(VIRT_VIEWER_WINDOW(self), FALSE);
+
+    return self->priv->display;
+}
+
 /*
  * Local variables:
  *  c-indent-level: 4
diff --git a/src/virt-viewer-window.h b/src/virt-viewer-window.h
index f80c4c7..44db585 100644
--- a/src/virt-viewer-window.h
+++ b/src/virt-viewer-window.h
@@ -63,6 +63,7 @@ GType virt_viewer_window_get_type (void);
 GtkWindow* virt_viewer_window_get_window (VirtViewerWindow* window);
 VirtViewerNotebook* virt_viewer_window_get_notebook (VirtViewerWindow* window);
 void virt_viewer_window_set_display(VirtViewerWindow *self, VirtViewerDisplay *display);
+VirtViewerDisplay* virt_viewer_window_get_display(VirtViewerWindow *self);
 void virt_viewer_window_set_usb_options_sensitive(VirtViewerWindow *self, gboolean sensitive);
 void virt_viewer_window_update_title(VirtViewerWindow *self);
 void virt_viewer_window_show(VirtViewerWindow *self);
-- 
1.7.10.4




More information about the virt-tools-list mailing list