Hi, On Wed, Sep 26, 2018 at 07:26:37PM +0400, marcandre.lureau@xxxxxxxxxx wrote: > From: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> > > Add a new "Machine" menu, which allows to Pause/Reset/Power Down a VM. > > The menu is only visible if "vm-ui" app property is set. > > When the application quits, it will also send a quit action to the VM. > > This is a similar behaviour/UI as qemu -display gtk. > > Signed-off-by: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> Acked-by: Victor Toso <victortoso@xxxxxxxxxx> > --- > src/resources/ui/virt-viewer.ui | 46 ++++++++++++++++++++++++++++++ > src/virt-viewer-app.c | 24 ++++++++++++++++ > src/virt-viewer-session.c | 11 ++++++++ > src/virt-viewer-session.h | 11 ++++++++ > src/virt-viewer-window.c | 50 +++++++++++++++++++++++++++++++++ > 5 files changed, 142 insertions(+) > > diff --git a/src/resources/ui/virt-viewer.ui b/src/resources/ui/virt-viewer.ui > index 9da1403..93471a4 100644 > --- a/src/resources/ui/virt-viewer.ui > +++ b/src/resources/ui/virt-viewer.ui > @@ -113,6 +113,52 @@ > </child> > </object> > </child> > + <child> > + <object class="GtkMenuItem" id="menu-machine"> > + <property name="can_focus">False</property> > + <property name="label" translatable="yes">_Machine</property> > + <property name="use_underline">True</property> > + <child type="submenu"> > + <object class="GtkMenu"> > + <property name="visible">True</property> > + <property name="can_focus">False</property> > + <child> > + <object class="GtkCheckMenuItem" id="menu-vm-pause"> > + <property name="visible">True</property> > + <property name="can_focus">False</property> > + <property name="label" translatable="yes">_Pause</property> > + <property name="use_underline">True</property> > + <signal name="toggled" handler="virt_viewer_window_menu_machine_pause" swapped="no"/> > + </object> > + </child> > + <child> > + <object class="GtkSeparatorMenuItem"> > + <property name="visible">True</property> > + <property name="can_focus">False</property> > + </object> > + </child> > + <child> > + <object class="GtkMenuItem" id="menu-vm-reset"> > + <property name="visible">True</property> > + <property name="can_focus">False</property> > + <property name="label" translatable="yes">_Reset</property> > + <property name="use_underline">True</property> > + <signal name="activate" handler="virt_viewer_window_menu_machine_reset" swapped="no"/> > + </object> > + </child> > + <child> > + <object class="GtkMenuItem" id="menu-vm-powerdown"> > + <property name="visible">True</property> > + <property name="can_focus">False</property> > + <property name="label" translatable="yes">_Power down</property> > + <property name="use_underline">True</property> > + <signal name="activate" handler="virt_viewer_window_menu_machine_powerdown" swapped="no"/> > + </object> > + </child> > + </object> > + </child> > + </object> > + </child> > <child> > <object class="GtkMenuItem" id="menu-view"> > <property name="visible">True</property> > diff --git a/src/virt-viewer-app.c b/src/virt-viewer-app.c > index 376fe98..402c80b 100644 > --- a/src/virt-viewer-app.c > +++ b/src/virt-viewer-app.c > @@ -127,6 +127,7 @@ struct _VirtViewerAppPrivate { > gboolean attach; > gboolean quitting; > gboolean kiosk; > + gboolean vm_ui; > > VirtViewerSession *session; > gboolean active; > @@ -174,6 +175,7 @@ enum { > PROP_KIOSK, > PROP_QUIT_ON_DISCONNECT, > PROP_UUID, > + PROP_VM_UI, > }; > > void > @@ -286,6 +288,11 @@ virt_viewer_app_quit(VirtViewerApp *self) > > virt_viewer_app_save_config(self); > > + if (priv->vm_ui) { > + virt_viewer_session_vm_action(VIRT_VIEWER_SESSION(priv->session), > + VIRT_VIEWER_SESSION_VM_ACTION_QUIT); > + } > + > if (priv->session) { > virt_viewer_session_close(VIRT_VIEWER_SESSION(priv->session)); > if (priv->connected) { > @@ -1573,6 +1580,10 @@ virt_viewer_app_get_property (GObject *object, guint property_id, > g_value_set_string(value, priv->uuid); > break; > > + case PROP_VM_UI: > + g_value_set_boolean(value, priv->vm_ui); > + break; > + > default: > G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); > } > @@ -1627,6 +1638,10 @@ 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_VM_UI: > + priv->vm_ui = g_value_get_boolean(value); > + break; > + > default: > G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); > } > @@ -2018,6 +2033,15 @@ 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_VM_UI, > + g_param_spec_boolean("vm-ui", > + "VM UI", > + "QEMU UI & behaviour", > + FALSE, > + G_PARAM_READWRITE | > + G_PARAM_STATIC_STRINGS)); > } > > void > diff --git a/src/virt-viewer-session.c b/src/virt-viewer-session.c > index a40b0bb..3336abe 100644 > --- a/src/virt-viewer-session.c > +++ b/src/virt-viewer-session.c > @@ -688,6 +688,17 @@ gboolean virt_viewer_session_can_retry_auth(VirtViewerSession *self) > return klass->can_retry_auth ? klass->can_retry_auth(self) : FALSE; > } > > +void virt_viewer_session_vm_action(VirtViewerSession *self, gint action) > +{ > + VirtViewerSessionClass *klass; > + > + g_return_if_fail(VIRT_VIEWER_IS_SESSION(self)); > + > + klass = VIRT_VIEWER_SESSION_GET_CLASS(self); > + > + if (klass->vm_action) > + klass->vm_action(self, action); > +} > /* > * Local variables: > * c-indent-level: 4 > diff --git a/src/virt-viewer-session.h b/src/virt-viewer-session.h > index 0aab8ca..ddb54c4 100644 > --- a/src/virt-viewer-session.h > +++ b/src/virt-viewer-session.h > @@ -53,6 +53,14 @@ typedef struct _VirtViewerSessionPrivate VirtViewerSessionPrivate; > > typedef struct _VirtViewerSessionChannel VirtViewerSessionChannel; > > +enum { > + VIRT_VIEWER_SESSION_VM_ACTION_QUIT, > + VIRT_VIEWER_SESSION_VM_ACTION_RESET, > + VIRT_VIEWER_SESSION_VM_ACTION_POWER_DOWN, > + VIRT_VIEWER_SESSION_VM_ACTION_PAUSE, > + VIRT_VIEWER_SESSION_VM_ACTION_CONTINUE, > +}; > + > > /* perhaps this become an interface, and be pushed in gtkvnc and spice? */ > struct _VirtViewerSession { > @@ -79,6 +87,7 @@ struct _VirtViewerSessionClass { > void (*apply_monitor_geometry)(VirtViewerSession *session, GHashTable* monitors); > gboolean (*can_share_folder)(VirtViewerSession *session); > gboolean (*can_retry_auth)(VirtViewerSession *session); > + void (*vm_action)(VirtViewerSession *session, gint action); > }; > > GType virt_viewer_session_get_type(void); > @@ -116,6 +125,8 @@ VirtViewerFile* virt_viewer_session_get_file(VirtViewerSession *self); > gboolean virt_viewer_session_can_share_folder(VirtViewerSession *self); > gboolean virt_viewer_session_can_retry_auth(VirtViewerSession *self); > > +void virt_viewer_session_vm_action(VirtViewerSession *self, gint action); > + > G_END_DECLS > > #endif /* _VIRT_VIEWER_SESSION_H */ > diff --git a/src/virt-viewer-window.c b/src/virt-viewer-window.c > index 67e6f4f..514a410 100644 > --- a/src/virt-viewer-window.c > +++ b/src/virt-viewer-window.c > @@ -52,6 +52,9 @@ > void virt_viewer_window_menu_view_zoom_out(GtkWidget *menu, VirtViewerWindow *self); > void virt_viewer_window_menu_view_zoom_in(GtkWidget *menu, VirtViewerWindow *self); > void virt_viewer_window_menu_view_zoom_reset(GtkWidget *menu, VirtViewerWindow *self); > +void virt_viewer_window_menu_machine_reset(GtkWidget *menu, VirtViewerWindow *self); > +void virt_viewer_window_menu_machine_powerdown(GtkWidget *menu, VirtViewerWindow *self); > +void virt_viewer_window_menu_machine_pause(GtkWidget *menu, VirtViewerWindow *self); > 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_guest_details_response(GtkDialog *dialog, gint response_id, gpointer user_data); > @@ -222,6 +225,18 @@ rebuild_combo_menu(GObject *gobject G_GNUC_UNUSED, > GTK_WIDGET(virt_viewer_window_get_keycombo_menu(self))); > } > > +static void > +vm_ui_changed(GObject *gobject G_GNUC_UNUSED, > + GParamSpec *pspec G_GNUC_UNUSED, > + gpointer user_data) > +{ > + VirtViewerWindow *self = user_data; > + gboolean vm_ui; > + > + g_object_get(G_OBJECT(self->priv->app), "vm-ui", &vm_ui, NULL); > + gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(self->priv->builder, "menu-machine")), vm_ui); > +} > + > static void > virt_viewer_window_constructed(GObject *object) > { > @@ -232,6 +247,8 @@ virt_viewer_window_constructed(GObject *object) > > g_signal_connect(priv->app, "notify::enable-accel", > G_CALLBACK(rebuild_combo_menu), object); > + g_signal_connect(priv->app, "notify::vm-ui", > + G_CALLBACK(vm_ui_changed), object); > rebuild_combo_menu(NULL, NULL, object); > } > > @@ -380,6 +397,36 @@ virt_viewer_window_get_real_zoom_level(VirtViewerWindow *self) > return round((double) NORMAL_ZOOM_LEVEL * allocation.width / width); > } > > +G_MODULE_EXPORT void > +virt_viewer_window_menu_machine_reset(GtkWidget *menu G_GNUC_UNUSED, > + VirtViewerWindow *self) > +{ > + virt_viewer_session_vm_action(virt_viewer_app_get_session(self->priv->app), > + VIRT_VIEWER_SESSION_VM_ACTION_RESET); > +} > + > +G_MODULE_EXPORT void > +virt_viewer_window_menu_machine_powerdown(GtkWidget *menu G_GNUC_UNUSED, > + VirtViewerWindow *self) > +{ > + virt_viewer_session_vm_action(virt_viewer_app_get_session(self->priv->app), > + VIRT_VIEWER_SESSION_VM_ACTION_POWER_DOWN); > +} > + > +G_MODULE_EXPORT void > +virt_viewer_window_menu_machine_pause(GtkWidget *menu G_GNUC_UNUSED, > + VirtViewerWindow *self) > +{ > + gint action; > + > + if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu))) > + action = VIRT_VIEWER_SESSION_VM_ACTION_PAUSE; > + else > + action = VIRT_VIEWER_SESSION_VM_ACTION_CONTINUE; > + > + virt_viewer_session_vm_action(virt_viewer_app_get_session(self->priv->app), action); > +} > + > G_MODULE_EXPORT void > virt_viewer_window_menu_view_zoom_out(GtkWidget *menu G_GNUC_UNUSED, > VirtViewerWindow *self) > @@ -1358,6 +1405,9 @@ virt_viewer_window_set_menus_sensitive(VirtViewerWindow *self, gboolean sensitiv > menu = GTK_WIDGET(gtk_builder_get_object(priv->builder, "menu-view-zoom")); > gtk_widget_set_sensitive(menu, sensitive); > > + menu = GTK_WIDGET(gtk_builder_get_object(priv->builder, "menu-machine")); > + gtk_widget_set_sensitive(menu, sensitive); > + > { > gboolean can_send = sensitive && > VIRT_VIEWER_DISPLAY_CAN_SEND_KEYS(self->priv->display); > -- > 2.19.0.271.gfe8321ec05 >
Attachment:
signature.asc
Description: PGP signature
_______________________________________________ virt-tools-list mailing list virt-tools-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/virt-tools-list