mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/virt-viewer
synced 2025-12-29 00:15:15 +00:00
src: convert accelerator handling over to actions
This better decouples the accelerator handling from the current user interface design. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
407836ecee
commit
2f11e0a407
@ -162,12 +162,9 @@ struct _VirtViewerAppPrivate {
|
||||
GKeyFile *config;
|
||||
gchar *config_file;
|
||||
|
||||
guint insert_smartcard_accel_key;
|
||||
GdkModifierType insert_smartcard_accel_mods;
|
||||
guint remove_smartcard_accel_key;
|
||||
GdkModifierType remove_smartcard_accel_mods;
|
||||
guint usb_device_reset_accel_key;
|
||||
GdkModifierType usb_device_reset_accel_mods;
|
||||
gchar **insert_smartcard_accel;
|
||||
gchar **remove_smartcard_accel;
|
||||
gchar **usb_device_reset_accel;
|
||||
gboolean quit_on_disconnect;
|
||||
gboolean supports_share_clipboard;
|
||||
VirtViewerKeyMapping *keyMappings;
|
||||
@ -2130,28 +2127,6 @@ virt_viewer_app_init(VirtViewerApp *self)
|
||||
g_signal_connect(self, "notify::guri", G_CALLBACK(title_maybe_changed), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_set_insert_smartcard_accel(VirtViewerApp *self,
|
||||
guint accel_key,
|
||||
GdkModifierType accel_mods)
|
||||
{
|
||||
VirtViewerAppPrivate *priv = virt_viewer_app_get_instance_private(self);
|
||||
|
||||
priv->insert_smartcard_accel_key = accel_key;
|
||||
priv->insert_smartcard_accel_mods = accel_mods;
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_set_remove_smartcard_accel(VirtViewerApp *self,
|
||||
guint accel_key,
|
||||
GdkModifierType accel_mods)
|
||||
{
|
||||
VirtViewerAppPrivate *priv = virt_viewer_app_get_instance_private(self);
|
||||
|
||||
priv->remove_smartcard_accel_key = accel_key;
|
||||
priv->remove_smartcard_accel_mods = accel_mods;
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_update_smartcard_accels(VirtViewerApp *self)
|
||||
{
|
||||
@ -2166,38 +2141,30 @@ virt_viewer_update_smartcard_accels(VirtViewerApp *self)
|
||||
sw_smartcard = FALSE;
|
||||
}
|
||||
if (sw_smartcard) {
|
||||
gboolean r;
|
||||
g_debug("enabling smartcard shortcuts");
|
||||
r = gtk_accel_map_change_entry("<virt-viewer>/file/smartcard-insert",
|
||||
priv->insert_smartcard_accel_key,
|
||||
priv->insert_smartcard_accel_mods,
|
||||
TRUE);
|
||||
if (!r)
|
||||
g_warning("Unable to set hotkey for 'smartcard-insert' due to a conflict in GTK");
|
||||
r = gtk_accel_map_change_entry("<virt-viewer>/file/smartcard-remove",
|
||||
priv->remove_smartcard_accel_key,
|
||||
priv->remove_smartcard_accel_mods,
|
||||
TRUE);
|
||||
if (!r)
|
||||
g_warning("Unable to set hotkey for 'smartcard-remove' due to a conflict in GTK");
|
||||
|
||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "app.smartcard-insert",
|
||||
(const gchar * const *)priv->insert_smartcard_accel);
|
||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "app.smartcard-remove",
|
||||
(const gchar * const *)priv->remove_smartcard_accel);
|
||||
} else {
|
||||
g_debug("disabling smartcard shortcuts");
|
||||
gtk_accel_map_change_entry("<virt-viewer>/file/smartcard-insert", 0, 0, TRUE);
|
||||
gtk_accel_map_change_entry("<virt-viewer>/file/smartcard-remove", 0, 0, TRUE);
|
||||
const gchar *no_accels[] = { NULL };
|
||||
char **old_insert_accels = gtk_application_get_accels_for_action(GTK_APPLICATION(self), "win.smartcard-insert");
|
||||
char **old_remove_accels = gtk_application_get_accels_for_action(GTK_APPLICATION(self), "win.smartcard-remove");
|
||||
if (old_insert_accels) {
|
||||
g_strfreev(priv->insert_smartcard_accel);
|
||||
priv->insert_smartcard_accel = old_insert_accels;
|
||||
}
|
||||
if (old_remove_accels) {
|
||||
g_strfreev(priv->remove_smartcard_accel);
|
||||
priv->remove_smartcard_accel = old_remove_accels;
|
||||
}
|
||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.smartcard-insert", no_accels);
|
||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.smartcard-remove", no_accels);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_set_usb_device_reset_accel(VirtViewerApp *self,
|
||||
guint accel_key,
|
||||
GdkModifierType accel_mods)
|
||||
{
|
||||
VirtViewerAppPrivate *priv = virt_viewer_app_get_instance_private(self);
|
||||
|
||||
priv->usb_device_reset_accel_key = accel_key;
|
||||
priv->usb_device_reset_accel_mods = accel_mods;
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_update_usbredir_accels(VirtViewerApp *self)
|
||||
{
|
||||
@ -2212,12 +2179,17 @@ virt_viewer_update_usbredir_accels(VirtViewerApp *self)
|
||||
}
|
||||
|
||||
if (has_usbredir) {
|
||||
gtk_accel_map_change_entry("<virt-viewer>/file/usb-device-reset",
|
||||
priv->usb_device_reset_accel_key,
|
||||
priv->usb_device_reset_accel_mods,
|
||||
TRUE);
|
||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.usb-device-reset",
|
||||
(const gchar * const *)priv->usb_device_reset_accel);
|
||||
} else {
|
||||
gtk_accel_map_change_entry("<virt-viewer>/file/usb-device-reset", 0, 0, TRUE);
|
||||
const gchar *no_accels[] = { NULL };
|
||||
char **old_accels = gtk_application_get_accels_for_action(GTK_APPLICATION(self), "win.usb-device-reset");
|
||||
|
||||
if (old_accels) {
|
||||
g_strfreev(priv->usb_device_reset_accel);
|
||||
priv->usb_device_reset_accel = old_accels;
|
||||
}
|
||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.usb-device-reset", no_accels);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2388,12 +2360,30 @@ static GActionEntry actions[] = {
|
||||
.activate = virt_viewer_app_action_smartcard_remove },
|
||||
};
|
||||
|
||||
struct VirtViewerActionAccels {
|
||||
const char *action;
|
||||
const char *accels[3];
|
||||
};
|
||||
|
||||
static const struct VirtViewerActionAccels action_accels[] = {
|
||||
{ "win.fullscreen", {"F11", NULL, NULL} },
|
||||
{ "win.zoom-in", { "<Ctrl>plus", "<Ctrl>KP_Add", NULL } },
|
||||
{ "win.zoom-out", { "<Ctrl>minus", "<Ctrl>KP_Subtract", NULL } },
|
||||
{ "win.zoom-reset", { "<Ctrl>0", "<Ctrl>KP_0", NULL } },
|
||||
{ "win.release-cursor", {"<Shift>F12", NULL, NULL} },
|
||||
{ "app.smartcard-insert", {"<Shift>F8", NULL, NULL} },
|
||||
{ "app.smartcard-remove", {"<Shift>F9", NULL, NULL} },
|
||||
{ "win.secure-attention", {"<Ctrl><Alt>End", NULL, NULL} },
|
||||
{ "win.usb-device-reset", {"<Ctrl><Shift>r", NULL, NULL} },
|
||||
};
|
||||
|
||||
static void
|
||||
virt_viewer_app_on_application_startup(GApplication *app)
|
||||
{
|
||||
VirtViewerApp *self = VIRT_VIEWER_APP(app);
|
||||
VirtViewerAppPrivate *priv = virt_viewer_app_get_instance_private(self);
|
||||
GError *error = NULL;
|
||||
gint i;
|
||||
|
||||
G_APPLICATION_CLASS(virt_viewer_app_parent_class)->startup(app);
|
||||
|
||||
@ -2404,6 +2394,12 @@ virt_viewer_app_on_application_startup(GApplication *app)
|
||||
|
||||
priv->resource = virt_viewer_get_resource();
|
||||
|
||||
for (i = 0 ; i < G_N_ELEMENTS(action_accels); i++) {
|
||||
gtk_application_set_accels_for_action(GTK_APPLICATION(app),
|
||||
action_accels[i].action,
|
||||
action_accels[i].accels);
|
||||
}
|
||||
|
||||
virt_viewer_app_set_debug(opt_debug);
|
||||
virt_viewer_app_set_fullscreen(self, opt_fullscreen);
|
||||
|
||||
@ -2427,17 +2423,6 @@ virt_viewer_app_on_application_startup(GApplication *app)
|
||||
|
||||
virt_viewer_window_set_zoom_level(priv->main_window, opt_zoom);
|
||||
|
||||
virt_viewer_set_insert_smartcard_accel(self, GDK_KEY_F8, GDK_SHIFT_MASK);
|
||||
virt_viewer_set_remove_smartcard_accel(self, GDK_KEY_F9, GDK_SHIFT_MASK);
|
||||
virt_viewer_set_usb_device_reset_accel(self, GDK_KEY_r, GDK_SHIFT_MASK | GDK_CONTROL_MASK);
|
||||
|
||||
gtk_accel_map_add_entry("<virt-viewer>/view/toggle-fullscreen", GDK_KEY_F11, 0);
|
||||
gtk_accel_map_add_entry("<virt-viewer>/view/release-cursor", GDK_KEY_F12, GDK_SHIFT_MASK);
|
||||
gtk_accel_map_add_entry("<virt-viewer>/view/zoom-reset", GDK_KEY_0, GDK_CONTROL_MASK);
|
||||
gtk_accel_map_add_entry("<virt-viewer>/view/zoom-out", GDK_KEY_minus, GDK_CONTROL_MASK);
|
||||
gtk_accel_map_add_entry("<virt-viewer>/view/zoom-in", GDK_KEY_plus, GDK_CONTROL_MASK);
|
||||
gtk_accel_map_add_entry("<virt-viewer>/send/secure-attention", GDK_KEY_End, GDK_CONTROL_MASK | GDK_MOD1_MASK);
|
||||
|
||||
// Restore initial state of config-share-clipboard property from config and notify about it
|
||||
virt_viewer_app_set_config_share_clipboard(self, virt_viewer_app_get_config_share_clipboard(self));
|
||||
|
||||
@ -2675,16 +2660,14 @@ gboolean virt_viewer_app_get_direct(VirtViewerApp *self)
|
||||
void
|
||||
virt_viewer_app_clear_hotkeys(VirtViewerApp *self)
|
||||
{
|
||||
/* Disable default bindings and replace them with our own */
|
||||
gtk_accel_map_change_entry("<virt-viewer>/view/toggle-fullscreen", 0, 0, TRUE);
|
||||
gtk_accel_map_change_entry("<virt-viewer>/view/release-cursor", 0, 0, TRUE);
|
||||
gtk_accel_map_change_entry("<virt-viewer>/view/zoom-reset", 0, 0, TRUE);
|
||||
gtk_accel_map_change_entry("<virt-viewer>/view/zoom-in", 0, 0, TRUE);
|
||||
gtk_accel_map_change_entry("<virt-viewer>/view/zoom-out", 0, 0, TRUE);
|
||||
gtk_accel_map_change_entry("<virt-viewer>/send/secure-attention", 0, 0, TRUE);
|
||||
virt_viewer_set_insert_smartcard_accel(self, 0, 0);
|
||||
virt_viewer_set_remove_smartcard_accel(self, 0, 0);
|
||||
virt_viewer_set_usb_device_reset_accel(self, 0, 0);
|
||||
gint i;
|
||||
const gchar *no_accels[] = { NULL };
|
||||
|
||||
for (i = 0 ; i < G_N_ELEMENTS(action_accels); i++) {
|
||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self),
|
||||
action_accels[i].action,
|
||||
no_accels);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -2708,6 +2691,8 @@ 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);
|
||||
virt_viewer_update_smartcard_accels(self);
|
||||
virt_viewer_update_usbredir_accels(self);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2724,38 +2709,37 @@ virt_viewer_app_set_hotkeys(VirtViewerApp *self, const gchar *hotkeys_str)
|
||||
gchar *accel = spice_hotkey_to_gtk_accelerator(value);
|
||||
guint accel_key;
|
||||
GdkModifierType accel_mods;
|
||||
const gchar *accels[] = { accel, NULL };
|
||||
gtk_accelerator_parse(accel, &accel_key, &accel_mods);
|
||||
g_free(accel);
|
||||
|
||||
if (accel_key == 0 && accel_mods == 0) {
|
||||
g_warning("Invalid value '%s' for key '%s'", value, *hotkey);
|
||||
g_free(accel);
|
||||
continue;
|
||||
}
|
||||
|
||||
gboolean status = TRUE;
|
||||
if (g_str_equal(*hotkey, "toggle-fullscreen")) {
|
||||
status = gtk_accel_map_change_entry("<virt-viewer>/view/toggle-fullscreen", accel_key, accel_mods, TRUE);
|
||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.fullscreen", accels);
|
||||
} else if (g_str_equal(*hotkey, "release-cursor")) {
|
||||
status = gtk_accel_map_change_entry("<virt-viewer>/view/release-cursor", accel_key, accel_mods, TRUE);
|
||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.release-cursor", accels);
|
||||
} else if (g_str_equal(*hotkey, "zoom-reset")) {
|
||||
status = gtk_accel_map_change_entry("<virt-viewer>/view/zoom-reset", accel_key, accel_mods, TRUE);
|
||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.zoom-reset", accels);
|
||||
} else if (g_str_equal(*hotkey, "zoom-out")) {
|
||||
status = gtk_accel_map_change_entry("<virt-viewer>/view/zoom-out", accel_key, accel_mods, TRUE);
|
||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.zoom-out", accels);
|
||||
} else if (g_str_equal(*hotkey, "zoom-in")) {
|
||||
status = gtk_accel_map_change_entry("<virt-viewer>/view/zoom-in", accel_key, accel_mods, TRUE);
|
||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.zoom-in", accels);
|
||||
} else if (g_str_equal(*hotkey, "secure-attention")) {
|
||||
status = gtk_accel_map_change_entry("<virt-viewer>/send/secure-attention", accel_key, accel_mods, TRUE);
|
||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.secure-attention", accels);
|
||||
} else if (g_str_equal(*hotkey, "smartcard-insert")) {
|
||||
virt_viewer_set_insert_smartcard_accel(self, accel_key, accel_mods);
|
||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "app.smartcard-insert", accels);
|
||||
} else if (g_str_equal(*hotkey, "smartcard-remove")) {
|
||||
virt_viewer_set_remove_smartcard_accel(self, accel_key, accel_mods);
|
||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "app.smartcard-remove", accels);
|
||||
} else if (g_str_equal(*hotkey, "usb-device-reset")) {
|
||||
virt_viewer_set_usb_device_reset_accel(self, accel_key, accel_mods);
|
||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "app.usb-device-reset", accels);
|
||||
} else {
|
||||
g_warning("Unknown hotkey command %s", *hotkey);
|
||||
}
|
||||
if (!status)
|
||||
g_warning("Unable to set hotkey for '%s' due to a conflict in GTK", *hotkey);
|
||||
g_free(accel);
|
||||
}
|
||||
g_strfreev(hotkeys);
|
||||
|
||||
|
||||
@ -237,15 +237,21 @@ enable_accel_changed(VirtViewerApp *app,
|
||||
GParamSpec *pspec G_GNUC_UNUSED,
|
||||
VirtViewerDisplaySpice *self)
|
||||
{
|
||||
GtkAccelKey key = {0, 0, 0};
|
||||
gboolean kiosk;
|
||||
guint accel_key = 0;
|
||||
GdkModifierType accel_mods = 0;
|
||||
gchar **accels;
|
||||
|
||||
if (virt_viewer_app_get_enable_accel(app))
|
||||
gtk_accel_map_lookup_entry("<virt-viewer>/view/release-cursor", &key);
|
||||
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);
|
||||
}
|
||||
|
||||
g_object_get(app, "kiosk", &kiosk, NULL);
|
||||
|
||||
if (key.accel_key || key.accel_mods || kiosk) {
|
||||
if (accel_key || accel_mods || kiosk) {
|
||||
SpiceGrabSequence *seq = spice_grab_sequence_new(0, NULL);
|
||||
/* disable default grab sequence */
|
||||
spice_display_set_grab_keys(self->display, seq);
|
||||
|
||||
@ -187,15 +187,21 @@ enable_accel_changed(VirtViewerApp *app,
|
||||
GParamSpec *pspec G_GNUC_UNUSED,
|
||||
VncDisplay *vnc)
|
||||
{
|
||||
GtkAccelKey key = {0, 0, 0};
|
||||
gboolean kiosk;
|
||||
guint accel_key = 0;
|
||||
GdkModifierType accel_mods = 0;
|
||||
gchar **accels;
|
||||
|
||||
if (virt_viewer_app_get_enable_accel(app))
|
||||
gtk_accel_map_lookup_entry("<virt-viewer>/view/release-cursor", &key);
|
||||
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);
|
||||
}
|
||||
|
||||
g_object_get(app, "kiosk", &kiosk, NULL);
|
||||
|
||||
if (key.accel_key || key.accel_mods || kiosk) {
|
||||
if (accel_key || accel_mods || kiosk) {
|
||||
VncGrabSequence *seq = vnc_grab_sequence_new(0, NULL);
|
||||
/* disable default grab sequence */
|
||||
vnc_display_set_grab_keys(vnc, seq);
|
||||
|
||||
@ -869,17 +869,14 @@ virt_viewer_file_set_ovirt_admin(VirtViewerFile* self, gint value)
|
||||
}
|
||||
|
||||
static void
|
||||
spice_hotkey_set_accel(const gchar *accel_path, const gchar *key)
|
||||
spice_hotkey_set_accel(VirtViewerApp *app, const gchar *action_name, const gchar *key)
|
||||
{
|
||||
gchar *accel;
|
||||
guint accel_key;
|
||||
GdkModifierType accel_mods;
|
||||
gchar *accel = spice_hotkey_to_gtk_accelerator(key);
|
||||
const gchar *accels[] = { accel, NULL };
|
||||
|
||||
gtk_application_set_accels_for_action(GTK_APPLICATION(app), action_name, accels);
|
||||
|
||||
accel = spice_hotkey_to_gtk_accelerator(key);
|
||||
gtk_accelerator_parse(accel, &accel_key, &accel_mods);
|
||||
g_free(accel);
|
||||
|
||||
gtk_accel_map_change_entry(accel_path, accel_key, accel_mods, TRUE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -960,16 +957,16 @@ virt_viewer_file_fill_app(VirtViewerFile* self, VirtViewerApp *app, GError **err
|
||||
gchar *val;
|
||||
static const struct {
|
||||
const char *prop;
|
||||
const char *accel;
|
||||
const char *action_name;
|
||||
} accels[] = {
|
||||
{ "release-cursor", "<virt-viewer>/view/release-cursor" },
|
||||
{ "toggle-fullscreen", "<virt-viewer>/view/toggle-fullscreen" },
|
||||
{ "zoom-in", "<virt-viewer>/view/zoom-in" },
|
||||
{ "zoom-out", "<virt-viewer>/view/zoom-out" },
|
||||
{ "zoom-reset", "<virt-viewer>/view/zoom-reset" },
|
||||
{ "smartcard-insert", "<virt-viewer>/file/smartcard-insert" },
|
||||
{ "smartcard-remove", "<virt-viewer>/file/smartcard-remove" },
|
||||
{ "secure-attention", "<virt-viewer>/send/secure-attention" }
|
||||
{ "release-cursor", "win.release-cursor" },
|
||||
{ "toggle-fullscreen", "win.fullscreen" },
|
||||
{ "zoom-in", "win.zoom-in" },
|
||||
{ "zoom-out", "win.zoom-out" },
|
||||
{ "zoom-reset", "win.zoom-reset" },
|
||||
{ "smartcard-insert", "app.smartcard-insert" },
|
||||
{ "smartcard-remove", "app.smartcard-remove" },
|
||||
{ "secure-attention", "win.secure-attention" },
|
||||
};
|
||||
int i;
|
||||
|
||||
@ -977,7 +974,7 @@ virt_viewer_file_fill_app(VirtViewerFile* self, VirtViewerApp *app, GError **err
|
||||
if (!virt_viewer_file_is_set(self, accels[i].prop))
|
||||
continue;
|
||||
g_object_get(self, accels[i].prop, &val, NULL);
|
||||
spice_hotkey_set_accel(accels[i].accel, val);
|
||||
spice_hotkey_set_accel(app, accels[i].action_name, val);
|
||||
g_free(val);
|
||||
}
|
||||
}
|
||||
|
||||
@ -501,6 +501,20 @@ virt_viewer_window_action_change_cd(GSimpleAction *act G_GNUC_UNUSED,
|
||||
virt_viewer_window_change_cd(VIRT_VIEWER_WINDOW(opaque));
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_window_action_secure_attention(GSimpleAction *action G_GNUC_UNUSED,
|
||||
GVariant *param G_GNUC_UNUSED,
|
||||
gpointer opaque)
|
||||
{
|
||||
g_return_if_fail(VIRT_VIEWER_IS_WINDOW(opaque));
|
||||
|
||||
VirtViewerWindow *self = VIRT_VIEWER_WINDOW(opaque);
|
||||
guint keys[] = { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_Delete };
|
||||
|
||||
virt_viewer_display_send_keys(VIRT_VIEWER_DISPLAY(self->display),
|
||||
keys, G_N_ELEMENTS(keys));
|
||||
}
|
||||
|
||||
static GActionEntry actions[] = {
|
||||
{ .name = "zoom-out",
|
||||
.activate = virt_viewer_window_action_zoom_out },
|
||||
@ -534,6 +548,8 @@ static GActionEntry actions[] = {
|
||||
.activate = virt_viewer_window_action_preferences },
|
||||
{ .name = "change-cd",
|
||||
.activate = virt_viewer_window_action_change_cd },
|
||||
{ .name = "secure-attention",
|
||||
.activate = virt_viewer_window_action_secure_attention },
|
||||
};
|
||||
|
||||
static void
|
||||
@ -789,27 +805,26 @@ virt_viewer_window_enter_fullscreen(VirtViewerWindow *self, gint monitor)
|
||||
struct keyComboDef {
|
||||
guint32 keys[MAX_KEY_COMBO];
|
||||
const char *accel_label;
|
||||
const gchar* accel_path;
|
||||
};
|
||||
|
||||
static const struct keyComboDef keyCombos[] = {
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_Delete, GDK_KEY_VoidSymbol }, "<Control><Alt>Delete", "<virt-viewer>/send/secure-attention"},
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_BackSpace, GDK_KEY_VoidSymbol }, "<Control><Alt>BackSpace", NULL},
|
||||
{ { GDK_KEY_VoidSymbol }, "" , NULL},
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F1, GDK_KEY_VoidSymbol }, "<Control><Alt>F1", NULL},
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F2, GDK_KEY_VoidSymbol }, "<Control><Alt>F2", NULL},
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F3, GDK_KEY_VoidSymbol }, "<Control><Alt>F3", NULL},
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F4, GDK_KEY_VoidSymbol }, "<Control><Alt>F4", NULL},
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F5, GDK_KEY_VoidSymbol }, "<Control><Alt>F5", NULL},
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F6, GDK_KEY_VoidSymbol }, "<Control><Alt>F6", NULL},
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F7, GDK_KEY_VoidSymbol }, "<Control><Alt>F7", NULL},
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F8, GDK_KEY_VoidSymbol }, "<Control><Alt>F8", NULL},
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F9, GDK_KEY_VoidSymbol }, "<Control><Alt>F9", NULL},
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F10, GDK_KEY_VoidSymbol }, "<Control><Alt>F10", NULL},
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F11, GDK_KEY_VoidSymbol }, "<Control><Alt>F11", NULL},
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F12, GDK_KEY_VoidSymbol }, "<Control><Alt>F12", NULL},
|
||||
{ { GDK_KEY_VoidSymbol }, "" , NULL},
|
||||
{ { GDK_KEY_Print, GDK_KEY_VoidSymbol }, "Print", NULL},
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_Delete, GDK_KEY_VoidSymbol }, "<Control><Alt>Delete" },
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_BackSpace, GDK_KEY_VoidSymbol }, "<Control><Alt>BackSpace" },
|
||||
{ { GDK_KEY_VoidSymbol }, "" },
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F1, GDK_KEY_VoidSymbol }, "<Control><Alt>F1" },
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F2, GDK_KEY_VoidSymbol }, "<Control><Alt>F2" },
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F3, GDK_KEY_VoidSymbol }, "<Control><Alt>F3" },
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F4, GDK_KEY_VoidSymbol }, "<Control><Alt>F4" },
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F5, GDK_KEY_VoidSymbol }, "<Control><Alt>F5" },
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F6, GDK_KEY_VoidSymbol }, "<Control><Alt>F6" },
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F7, GDK_KEY_VoidSymbol }, "<Control><Alt>F7" },
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F8, GDK_KEY_VoidSymbol }, "<Control><Alt>F8" },
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F9, GDK_KEY_VoidSymbol }, "<Control><Alt>F9" },
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F10, GDK_KEY_VoidSymbol }, "<Control><Alt>F10" },
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F11, GDK_KEY_VoidSymbol }, "<Control><Alt>F11" },
|
||||
{ { GDK_KEY_Control_L, GDK_KEY_Alt_L, GDK_KEY_F12, GDK_KEY_VoidSymbol }, "<Control><Alt>F12" },
|
||||
{ { GDK_KEY_VoidSymbol }, "" },
|
||||
{ { GDK_KEY_Print, GDK_KEY_VoidSymbol }, "Print" },
|
||||
};
|
||||
|
||||
static guint
|
||||
@ -824,8 +839,8 @@ get_nkeys(const guint32 *keys)
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_menu_add_combo(VirtViewerWindow *self, GtkMenu *menu,
|
||||
const guint *keys, const gchar *label, const gchar* accel_path)
|
||||
virt_viewer_menu_add_combo(VirtViewerWindow *self G_GNUC_UNUSED, GtkMenu *menu,
|
||||
const guint *keys, const gchar *label)
|
||||
{
|
||||
GtkWidget *item;
|
||||
|
||||
@ -833,11 +848,6 @@ virt_viewer_menu_add_combo(VirtViewerWindow *self, GtkMenu *menu,
|
||||
item = gtk_separator_menu_item_new();
|
||||
} else {
|
||||
item = gtk_menu_item_new_with_label(label);
|
||||
if (accel_path) {
|
||||
gtk_menu_item_set_accel_path(GTK_MENU_ITEM(item), accel_path);
|
||||
/* make accel work in fullscreen */
|
||||
g_signal_connect(item, "can-activate-accel", G_CALLBACK(can_activate_cb), self);
|
||||
}
|
||||
gtk_actionable_set_action_name(GTK_ACTIONABLE(item), "win.send-key");
|
||||
gtk_actionable_set_action_target_value(GTK_ACTIONABLE(item),
|
||||
g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
|
||||
@ -850,7 +860,8 @@ virt_viewer_menu_add_combo(VirtViewerWindow *self, GtkMenu *menu,
|
||||
}
|
||||
|
||||
static guint*
|
||||
accel_key_to_keys(const GtkAccelKey *key)
|
||||
accel_key_to_keys(guint accel_key,
|
||||
GdkModifierType accel_mods)
|
||||
{
|
||||
guint i;
|
||||
guint *val, *keys;
|
||||
@ -863,59 +874,28 @@ accel_key_to_keys(const GtkAccelKey *key)
|
||||
{GDK_MOD1_MASK, GDK_KEY_Alt_L},
|
||||
};
|
||||
|
||||
g_warn_if_fail((key->accel_mods &
|
||||
g_warn_if_fail((accel_mods &
|
||||
~(GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)) == 0);
|
||||
|
||||
keys = val = g_new(guint, G_N_ELEMENTS(modifiers) + 2); /* up to 3 modifiers, key and the stop symbol */
|
||||
/* first, send the modifiers */
|
||||
for (i = 0; i < G_N_ELEMENTS(modifiers); i++) {
|
||||
if (key->accel_mods & modifiers[i].mask)
|
||||
if (accel_mods & modifiers[i].mask)
|
||||
*val++ = modifiers[i].key;
|
||||
}
|
||||
|
||||
/* only after, the non-modifier key (ctrl-t, not t-ctrl) */
|
||||
*val++ = key->accel_key;
|
||||
*val++ = accel_key;
|
||||
/* stop symbol */
|
||||
*val = GDK_KEY_VoidSymbol;
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
struct accelCbData
|
||||
{
|
||||
VirtViewerWindow *self;
|
||||
GtkMenu *menu;
|
||||
};
|
||||
|
||||
static void
|
||||
accel_map_item_cb(gpointer data,
|
||||
const gchar *accel_path,
|
||||
guint accel_key,
|
||||
GdkModifierType accel_mods,
|
||||
gboolean changed G_GNUC_UNUSED)
|
||||
{
|
||||
struct accelCbData *d = data;
|
||||
GtkAccelKey key = {
|
||||
.accel_key = accel_key,
|
||||
.accel_mods = accel_mods
|
||||
};
|
||||
|
||||
if (!g_str_has_prefix(accel_path, "<virt-viewer>"))
|
||||
return;
|
||||
if (accel_key == GDK_KEY_VoidSymbol || accel_key == 0)
|
||||
return;
|
||||
|
||||
guint *keys = accel_key_to_keys(&key);
|
||||
gchar *label = gtk_accelerator_get_label(accel_key, accel_mods);
|
||||
virt_viewer_menu_add_combo(d->self, d->menu, keys, label, NULL);
|
||||
g_free(label);
|
||||
g_free(keys);
|
||||
}
|
||||
|
||||
static GtkMenu*
|
||||
virt_viewer_window_get_keycombo_menu(VirtViewerWindow *self)
|
||||
{
|
||||
gint i;
|
||||
gint i, j;
|
||||
GtkMenu *menu = GTK_MENU(gtk_menu_new());
|
||||
gtk_menu_set_accel_group(menu, self->accel_group);
|
||||
|
||||
@ -927,43 +907,44 @@ virt_viewer_window_get_keycombo_menu(VirtViewerWindow *self)
|
||||
gtk_accelerator_parse(keyCombos[i].accel_label, &key, &mods);
|
||||
label = gtk_accelerator_get_label(key, mods);
|
||||
}
|
||||
virt_viewer_menu_add_combo(self, menu, keyCombos[i].keys, label, keyCombos[i].accel_path);
|
||||
virt_viewer_menu_add_combo(self, menu, keyCombos[i].keys, label);
|
||||
g_free(label);
|
||||
}
|
||||
|
||||
if (virt_viewer_app_get_enable_accel(self->app)) {
|
||||
struct accelCbData d = {
|
||||
.self = self,
|
||||
.menu = menu
|
||||
};
|
||||
gchar **accelactions = gtk_application_list_action_descriptions(GTK_APPLICATION(self->app));
|
||||
|
||||
gtk_accel_map_foreach(&d, accel_map_item_cb);
|
||||
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++) {
|
||||
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, menu, keys, label);
|
||||
g_free(label);
|
||||
g_free(keys);
|
||||
}
|
||||
g_strfreev(accels);
|
||||
}
|
||||
|
||||
g_strfreev(accelactions);
|
||||
}
|
||||
|
||||
gtk_widget_show_all(GTK_WIDGET(menu));
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
||||
struct VirtViewerActionAccels {
|
||||
const char *accels[2];
|
||||
const char *action;
|
||||
};
|
||||
|
||||
static const struct VirtViewerActionAccels action_accels[] = {
|
||||
/* numpad keys are not handled automatically by gtk, see bgo#699823 */
|
||||
{ {"<control>KP_Add", NULL}, "win.zoom-in" },
|
||||
{ {"<control>KP_Subtract", NULL}, "win.zoom-out" },
|
||||
{ {"<control>KP_0", NULL}, "win.zoom-reset" },
|
||||
};
|
||||
|
||||
void
|
||||
virt_viewer_window_disable_modifiers(VirtViewerWindow *self)
|
||||
{
|
||||
GtkSettings *settings = gtk_settings_get_default();
|
||||
GValue empty;
|
||||
GSList *accels;
|
||||
guint i;
|
||||
|
||||
if (!self->accel_enabled)
|
||||
return;
|
||||
@ -991,13 +972,6 @@ virt_viewer_window_disable_modifiers(VirtViewerWindow *self)
|
||||
"gtk-enable-mnemonics", FALSE,
|
||||
NULL);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS(action_accels); i++) {
|
||||
const char *noaccels[1] = { NULL };
|
||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self->app),
|
||||
action_accels[i].action,
|
||||
noaccels);
|
||||
}
|
||||
|
||||
self->accel_enabled = FALSE;
|
||||
}
|
||||
|
||||
@ -1006,8 +980,6 @@ virt_viewer_window_enable_modifiers(VirtViewerWindow *self)
|
||||
{
|
||||
GtkSettings *settings = gtk_settings_get_default();
|
||||
GSList *accels;
|
||||
guint i;
|
||||
GtkAccelKey key;
|
||||
GSList *attached_accels;
|
||||
|
||||
if (self->accel_enabled)
|
||||
@ -1031,19 +1003,6 @@ virt_viewer_window_enable_modifiers(VirtViewerWindow *self)
|
||||
"gtk-enable-mnemonics", self->enable_mnemonics_save,
|
||||
NULL);
|
||||
|
||||
/* if the user did not set hotkeys and
|
||||
* zoom actions using "normal" +/-/0 keys are enabled,
|
||||
* allow the user to use the numpad +/-/0 keys as well */
|
||||
if (!virt_viewer_app_get_enable_accel(self->app)
|
||||
&& gtk_accel_map_lookup_entry("<virt-viewer>/view/zoom-out", &key)
|
||||
&& key.accel_key != 0) {
|
||||
for (i = 0; i < G_N_ELEMENTS(action_accels); i++) {
|
||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self->app),
|
||||
action_accels[i].action,
|
||||
action_accels[i].accels);
|
||||
}
|
||||
}
|
||||
|
||||
self->accel_enabled = TRUE;
|
||||
}
|
||||
|
||||
@ -1453,14 +1412,20 @@ virt_viewer_window_update_title(VirtViewerWindow *self)
|
||||
|
||||
if (self->grabbed) {
|
||||
gchar *label;
|
||||
GtkAccelKey key = {0, 0, 0};
|
||||
guint accel_key = 0;
|
||||
GdkModifierType accel_mods = 0;
|
||||
gchar **accels;
|
||||
|
||||
if (virt_viewer_app_get_enable_accel(self->app))
|
||||
gtk_accel_map_lookup_entry("<virt-viewer>/view/release-cursor", &key);
|
||||
if (virt_viewer_app_get_enable_accel(self->app)) {
|
||||
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 (key.accel_key || key.accel_mods) {
|
||||
g_debug("release-cursor accel key: key=%u, mods=%x, flags=%u", key.accel_key, key.accel_mods, key.accel_flags);
|
||||
label = gtk_accelerator_get_label(key.accel_key, key.accel_mods);
|
||||
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"));
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user