mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/virt-viewer
synced 2025-12-27 06:23:42 +00:00
src: Support modifier-only hotkey for release-cursor
This is implemented by switching from GTK accelerators to using the display's grab sequence handling when a modifier-only hotkey is configured. Signed-off-by: Paul Donohue <git@PaulSD.com>
This commit is contained in:
parent
26f5f2a3f2
commit
f0cc7103be
@ -131,7 +131,6 @@ struct _VirtViewerAppPrivate {
|
||||
GResource *resource;
|
||||
gboolean direct;
|
||||
gboolean verbose;
|
||||
gboolean enable_accel;
|
||||
gboolean authretry;
|
||||
gboolean started;
|
||||
gboolean fullscreen;
|
||||
@ -166,6 +165,7 @@ struct _VirtViewerAppPrivate {
|
||||
GKeyFile *config;
|
||||
gchar *config_file;
|
||||
|
||||
gchar *release_cursor_display_hotkey;
|
||||
gchar **insert_smartcard_accel;
|
||||
gchar **remove_smartcard_accel;
|
||||
gchar **usb_device_reset_accel;
|
||||
@ -185,7 +185,7 @@ enum {
|
||||
PROP_GURI,
|
||||
PROP_FULLSCREEN,
|
||||
PROP_TITLE,
|
||||
PROP_ENABLE_ACCEL,
|
||||
PROP_RELEASE_CURSOR_DISPLAY_HOTKEY,
|
||||
PROP_KIOSK,
|
||||
PROP_QUIT_ON_DISCONNECT,
|
||||
PROP_UUID,
|
||||
@ -1930,8 +1930,8 @@ virt_viewer_app_get_property (GObject *object, guint property_id,
|
||||
g_value_set_string(value, virt_viewer_app_get_title(self));
|
||||
break;
|
||||
|
||||
case PROP_ENABLE_ACCEL:
|
||||
g_value_set_boolean(value, virt_viewer_app_get_enable_accel(self));
|
||||
case PROP_RELEASE_CURSOR_DISPLAY_HOTKEY:
|
||||
g_value_set_string(value, virt_viewer_app_get_release_cursor_display_hotkey(self));
|
||||
break;
|
||||
|
||||
case PROP_KIOSK:
|
||||
@ -2001,8 +2001,8 @@ virt_viewer_app_set_property (GObject *object, guint property_id,
|
||||
priv->title = g_value_dup_string(value);
|
||||
break;
|
||||
|
||||
case PROP_ENABLE_ACCEL:
|
||||
virt_viewer_app_set_enable_accel(self, g_value_get_boolean(value));
|
||||
case PROP_RELEASE_CURSOR_DISPLAY_HOTKEY:
|
||||
virt_viewer_app_set_release_cursor_display_hotkey(self, g_value_dup_string(value));
|
||||
break;
|
||||
|
||||
case PROP_KIOSK:
|
||||
@ -2089,6 +2089,8 @@ virt_viewer_app_dispose (GObject *object)
|
||||
priv->uuid = NULL;
|
||||
g_free(priv->config_file);
|
||||
priv->config_file = NULL;
|
||||
g_free(priv->release_cursor_display_hotkey);
|
||||
priv->release_cursor_display_hotkey = NULL;
|
||||
g_strfreev(priv->insert_smartcard_accel);
|
||||
priv->insert_smartcard_accel = NULL;
|
||||
g_strfreev(priv->remove_smartcard_accel);
|
||||
@ -2496,6 +2498,7 @@ virt_viewer_app_on_application_startup(GApplication *app)
|
||||
|
||||
virt_viewer_app_set_kiosk(self, opt_kiosk);
|
||||
|
||||
priv->release_cursor_display_hotkey = NULL;
|
||||
hotkey_names = g_new(gchar*, G_N_ELEMENTS(hotkey_defaults) + 1);
|
||||
for (i = 0 ; i < G_N_ELEMENTS(hotkey_defaults); i++) {
|
||||
hotkey_names[i] = g_strdup(hotkey_defaults[i].name);
|
||||
@ -2699,14 +2702,13 @@ virt_viewer_app_class_init (VirtViewerAppClass *klass)
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property(object_class,
|
||||
PROP_ENABLE_ACCEL,
|
||||
g_param_spec_boolean("enable-accel",
|
||||
"Enable Accel",
|
||||
"Enable accelerators",
|
||||
FALSE,
|
||||
G_PARAM_CONSTRUCT |
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
PROP_RELEASE_CURSOR_DISPLAY_HOTKEY,
|
||||
g_param_spec_string("release-cursor-display-hotkey",
|
||||
"Release Cursor Display Hotkey",
|
||||
"Display-managed hotkey to ungrab keyboard and mouse",
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property(object_class,
|
||||
PROP_KIOSK,
|
||||
@ -2828,21 +2830,24 @@ gboolean virt_viewer_app_get_direct(VirtViewerApp *self)
|
||||
return priv->direct;
|
||||
}
|
||||
|
||||
gboolean
|
||||
virt_viewer_app_get_enable_accel(VirtViewerApp *self)
|
||||
gchar*
|
||||
virt_viewer_app_get_release_cursor_display_hotkey(VirtViewerApp *self)
|
||||
{
|
||||
g_return_val_if_fail(VIRT_VIEWER_IS_APP(self), FALSE);
|
||||
g_return_val_if_fail(VIRT_VIEWER_IS_APP(self), NULL);
|
||||
|
||||
VirtViewerAppPrivate *priv = virt_viewer_app_get_instance_private(self);
|
||||
return priv->enable_accel;
|
||||
return priv->release_cursor_display_hotkey;
|
||||
}
|
||||
|
||||
void
|
||||
virt_viewer_app_set_enable_accel(VirtViewerApp *self, gboolean enable)
|
||||
virt_viewer_app_set_release_cursor_display_hotkey(VirtViewerApp *self, const gchar *hotkey)
|
||||
{
|
||||
g_return_if_fail(VIRT_VIEWER_IS_APP(self));
|
||||
|
||||
VirtViewerAppPrivate *priv = virt_viewer_app_get_instance_private(self);
|
||||
priv->enable_accel = enable;
|
||||
g_object_notify(G_OBJECT(self), "enable-accel");
|
||||
g_free(priv->release_cursor_display_hotkey);
|
||||
priv->release_cursor_display_hotkey = g_strdup(hotkey);
|
||||
g_object_notify(G_OBJECT(self), "release-cursor-display-hotkey");
|
||||
}
|
||||
|
||||
gchar**
|
||||
@ -2863,6 +2868,7 @@ virt_viewer_app_clear_hotkeys(VirtViewerApp *self)
|
||||
}
|
||||
|
||||
g_return_if_fail(VIRT_VIEWER_IS_APP(self));
|
||||
virt_viewer_app_set_release_cursor_display_hotkey(self, "Control_L+Alt_L");
|
||||
VirtViewerAppPrivate *priv = virt_viewer_app_get_instance_private(self);
|
||||
g_strfreev(priv->insert_smartcard_accel);
|
||||
priv->insert_smartcard_accel = NULL;
|
||||
@ -2909,7 +2915,18 @@ virt_viewer_app_set_hotkey(VirtViewerApp *self, const gchar *hotkey_name,
|
||||
accels[0] = hotkey;
|
||||
gtk_accelerator_parse(accels[0], &accel_key, &accel_mods);
|
||||
}
|
||||
if (accel_key == 0 && accel_mods == 0) {
|
||||
if (g_str_equal(hotkey_name, "release-cursor")) {
|
||||
if (accel_key == 0) {
|
||||
/* GTK does not support using modifiers as hotkeys without any non-modifiers
|
||||
* (eg. CTRL+ALT), however the displays do support this for the grab sequence.
|
||||
*/
|
||||
virt_viewer_app_set_release_cursor_display_hotkey(self, hotkey);
|
||||
g_free(accel);
|
||||
return;
|
||||
}
|
||||
virt_viewer_app_set_release_cursor_display_hotkey(self, NULL);
|
||||
}
|
||||
if (accel_key == 0) {
|
||||
g_warning("Invalid hotkey '%s' for '%s'", hotkey, hotkey_name);
|
||||
g_free(accel);
|
||||
return;
|
||||
@ -2953,7 +2970,6 @@ virt_viewer_app_set_hotkeys(VirtViewerApp *self, const gchar *hotkeys_str)
|
||||
|
||||
if (!hotkeys || g_strv_length(hotkeys) == 0) {
|
||||
g_strfreev(hotkeys);
|
||||
virt_viewer_app_set_enable_accel(self, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2970,8 +2986,6 @@ virt_viewer_app_set_hotkeys(VirtViewerApp *self, const gchar *hotkeys_str)
|
||||
virt_viewer_app_set_hotkey(self, *hotkey, value);
|
||||
}
|
||||
g_strfreev(hotkeys);
|
||||
|
||||
virt_viewer_app_set_enable_accel(self, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@ -73,6 +73,8 @@ gboolean virt_viewer_app_initial_connect(VirtViewerApp *self, GError **error);
|
||||
gboolean virt_viewer_app_get_direct(VirtViewerApp *self);
|
||||
void virt_viewer_app_set_direct(VirtViewerApp *self, gboolean direct);
|
||||
char** virt_viewer_app_get_hotkey_names(void);
|
||||
gchar* virt_viewer_app_get_release_cursor_display_hotkey(VirtViewerApp *self);
|
||||
void virt_viewer_app_set_release_cursor_display_hotkey(VirtViewerApp *self, const gchar *hotkey);
|
||||
void virt_viewer_app_set_hotkey(VirtViewerApp *self, const gchar *hotkey_name, const gchar *hotkey);
|
||||
void virt_viewer_app_set_hotkeys(VirtViewerApp *self, const gchar *hotkeys);
|
||||
void virt_viewer_app_set_attach(VirtViewerApp *self, gboolean attach);
|
||||
@ -96,13 +98,11 @@ void virt_viewer_app_set_connect_info(VirtViewerApp *self,
|
||||
void virt_viewer_app_show_status(VirtViewerApp *self, const gchar *fmt, ...) G_GNUC_PRINTF(2, 3);
|
||||
void virt_viewer_app_show_display(VirtViewerApp *self);
|
||||
GList* virt_viewer_app_get_windows(VirtViewerApp *self);
|
||||
gboolean virt_viewer_app_get_enable_accel(VirtViewerApp *self);
|
||||
VirtViewerSession* virt_viewer_app_get_session(VirtViewerApp *self);
|
||||
gboolean virt_viewer_app_get_fullscreen(VirtViewerApp *app);
|
||||
void virt_viewer_app_clear_hotkeys(VirtViewerApp *app);
|
||||
GList* virt_viewer_app_get_initial_displays(VirtViewerApp* self);
|
||||
gint virt_viewer_app_get_initial_monitor_for_display(VirtViewerApp* self, gint display);
|
||||
void virt_viewer_app_set_enable_accel(VirtViewerApp *app, gboolean enable);
|
||||
void virt_viewer_app_show_preferences(VirtViewerApp *app, GtkWidget *parent);
|
||||
gboolean virt_viewer_app_get_session_cancelled(VirtViewerApp *self);
|
||||
|
||||
|
||||
@ -233,31 +233,26 @@ zoom_level_changed(VirtViewerDisplaySpice *self,
|
||||
}
|
||||
|
||||
static void
|
||||
enable_accel_changed(VirtViewerApp *app,
|
||||
GParamSpec *pspec G_GNUC_UNUSED,
|
||||
VirtViewerDisplaySpice *self)
|
||||
release_cursor_display_hotkey_changed(VirtViewerApp *app,
|
||||
GParamSpec *pspec G_GNUC_UNUSED,
|
||||
VirtViewerDisplaySpice *self)
|
||||
{
|
||||
gboolean kiosk;
|
||||
guint accel_key = 0;
|
||||
GdkModifierType accel_mods = 0;
|
||||
gchar **accels;
|
||||
|
||||
if (virt_viewer_app_get_enable_accel(app)){
|
||||
accels = gtk_application_get_accels_for_action(GTK_APPLICATION(app), "win.release-cursor");
|
||||
if (accels[0])
|
||||
gtk_accelerator_parse(accels[0], &accel_key, &accel_mods);
|
||||
g_strfreev(accels);
|
||||
}
|
||||
|
||||
gchar *hotkey;
|
||||
g_object_get(app, "kiosk", &kiosk, NULL);
|
||||
hotkey = virt_viewer_app_get_release_cursor_display_hotkey(app);
|
||||
|
||||
if (accel_key || accel_mods || kiosk) {
|
||||
SpiceGrabSequence *seq = spice_grab_sequence_new(0, NULL);
|
||||
if (kiosk || hotkey == NULL) {
|
||||
/* disable default grab sequence */
|
||||
SpiceGrabSequence *seq = spice_grab_sequence_new(0, NULL);
|
||||
spice_display_set_grab_keys(self->display, seq);
|
||||
spice_grab_sequence_free(seq);
|
||||
} else {
|
||||
spice_display_set_grab_keys(self->display, NULL);
|
||||
hotkey = spice_hotkey_to_display_hotkey(hotkey);
|
||||
SpiceGrabSequence *seq = spice_grab_sequence_new_from_string(hotkey);
|
||||
g_free(hotkey);
|
||||
spice_display_set_grab_keys(self->display, seq);
|
||||
spice_grab_sequence_free(seq);
|
||||
}
|
||||
}
|
||||
|
||||
@ -337,8 +332,8 @@ virt_viewer_display_spice_new(VirtViewerSessionSpice *session,
|
||||
|
||||
|
||||
app = virt_viewer_session_get_app(VIRT_VIEWER_SESSION(session));
|
||||
virt_viewer_signal_connect_object(app, "notify::enable-accel",
|
||||
G_CALLBACK(enable_accel_changed), self, 0);
|
||||
virt_viewer_signal_connect_object(app, "notify::release-cursor-display-hotkey",
|
||||
G_CALLBACK(release_cursor_display_hotkey_changed), self, 0);
|
||||
virt_viewer_signal_connect_object(self, "notify::fullscreen",
|
||||
G_CALLBACK(resize_policy_changed), app, 0);
|
||||
virt_viewer_signal_connect_object(self, "notify::auto-resize",
|
||||
@ -346,7 +341,7 @@ virt_viewer_display_spice_new(VirtViewerSessionSpice *session,
|
||||
virt_viewer_signal_connect_object(self, "notify::zoom-level",
|
||||
G_CALLBACK(zoom_level_changed), app, 0);
|
||||
resize_policy_changed(self, NULL, app);
|
||||
enable_accel_changed(app, NULL, self);
|
||||
release_cursor_display_hotkey_changed(app, NULL, self);
|
||||
|
||||
return GTK_WIDGET(self);
|
||||
}
|
||||
|
||||
@ -192,31 +192,26 @@ virt_viewer_display_vnc_resize_desktop(VncDisplay *vnc G_GNUC_UNUSED,
|
||||
|
||||
|
||||
static void
|
||||
enable_accel_changed(VirtViewerApp *app,
|
||||
GParamSpec *pspec G_GNUC_UNUSED,
|
||||
VncDisplay *vnc)
|
||||
release_cursor_display_hotkey_changed(VirtViewerApp *app,
|
||||
GParamSpec *pspec G_GNUC_UNUSED,
|
||||
VncDisplay *vnc)
|
||||
{
|
||||
gboolean kiosk;
|
||||
guint accel_key = 0;
|
||||
GdkModifierType accel_mods = 0;
|
||||
gchar **accels;
|
||||
|
||||
if (virt_viewer_app_get_enable_accel(app)){
|
||||
accels = gtk_application_get_accels_for_action(GTK_APPLICATION(app), "win.release-cursor");
|
||||
if (accels[0])
|
||||
gtk_accelerator_parse(accels[0], &accel_key, &accel_mods);
|
||||
g_strfreev(accels);
|
||||
}
|
||||
|
||||
gchar *hotkey;
|
||||
g_object_get(app, "kiosk", &kiosk, NULL);
|
||||
hotkey = virt_viewer_app_get_release_cursor_display_hotkey(app);
|
||||
|
||||
if (accel_key || accel_mods || kiosk) {
|
||||
VncGrabSequence *seq = vnc_grab_sequence_new(0, NULL);
|
||||
if(kiosk || hotkey == NULL) {
|
||||
/* disable default grab sequence */
|
||||
VncGrabSequence *seq = vnc_grab_sequence_new(0, NULL);
|
||||
vnc_display_set_grab_keys(vnc, seq);
|
||||
vnc_grab_sequence_free(seq);
|
||||
} else {
|
||||
vnc_display_set_grab_keys(vnc, NULL);
|
||||
hotkey = spice_hotkey_to_display_hotkey(hotkey);
|
||||
VncGrabSequence *seq = vnc_grab_sequence_new_from_string(hotkey);
|
||||
g_free(hotkey);
|
||||
vnc_display_set_grab_keys(vnc, seq);
|
||||
vnc_grab_sequence_free(seq);
|
||||
}
|
||||
}
|
||||
|
||||
@ -293,9 +288,9 @@ virt_viewer_display_vnc_new(VirtViewerSessionVnc *session,
|
||||
G_CALLBACK(virt_viewer_display_vnc_initialized), self);
|
||||
|
||||
app = virt_viewer_session_get_app(VIRT_VIEWER_SESSION(session));
|
||||
virt_viewer_signal_connect_object(app, "notify::enable-accel",
|
||||
G_CALLBACK(enable_accel_changed), self->vnc, 0);
|
||||
enable_accel_changed(app, NULL, self->vnc);
|
||||
virt_viewer_signal_connect_object(app, "notify::release-cursor-display-hotkey",
|
||||
G_CALLBACK(release_cursor_display_hotkey_changed), self->vnc, 0);
|
||||
release_cursor_display_hotkey_changed(app, NULL, self->vnc);
|
||||
|
||||
#ifdef HAVE_VNC_REMOTE_RESIZE
|
||||
virt_viewer_signal_connect_object(self, "notify::auto-resize",
|
||||
|
||||
@ -970,8 +970,6 @@ virt_viewer_file_fill_app(VirtViewerFile* self, VirtViewerApp *app, GError **err
|
||||
}
|
||||
}
|
||||
|
||||
virt_viewer_app_set_enable_accel(app, TRUE);
|
||||
|
||||
if (virt_viewer_file_is_set(self, "fullscreen"))
|
||||
g_object_set(G_OBJECT(app), "fullscreen",
|
||||
virt_viewer_file_get_fullscreen(self), NULL);
|
||||
|
||||
@ -434,6 +434,133 @@ spice_hotkey_to_gtk_accelerator(const gchar *key)
|
||||
return accel;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
spice_key_to_gdk_key(const gchar *spice_key)
|
||||
{
|
||||
guint i;
|
||||
gchar *key = g_strdup(spice_key);
|
||||
|
||||
static const struct {
|
||||
const char *spice;
|
||||
const char *gdk;
|
||||
} keys[] = {
|
||||
|
||||
{ "alt", "Alt_L" },
|
||||
{ "lalt", "Alt_L" },
|
||||
{ "leftalt", "Alt_L" },
|
||||
{ "left-alt", "Alt_L" },
|
||||
{ "ralt", "Alt_R" },
|
||||
{ "rightalt", "Alt_R" },
|
||||
{ "right-alt", "Alt_R" },
|
||||
|
||||
{ "ctrl", "Control_L" },
|
||||
{ "ctl", "Control_L" },
|
||||
{ "control", "Control_L" },
|
||||
{ "lctrl", "Control_L" },
|
||||
{ "leftctrl", "Control_L" },
|
||||
{ "left-ctrl", "Control_L" },
|
||||
{ "rctrl", "Control_R" },
|
||||
{ "rightctrl", "Control_R" },
|
||||
{ "right-ctrl", "Control_R" },
|
||||
|
||||
{ "cmd", "Control_L" },
|
||||
{ "lcmd", "Control_L" },
|
||||
{ "leftcmd", "Control_L" },
|
||||
{ "left-cmd", "Control_L" },
|
||||
{ "rcmd", "Control_R" },
|
||||
{ "rightcmd", "Control_R" },
|
||||
{ "right-cmd", "Control_R" },
|
||||
|
||||
{ "shift", "Shift_L" },
|
||||
{ "shft", "Shift_L" },
|
||||
{ "lshift", "Shift_L" },
|
||||
{ "leftshift", "Shift_L" },
|
||||
{ "left-shift", "Shift_L" },
|
||||
{ "rshift", "Shift_R" },
|
||||
{ "rightshift", "Shift_R" },
|
||||
{ "right-shift", "Shift_R" },
|
||||
|
||||
{ "win", "Super_L" },
|
||||
{ "lwin", "Super_L" },
|
||||
{ "leftwin", "Super_L" },
|
||||
{ "left-win", "Super_L" },
|
||||
{ "rwin", "Super_R" },
|
||||
{ "rightwin", "Super_R" },
|
||||
{ "right-win", "Super_R" },
|
||||
|
||||
{ "super", "Super_L" },
|
||||
{ "hyper", "Hyper_L" },
|
||||
{ "meta", "Meta_L" },
|
||||
|
||||
{ "esc", "Escape" },
|
||||
{ "escape", "Escape" },
|
||||
{ "ins", "Insert" },
|
||||
{ "insert", "Insert" },
|
||||
{ "del", "Delete" },
|
||||
{ "delete", "Delete" },
|
||||
|
||||
{ "pgup", "Page_Up" },
|
||||
{ "pageup", "Page_Up" },
|
||||
{ "pgdn", "Page_Down" },
|
||||
{ "pagedown", "Page_Down" },
|
||||
|
||||
{ "home", "Home" },
|
||||
{ "end", "End" },
|
||||
{ "space", "space" },
|
||||
|
||||
{ "enter", "Return" },
|
||||
|
||||
{ "tab", "Tab" },
|
||||
{ "f1", "F1" },
|
||||
{ "f2", "F2" },
|
||||
{ "f3", "F3" },
|
||||
{ "f4", "F4" },
|
||||
{ "f5", "F5" },
|
||||
{ "f6", "F6" },
|
||||
{ "f7", "F7" },
|
||||
{ "f8", "F8" },
|
||||
{ "f9", "F9" },
|
||||
{ "f10", "F10" },
|
||||
{ "f11", "F11" },
|
||||
{ "f12", "F12" },
|
||||
};
|
||||
|
||||
if (key[0] == '<' && key[strlen(key)-1] == '>') {
|
||||
gchar *tmp = key;
|
||||
key = g_strndup(key+1, strlen(key)-2);
|
||||
g_free(tmp);
|
||||
}
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS(keys); ++i) {
|
||||
if (g_ascii_strcasecmp(keys[i].spice, key) == 0) {
|
||||
g_free(key);
|
||||
return g_strdup(keys[i].gdk);
|
||||
}
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
gchar*
|
||||
spice_hotkey_to_display_hotkey(const gchar *key)
|
||||
{
|
||||
gchar *new_key, **k, **keyv;
|
||||
|
||||
keyv = g_strsplit(key, "+", -1);
|
||||
g_return_val_if_fail(keyv != NULL, NULL);
|
||||
|
||||
for (k = keyv; *k != NULL; k++) {
|
||||
gchar *tmp = *k;
|
||||
*k = spice_key_to_gdk_key(tmp);
|
||||
g_free(tmp);
|
||||
}
|
||||
|
||||
new_key = g_strjoinv("+", keyv);
|
||||
g_strfreev(keyv);
|
||||
|
||||
return new_key;
|
||||
}
|
||||
|
||||
static gboolean str_is_empty(const gchar *str)
|
||||
{
|
||||
return ((str == NULL) || (str[0] == '\0'));
|
||||
|
||||
@ -54,6 +54,7 @@ gulong virt_viewer_signal_connect_object(gpointer instance,
|
||||
GConnectFlags connect_flags);
|
||||
|
||||
gchar* spice_hotkey_to_gtk_accelerator(const gchar *key);
|
||||
gchar* spice_hotkey_to_display_hotkey(const gchar *key);
|
||||
gint virt_viewer_compare_buildid(const gchar *s1, const gchar *s2);
|
||||
|
||||
/* monitor alignment */
|
||||
|
||||
@ -224,7 +224,7 @@ virt_viewer_window_constructed(GObject *object)
|
||||
if (G_OBJECT_CLASS(virt_viewer_window_parent_class)->constructed)
|
||||
G_OBJECT_CLASS(virt_viewer_window_parent_class)->constructed(object);
|
||||
|
||||
g_signal_connect(self->app, "notify::enable-accel",
|
||||
g_signal_connect(self->app, "notify::release-cursor-display-hotkey",
|
||||
G_CALLBACK(rebuild_combo_menu), object);
|
||||
rebuild_combo_menu(NULL, NULL, object);
|
||||
}
|
||||
@ -872,34 +872,48 @@ virt_viewer_window_get_keycombo_menu(VirtViewerWindow *self)
|
||||
}
|
||||
}
|
||||
|
||||
if (virt_viewer_app_get_enable_accel(self->app)) {
|
||||
gchar **accelactions = gtk_application_list_action_descriptions(GTK_APPLICATION(self->app));
|
||||
gchar **accelactions = gtk_application_list_action_descriptions(GTK_APPLICATION(self->app));
|
||||
|
||||
sectionitems = g_menu_new();
|
||||
section = g_menu_item_new_section(NULL, G_MENU_MODEL(sectionitems));
|
||||
g_menu_append_item(menu, section);
|
||||
sectionitems = g_menu_new();
|
||||
section = g_menu_item_new_section(NULL, G_MENU_MODEL(sectionitems));
|
||||
g_menu_append_item(menu, section);
|
||||
|
||||
for (i = 0; accelactions[i] != NULL; i++) {
|
||||
gchar **accels = gtk_application_get_accels_for_action(GTK_APPLICATION(self->app),
|
||||
accelactions[i]);
|
||||
|
||||
for (j = 0; accels[j] != NULL; j++) {
|
||||
for (i = 0; accelactions[i] != NULL; i++) {
|
||||
if (g_str_equal(accelactions[i], "win.release-cursor")) {
|
||||
gchar *display_hotkey = virt_viewer_app_get_release_cursor_display_hotkey(self->app);
|
||||
if (display_hotkey) {
|
||||
gchar *accel = spice_hotkey_to_gtk_accelerator(display_hotkey);
|
||||
guint accel_key;
|
||||
GdkModifierType accel_mods;
|
||||
gtk_accelerator_parse(accels[j], &accel_key, &accel_mods);
|
||||
gtk_accelerator_parse(accel, &accel_key, &accel_mods);
|
||||
|
||||
guint *keys = accel_key_to_keys(accel_key, accel_mods);
|
||||
gchar *label = gtk_accelerator_get_label(accel_key, accel_mods);
|
||||
gchar *label = spice_hotkey_to_display_hotkey(display_hotkey);
|
||||
virt_viewer_menu_add_combo(self, sectionitems, keys, label);
|
||||
g_free(label);
|
||||
g_free(keys);
|
||||
}
|
||||
g_strfreev(accels);
|
||||
}
|
||||
|
||||
g_strfreev(accelactions);
|
||||
gchar **accels = gtk_application_get_accels_for_action(GTK_APPLICATION(self->app),
|
||||
accelactions[i]);
|
||||
|
||||
for (j = 0; accels[j] != NULL; j++) {
|
||||
guint accel_key;
|
||||
GdkModifierType accel_mods;
|
||||
gtk_accelerator_parse(accels[j], &accel_key, &accel_mods);
|
||||
|
||||
guint *keys = accel_key_to_keys(accel_key, accel_mods);
|
||||
gchar *label = gtk_accelerator_get_label(accel_key, accel_mods);
|
||||
virt_viewer_menu_add_combo(self, sectionitems, keys, label);
|
||||
g_free(label);
|
||||
g_free(keys);
|
||||
}
|
||||
g_strfreev(accels);
|
||||
}
|
||||
|
||||
g_strfreev(accelactions);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
@ -921,9 +935,7 @@ virt_viewer_window_disable_modifiers(VirtViewerWindow *self)
|
||||
|
||||
/* This stops global accelerators like Ctrl+Q == Quit */
|
||||
for (accels = self->accel_list ; accels ; accels = accels->next) {
|
||||
if (virt_viewer_app_get_enable_accel(self->app) &&
|
||||
self->accel_group == accels->data &&
|
||||
!self->kiosk)
|
||||
if (self->accel_group == accels->data && !self->kiosk)
|
||||
continue;
|
||||
gtk_window_remove_accel_group(GTK_WINDOW(self->window), accels->data);
|
||||
}
|
||||
@ -1292,25 +1304,25 @@ virt_viewer_window_update_title(VirtViewerWindow *self)
|
||||
|
||||
if (self->grabbed) {
|
||||
gchar *label;
|
||||
gchar *display_hotkey;
|
||||
guint accel_key = 0;
|
||||
GdkModifierType accel_mods = 0;
|
||||
gchar **accels;
|
||||
|
||||
if (virt_viewer_app_get_enable_accel(self->app)) {
|
||||
display_hotkey = virt_viewer_app_get_release_cursor_display_hotkey(self->app);
|
||||
if (display_hotkey) {
|
||||
label = spice_hotkey_to_display_hotkey(display_hotkey);
|
||||
} else {
|
||||
accels = gtk_application_get_accels_for_action(GTK_APPLICATION(self->app), "win.release-cursor");
|
||||
if (accels[0])
|
||||
gtk_accelerator_parse(accels[0], &accel_key, &accel_mods);
|
||||
g_strfreev(accels);
|
||||
}
|
||||
|
||||
if (accel_key || accel_mods) {
|
||||
g_debug("release-cursor accel key: key=%u, mods=%x", accel_key, accel_mods);
|
||||
label = gtk_accelerator_get_label(accel_key, accel_mods);
|
||||
} else {
|
||||
label = g_strdup(_("Ctrl_L+Alt_L"));
|
||||
}
|
||||
|
||||
grabhint = g_strdup_printf(_("(Press %s to release pointer)"), label);
|
||||
g_free(label);
|
||||
|
||||
if (self->subtitle) {
|
||||
/* translators:
|
||||
@ -1330,8 +1342,6 @@ virt_viewer_window_update_title(VirtViewerWindow *self)
|
||||
grabhint,
|
||||
g_get_application_name());
|
||||
}
|
||||
|
||||
g_free(label);
|
||||
} else if (self->subtitle) {
|
||||
/* translators:
|
||||
* This is "<subtitle> - <appname>"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user