[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