mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/virt-viewer
synced 2025-12-27 14:54:14 +00:00
app: add "machine" UI
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@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
This commit is contained in:
parent
a0a2d99fbd
commit
2d8d923fd0
@ -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>
|
||||
|
||||
@ -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);
|
||||
}
|
||||
@ -2017,6 +2032,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
|
||||
|
||||
@ -686,6 +686,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
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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)
|
||||
@ -1368,6 +1415,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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user