[virt-tools-list] [PATCH v2 14/16] app: add "machine" UI

Victor Toso victortoso at redhat.com
Fri Dec 21 12:08:32 UTC 2018


Hi,

On Wed, Sep 26, 2018 at 07:26:37PM +0400, marcandre.lureau at redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau at redhat.com>
> 
> 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 at redhat.com>
Acked-by: Victor Toso <victortoso at redhat.com>
> ---
>  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
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/virt-tools-list/attachments/20181221/5d2580af/attachment.sig>


More information about the virt-tools-list mailing list