Signed-off-by: Aleksei Nikiforov <darktemplar@xxxxxxxxxx> --- man/remote-viewer.pod | 3 + src/resources/ui/virt-viewer-preferences.ui | 16 +++- src/virt-viewer-app.c | 93 +++++++++++++++++++++ src/virt-viewer-app.h | 6 ++ src/virt-viewer-session-spice.c | 9 +- 5 files changed, 125 insertions(+), 2 deletions(-) diff --git a/man/remote-viewer.pod b/man/remote-viewer.pod index 8cf5ee4..c009fb9 100644 --- a/man/remote-viewer.pod +++ b/man/remote-viewer.pod @@ -354,6 +354,9 @@ The monitor-mapping must contain ids of all displays from 1 to the last desired display id, e.g. "monitor-mapping=3:3" is invalid because mappings for displays 1 and 2 are not specified. +Configuration key B<share-clipboard> contains a boolean value. If it's "true", +then clipboard is shared with guests if clipboard sharing is supported by used protocol. + =head1 EXAMPLES To connect to SPICE server on host "makai" with port 5900 diff --git a/src/resources/ui/virt-viewer-preferences.ui b/src/resources/ui/virt-viewer-preferences.ui index f9738c5..0b88da4 100644 --- a/src/resources/ui/virt-viewer-preferences.ui +++ b/src/resources/ui/virt-viewer-preferences.ui @@ -61,7 +61,7 @@ <property name="visible">True</property> <property name="can_focus">False</property> <property name="border_width">6</property> - <property name="n_rows">2</property> + <property name="n_rows">3</property> <property name="n_columns">2</property> <property name="column_spacing">12</property> <property name="row_spacing">6</property> @@ -91,6 +91,20 @@ <property name="bottom_attach">2</property> </packing> </child> + <child> + <object class="GtkCheckButton" id="cbshareclipboard"> + <property name="label" translatable="yes">Share clipboard</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="right_attach">2</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + </packing> + </child> <child> <object class="GtkFileChooserButton" id="fcsharefolder"> <property name="visible">True</property> diff --git a/src/virt-viewer-app.c b/src/virt-viewer-app.c index e0e6e63..c91a828 100644 --- a/src/virt-viewer-app.c +++ b/src/virt-viewer-app.c @@ -153,6 +153,7 @@ struct _VirtViewerAppPrivate { guint remove_smartcard_accel_key; GdkModifierType remove_smartcard_accel_mods; gboolean quit_on_disconnect; + gboolean supports_share_clipboard; }; @@ -172,6 +173,8 @@ enum { PROP_KIOSK, PROP_QUIT_ON_DISCONNECT, PROP_UUID, + PROP_CONFIG_SHARE_CLIPBOARD, + PROP_SUPPORTS_SHARE_CLIPBOARD, }; void @@ -1549,6 +1552,14 @@ virt_viewer_app_get_property (GObject *object, guint property_id, g_value_set_string(value, priv->uuid); break; + case PROP_CONFIG_SHARE_CLIPBOARD: + g_value_set_boolean(value, virt_viewer_app_get_config_share_clipboard(self)); + break; + + case PROP_SUPPORTS_SHARE_CLIPBOARD: + g_value_set_boolean(value, virt_viewer_app_get_supports_share_clipboard(self)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -1603,6 +1614,14 @@ virt_viewer_app_set_property (GObject *object, guint property_id, virt_viewer_app_set_uuid_string(self, g_value_get_string(value)); break; + case PROP_CONFIG_SHARE_CLIPBOARD: + virt_viewer_app_set_config_share_clipboard(self, g_value_get_boolean(value)); + break; + + case PROP_SUPPORTS_SHARE_CLIPBOARD: + virt_viewer_app_set_supports_share_clipboard(self, g_value_get_boolean(value)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -1815,6 +1834,9 @@ virt_viewer_app_on_application_startup(GApplication *app) gtk_accel_map_add_entry("<virt-viewer>/view/zoom-in", GDK_KEY_plus, GDK_CONTROL_MASK); gtk_accel_map_add_entry("<virt-viewer>/send/secure-attention", GDK_KEY_End, GDK_CONTROL_MASK | GDK_MOD1_MASK); + // Restore initial state of config-share-clipboard property from config and notify about it + virt_viewer_app_set_config_share_clipboard(self, virt_viewer_app_get_config_share_clipboard(self)); + if (!virt_viewer_app_start(self, &error)) { if (error && !g_error_matches(error, VIRT_VIEWER_ERROR, VIRT_VIEWER_ERROR_CANCELLED)) virt_viewer_app_simple_message_dialog(self, error->message); @@ -1994,6 +2016,24 @@ virt_viewer_app_class_init (VirtViewerAppClass *klass) G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(object_class, + PROP_CONFIG_SHARE_CLIPBOARD, + g_param_spec_boolean("config-share-clipboard", + "Share clipboard", + "Indicates whether to share clipboard", + TRUE, /* backwards-compatible default value */ + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(object_class, + PROP_SUPPORTS_SHARE_CLIPBOARD, + g_param_spec_boolean("supports-share-clipboard", + "Support for share clipboard", + "Indicates whether to support for clipboard sharing is available", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); } void @@ -2467,6 +2507,14 @@ virt_viewer_app_get_preferences(VirtViewerApp *self) preferences = GTK_WIDGET(gtk_builder_get_object(builder, "preferences")); self->priv->preferences = preferences; + g_object_bind_property(self, + "config-share-clipboard", + gtk_builder_get_object(builder, "cbshareclipboard"), + "active", + G_BINDING_BIDIRECTIONAL|G_BINDING_SYNC_CREATE); + + g_object_set (gtk_builder_get_object(builder, "cbshareclipboard"), + "sensitive", virt_viewer_app_get_supports_share_clipboard(self), NULL); g_object_set (gtk_builder_get_object(builder, "cbsharefolder"), "sensitive", can_share_folder, NULL); g_object_set (gtk_builder_get_object(builder, "cbsharefolderro"), @@ -2571,6 +2619,51 @@ gboolean virt_viewer_app_get_session_cancelled(VirtViewerApp *self) return self->priv->cancelled; } +gboolean virt_viewer_app_get_config_share_clipboard(VirtViewerApp *self) +{ + VirtViewerAppPrivate *priv = self->priv; + + GError *error = NULL; + gboolean share_clipboard; + + share_clipboard = g_key_file_get_boolean(priv->config, + "virt-viewer", "share-clipboard", &error); + + if (error) { + share_clipboard = TRUE; /* backwards-compatible default value */ + g_clear_error(&error); + } + + return share_clipboard; +} + +void virt_viewer_app_set_config_share_clipboard(VirtViewerApp *self, gboolean enable) +{ + VirtViewerAppPrivate *priv = self->priv; + + g_key_file_set_boolean(priv->config, + "virt-viewer", "share-clipboard", enable); + g_object_notify(G_OBJECT(self), "config-share-clipboard"); +} + +gboolean virt_viewer_app_get_supports_share_clipboard(VirtViewerApp *self) +{ + g_return_val_if_fail(VIRT_VIEWER_IS_APP(self), FALSE); + + return self->priv->supports_share_clipboard; +} + +void virt_viewer_app_set_supports_share_clipboard(VirtViewerApp *self, gboolean enable) +{ + g_return_if_fail(VIRT_VIEWER_IS_APP(self)); + + if (self->priv->supports_share_clipboard == enable) + return; + + self->priv->supports_share_clipboard = enable; + g_object_notify(G_OBJECT(self), "supports-share-clipboard"); +} + /* * Local variables: * c-indent-level: 4 diff --git a/src/virt-viewer-app.h b/src/virt-viewer-app.h index 16b1c8c..d8d73da 100644 --- a/src/virt-viewer-app.h +++ b/src/virt-viewer-app.h @@ -99,6 +99,12 @@ void virt_viewer_app_show_preferences(VirtViewerApp *app, GtkWidget *parent); void virt_viewer_app_set_menus_sensitive(VirtViewerApp *self, gboolean sensitive); gboolean virt_viewer_app_get_session_cancelled(VirtViewerApp *self); +gboolean virt_viewer_app_get_config_share_clipboard(VirtViewerApp *self); +void virt_viewer_app_set_config_share_clipboard(VirtViewerApp *self, gboolean enable); + +gboolean virt_viewer_app_get_supports_share_clipboard(VirtViewerApp *self); +void virt_viewer_app_set_supports_share_clipboard(VirtViewerApp *self, gboolean enable); + G_END_DECLS #endif /* VIRT_VIEWER_APP_H */ diff --git a/src/virt-viewer-session-spice.c b/src/virt-viewer-session-spice.c index fdc7004..2915030 100644 --- a/src/virt-viewer-session-spice.c +++ b/src/virt-viewer-session-spice.c @@ -392,7 +392,14 @@ create_spice_session(VirtViewerSessionSpice *self) spice_set_session_option(self->priv->session); self->priv->gtk_session = spice_gtk_session_get(self->priv->session); - g_object_set(self->priv->gtk_session, "auto-clipboard", TRUE, NULL); + + g_object_set(virt_viewer_session_get_app(VIRT_VIEWER_SESSION(self)), + "supports-share-clipboard", TRUE, + NULL); + + g_object_bind_property(virt_viewer_session_get_app(VIRT_VIEWER_SESSION(self)), "config-share-clipboard", + self->priv->gtk_session, "auto-clipboard", + G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); virt_viewer_signal_connect_object(self->priv->session, "channel-new", G_CALLBACK(virt_viewer_session_spice_channel_new), self, 0); -- 2.19.2 _______________________________________________ virt-tools-list mailing list virt-tools-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/virt-tools-list