On Thu, Jun 12, 2014 at 04:07:02PM -0500, Jonathon Jongsma wrote: > This allows the user to obtain the GUID and vm name of the currently-connected > guest. Obviously, this only works with spice. In the future, it will allow them > to set guest-specific configuration options (using a GUID as a key) > --- > src/Makefile.am | 1 + > src/virt-viewer-app.c | 25 ++++++++ > src/virt-viewer-app.h | 1 - > src/virt-viewer-guest-details.xml | 120 ++++++++++++++++++++++++++++++++++++++ > src/virt-viewer-session-spice.c | 16 ++++- > src/virt-viewer-window.c | 40 +++++++++++++ > src/virt-viewer.c | 2 +- > src/virt-viewer.xml | 10 ++++ > 8 files changed, 212 insertions(+), 3 deletions(-) > create mode 100644 src/virt-viewer-guest-details.xml > > diff --git a/src/Makefile.am b/src/Makefile.am > index b3a9637..d4163c8 100644 > --- a/src/Makefile.am > +++ b/src/Makefile.am > @@ -8,6 +8,7 @@ builderxml_DATA = \ > virt-viewer.xml \ > virt-viewer-about.xml \ > virt-viewer-auth.xml \ > + virt-viewer-guest-details.xml \ > $(NULL) > > EXTRA_DIST = \ > diff --git a/src/virt-viewer-app.c b/src/virt-viewer-app.c > index 7dbb7fc..f12cb0d 100644 > --- a/src/virt-viewer-app.c > +++ b/src/virt-viewer-app.c > @@ -139,6 +139,7 @@ struct _VirtViewerAppPrivate { > gchar *guest_name; > gboolean grabbed; > char *title; > + char *uuid; > > gint focused; > GKeyFile *config; > @@ -168,6 +169,7 @@ enum { > PROP_HAS_FOCUS, > PROP_KIOSK, > PROP_QUIT_ON_DISCONNECT, > + PROP_UUID, > }; > > enum { > @@ -305,6 +307,7 @@ app_window_try_fullscreen(VirtViewerApp *self G_GNUC_UNUSED, > } > > > +static > void virt_viewer_app_set_uuid_string(VirtViewerApp* self, const gchar* uuid_string) > { > GArray* mapping = NULL; > @@ -315,6 +318,8 @@ void virt_viewer_app_set_uuid_string(VirtViewerApp* self, const gchar* uuid_stri > > g_debug("%s: UUID changed to %s", G_STRFUNC, uuid_string); > > + g_free(self->priv->uuid); > + self->priv->uuid = g_strdup(uuid_string); > displays = g_key_file_get_integer_list(self->priv->config, > uuid_string, "monitor-mapping", &ndisplays, &error); > if (error) { > @@ -1458,6 +1463,10 @@ virt_viewer_app_get_property (GObject *object, guint property_id, > g_value_set_boolean(value, priv->quit_on_disconnect); > break; > > + case PROP_UUID: > + g_value_set_string(value, priv->uuid); > + break; > + > default: > G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); > } > @@ -1508,6 +1517,10 @@ virt_viewer_app_set_property (GObject *object, guint property_id, > priv->quit_on_disconnect = g_value_get_boolean(value); > break; > > + case PROP_UUID: > + virt_viewer_app_set_uuid_string(self, g_value_get_string(value)); > + break; > + > default: > G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); > } > @@ -1540,6 +1553,8 @@ virt_viewer_app_dispose (GObject *object) > priv->guri = NULL; > g_free(priv->title); > priv->title = NULL; > + g_free(priv->uuid); > + priv->uuid = NULL; > g_free(priv->config_file); > priv->config_file = NULL; > g_clear_pointer(&priv->config, g_key_file_free); > @@ -1814,6 +1829,16 @@ virt_viewer_app_class_init (VirtViewerAppClass *klass) > G_PARAM_READWRITE | > G_PARAM_STATIC_STRINGS)); > > + g_object_class_install_property(object_class, > + PROP_UUID, > + g_param_spec_string("uuid", > + "uuid", > + "uuid", > + "", The default value here is "" (will get back to this below in this email) (I forgot if default values are set on properties which are not CONSTRUCT properties though) > + G_PARAM_READABLE | > + G_PARAM_WRITABLE | > + G_PARAM_STATIC_STRINGS)); > + > signals[SIGNAL_WINDOW_ADDED] = > g_signal_new("window-added", > G_OBJECT_CLASS_TYPE(object_class), > diff --git a/src/virt-viewer-app.h b/src/virt-viewer-app.h > index 6a53992..ba8cf71 100644 > --- a/src/virt-viewer-app.h > +++ b/src/virt-viewer-app.h > @@ -100,7 +100,6 @@ const GOptionEntry* virt_viewer_app_get_options(void); > void virt_viewer_app_clear_hotkeys(VirtViewerApp *app); > gint virt_viewer_app_get_n_initial_displays(VirtViewerApp* self); > gint virt_viewer_app_get_initial_monitor_for_display(VirtViewerApp* self, gint display); > -void virt_viewer_app_set_uuid_string(VirtViewerApp* self, const gchar* uuid_string); > void virt_viewer_app_set_enable_accel(VirtViewerApp *app, gboolean enable); > > G_END_DECLS > diff --git a/src/virt-viewer-guest-details.xml b/src/virt-viewer-guest-details.xml > new file mode 100644 > index 0000000..7f00567 > --- /dev/null > +++ b/src/virt-viewer-guest-details.xml > @@ -0,0 +1,120 @@ > +<?xml version="1.0" encoding="UTF-8"?> > +<!-- Generated with glade 3.16.0 on Thu Jan 16 16:13:38 2014 --> > +<interface> > + <!-- interface-requires gtk+ 3.0 --> > + <object class="GtkDialog" id="guestdetailsdialog"> > + <property name="can_focus">False</property> > + <property name="title" translatable="yes">Guest Details</property> > + <property name="resizable">True</property> > + <property name="default_width">400</property> > + <property name="type_hint">dialog</property> > + <signal name="response" handler="virt_viewer_window_guest_details_response" swapped="no"/> > + <child internal-child="vbox"> > + <object class="GtkBox" id="dialog-vbox2"> > + <property name="can_focus">False</property> > + <property name="orientation">vertical</property> > + <property name="spacing">2</property> > + <child internal-child="action_area"> > + <object class="GtkButtonBox" id="dialog-action_area2"> > + <property name="can_focus">False</property> > + <property name="layout_style">end</property> > + <child> > + <object class="GtkButton" id="button1"> > + <property name="label">gtk-close</property> > + <property name="visible">True</property> > + <property name="can_focus">True</property> > + <property name="receives_default">True</property> > + <property name="use_stock">True</property> > + </object> > + <packing> > + <property name="expand">False</property> > + <property name="fill">True</property> > + <property name="position">0</property> > + </packing> > + </child> > + </object> > + <packing> > + <property name="expand">False</property> > + <property name="fill">True</property> > + <property name="pack_type">end</property> > + <property name="position">0</property> > + </packing> > + </child> > + <child> > + <object class="GtkTable" id="grid1"> > + <property name="visible">True</property> > + <property name="can_focus">False</property> > + <property name="border_width">6</property> > + <property name="row_spacing">6</property> > + <property name="column_spacing">6</property> > + <property name="n_rows">2</property> > + <child> > + <object class="GtkLabel" id="label1"> > + <property name="visible">True</property> > + <property name="can_focus">False</property> > + <property name="xalign">1</property> > + <property name="label" translatable="yes">Name:</property> > + </object> > + <packing> > + <property name="x_options">GTK_SHRINK | GTK_FILL</property> > + <property name="y_options">GTK_FILL</property> > + </packing> > + </child> > + <child> > + <object class="GtkLabel" id="label2"> > + <property name="visible">True</property> > + <property name="can_focus">False</property> > + <property name="xalign">1</property> > + <property name="label" translatable="yes">GUID:</property> > + </object> > + <packing> > + <property name="top_attach">1</property> > + <property name="bottom_attach">2</property> > + <property name="x_options">GTK_SHRINK | GTK_FILL</property> > + <property name="y_options">GTK_FILL</property> > + </packing> > + </child> > + <child> > + <object class="GtkLabel" id="namevaluelabel"> > + <property name="visible">True</property> > + <property name="can_focus">False</property> > + <property name="xalign">0</property> > + <property name="label" translatable="yes">label</property> > + <property name="selectable">True</property> > + </object> > + <packing> > + <property name="left_attach">1</property> > + <property name="right_attach">2</property> > + <property name="y_options">GTK_FILL</property> > + </packing> > + </child> > + <child> > + <object class="GtkLabel" id="guidvaluelabel"> > + <property name="visible">True</property> > + <property name="can_focus">False</property> > + <property name="xalign">0</property> > + <property name="label" translatable="yes">label</property> > + <property name="selectable">True</property> > + </object> > + <packing> > + <property name="left_attach">1</property> > + <property name="right_attach">2</property> > + <property name="top_attach">1</property> > + <property name="bottom_attach">2</property> > + <property name="y_options">GTK_FILL</property> > + </packing> > + </child> > + </object> > + <packing> > + <property name="expand">False</property> > + <property name="fill">True</property> > + <property name="position">1</property> > + </packing> > + </child> > + </object> > + </child> > + <action-widgets> > + <action-widget response="-7">button1</action-widget> > + </action-widgets> > + </object> > +</interface> > diff --git a/src/virt-viewer-session-spice.c b/src/virt-viewer-session-spice.c > index 1820784..df7da34 100644 > --- a/src/virt-viewer-session-spice.c > +++ b/src/virt-viewer-session-spice.c > @@ -876,7 +876,7 @@ uuid_changed(GObject *gobject G_GNUC_UNUSED, > > if (!uuid_empty) { > gchar* uuid_str = spice_uuid_to_string(uuid); > - virt_viewer_app_set_uuid_string(app, uuid_str); > + g_object_set(app, "uuid", uuid_str, NULL); > g_free(uuid_str); > } > } > @@ -884,6 +884,19 @@ uuid_changed(GObject *gobject G_GNUC_UNUSED, > virt_viewer_session_spice_fullscreen_auto_conf(self); > } > > +static void > +name_changed(GObject *gobject G_GNUC_UNUSED, > + GParamSpec *pspec G_GNUC_UNUSED, > + VirtViewerSessionSpice *self) > +{ > + gchar* name = NULL; > + VirtViewerApp* app = virt_viewer_session_get_app(VIRT_VIEWER_SESSION(self)); > + > + g_object_get(self->priv->session, "name", &name, NULL); > + > + g_object_set(app, "guest-name", name, NULL); Missing g_free(name) > +} > + > VirtViewerSession * > virt_viewer_session_spice_new(VirtViewerApp *app, GtkWindow *main_window) > { > @@ -899,6 +912,7 @@ virt_viewer_session_spice_new(VirtViewerApp *app, GtkWindow *main_window) > /* notify::uuid is guaranteed to be emitted during connection startup even > * if the server is too old to support sending uuid */ > g_signal_connect(self->priv->session, "notify::uuid", G_CALLBACK(uuid_changed), self); > + g_signal_connect(self->priv->session, "notify::name", G_CALLBACK(name_changed), self); > > return VIRT_VIEWER_SESSION(self); > } > diff --git a/src/virt-viewer-window.c b/src/virt-viewer-window.c > index 22326e8..bb23efe 100644 > --- a/src/virt-viewer-window.c > +++ b/src/virt-viewer-window.c > @@ -49,6 +49,7 @@ void virt_viewer_window_menu_view_zoom_reset(GtkWidget *menu, VirtViewerWindow * > gboolean virt_viewer_window_delete(GtkWidget *src, void *dummy, VirtViewerWindow *self); > void virt_viewer_window_menu_file_quit(GtkWidget *src, VirtViewerWindow *self); > void virt_viewer_window_menu_help_about(GtkWidget *menu, VirtViewerWindow *self); > +void virt_viewer_window_menu_help_guest_details(GtkWidget *menu, VirtViewerWindow *self); > void virt_viewer_window_menu_view_fullscreen(GtkWidget *menu, VirtViewerWindow *self); > void virt_viewer_window_menu_send(GtkWidget *menu, VirtViewerWindow *self); > void virt_viewer_window_menu_file_screenshot(GtkWidget *menu, VirtViewerWindow *self); > @@ -1012,6 +1013,45 @@ virt_viewer_window_menu_view_release_cursor(GtkWidget *menu G_GNUC_UNUSED, > } > > G_MODULE_EXPORT void > +virt_viewer_window_menu_help_guest_details(GtkWidget *menu, VirtViewerWindow *self) > +{ > + GtkBuilder *ui = virt_viewer_util_load_ui("virt-viewer-guest-details.xml"); > + char* name = NULL; > + char* uuid = NULL; > + > + GtkWidget *dialog = GTK_WIDGET(gtk_builder_get_object(ui, "guestdetailsdialog")); Missing error check on virt_viewer_util_load_ui() > + GtkWidget *namelabel = GTK_WIDGET(gtk_builder_get_object(ui, "namevaluelabel")); > + GtkWidget *guidlabel = GTK_WIDGET(gtk_builder_get_object(ui, "guidvaluelabel")); > + I'd probably add some g_return_if_fail) on namelabel/guidlabel being !NULL > + g_object_get(self->priv->app, "guest-name", &name, "uuid", &uuid, NULL); > + > + if (!name) > + name = g_strdup(_("Unknown")); > + if (!uuid) > + uuid = g_strdup(_("Unknown")); The default value was "" but here we check for NULL, probably not an actual/a big issue > + gtk_label_set_text(namelabel, name); > + gtk_label_set_text(guidlabel, uuid); > + g_free(name); > + g_free(uuid); > + > + gtk_window_set_transient_for(GTK_WINDOW(dialog), > + GTK_WINDOW(self->priv->window)); > + > + gtk_builder_connect_signals(ui, self); > + > + gtk_widget_show_all(dialog); > + > + g_object_unref(G_OBJECT(ui)); > +} > + > +G_MODULE_EXPORT void > +virt_viewer_window_guest_details_response(GtkDialog *dialog, gint response_id, gpointer user_data) > +{ > + if (response_id == GTK_RESPONSE_CLOSE) > + gtk_widget_hide(GTK_WIDGET(dialog)); You hide the dialog here, but it's recreated every time the user clicks on the 'guest details' menu entry. > +} > + > +G_MODULE_EXPORT void > virt_viewer_window_menu_help_about(GtkWidget *menu G_GNUC_UNUSED, > VirtViewerWindow *self) > { > diff --git a/src/virt-viewer.c b/src/virt-viewer.c > index 8a1d8c5..c03503e 100644 > --- a/src/virt-viewer.c > +++ b/src/virt-viewer.c > @@ -560,7 +560,7 @@ virt_viewer_initial_connect(VirtViewerApp *app, GError **error) > if (virDomainGetUUIDString(dom, uuid_string) < 0) { > g_debug("Couldn't get uuid from libvirt"); > } else { > - virt_viewer_app_set_uuid_string(app, uuid_string); > + g_object_set(app, "uuid", uuid_string, NULL); > } > > virt_viewer_app_show_status(app, _("Checking guest domain status")); > diff --git a/src/virt-viewer.xml b/src/virt-viewer.xml > index 8a3d3c0..6764910 100644 > --- a/src/virt-viewer.xml > +++ b/src/virt-viewer.xml > @@ -215,6 +215,16 @@ > <property name="visible">True</property> > <property name="can_focus">False</property> > <child> > + <object class="GtkMenuItem" id="menu-help-guest-details"> > + <property name="visible">True</property> > + <property name="can_focus">False</property> > + <property name="use_action_appearance">False</property> > + <property name="label" translatable="yes">Guest Details</property> No mnemonic for the entry? Christophe
Attachment:
pgpNCfWmzD46T.pgp
Description: PGP signature
_______________________________________________ virt-tools-list mailing list virt-tools-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/virt-tools-list