mirror of
https://gitlab.com/virt-viewer/virt-viewer.git
synced 2024-12-21 09:33:59 +03:00
src: Unify hotkey setup from command line and config file
This is mostly just code de-duplication and cleanup. The only functional change is that the case-sensitive accel support from the command-line hotkey handling now also applies to the config file. Signed-off-by: Paul Donohue <git@PaulSD.com>
This commit is contained in:
parent
af644ec423
commit
0a997601ab
@ -2429,22 +2429,23 @@ static GActionEntry actions[] = {
|
|||||||
.change_state = virt_viewer_app_action_auto_resize },
|
.change_state = virt_viewer_app_action_auto_resize },
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VirtViewerActionAccels {
|
static const struct {
|
||||||
|
const char *name;
|
||||||
const char *action;
|
const char *action;
|
||||||
const char *accels[3];
|
const gchar *default_accels[3];
|
||||||
|
} hotkey_defaults[] = {
|
||||||
|
{ "toggle-fullscreen", "win.fullscreen", {"F11", NULL, NULL} },
|
||||||
|
{ "zoom-in", "win.zoom-in", { "<Ctrl>plus", "<Ctrl>KP_Add", NULL } },
|
||||||
|
{ "zoom-out", "win.zoom-out", { "<Ctrl>minus", "<Ctrl>KP_Subtract", NULL } },
|
||||||
|
{ "zoom-reset", "win.zoom-reset", { "<Ctrl>0", "<Ctrl>KP_0", NULL } },
|
||||||
|
{ "release-cursor", "win.release-cursor", {"<Shift>F12", NULL, NULL} },
|
||||||
|
{ "smartcard-insert", "app.smartcard-insert", {"<Shift>F8", NULL, NULL} },
|
||||||
|
{ "smartcard-remove", "app.smartcard-remove", {"<Shift>F9", NULL, NULL} },
|
||||||
|
{ "secure-attention", "win.secure-attention", {"<Ctrl><Alt>End", NULL, NULL} },
|
||||||
|
{ "usb-device-reset", "win.usb-device-reset", {"<Ctrl><Shift>r", NULL, NULL} },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct VirtViewerActionAccels action_accels[] = {
|
static gchar **hotkey_names;
|
||||||
{ "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
|
static void
|
||||||
virt_viewer_app_on_application_startup(GApplication *app)
|
virt_viewer_app_on_application_startup(GApplication *app)
|
||||||
@ -2468,12 +2469,6 @@ virt_viewer_app_on_application_startup(GApplication *app)
|
|||||||
|
|
||||||
priv->resource = virt_viewer_get_resource();
|
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_debug(opt_debug);
|
||||||
virt_viewer_app_set_fullscreen(self, opt_fullscreen);
|
virt_viewer_app_set_fullscreen(self, opt_fullscreen);
|
||||||
|
|
||||||
@ -2483,11 +2478,21 @@ virt_viewer_app_on_application_startup(GApplication *app)
|
|||||||
priv->quit_on_disconnect = opt_kiosk ? opt_kiosk_quit : TRUE;
|
priv->quit_on_disconnect = opt_kiosk ? opt_kiosk_quit : TRUE;
|
||||||
|
|
||||||
priv->main_window = virt_viewer_app_window_new(self,
|
priv->main_window = virt_viewer_app_window_new(self,
|
||||||
virt_viewer_app_get_first_monitor(self));
|
virt_viewer_app_get_first_monitor(self));
|
||||||
priv->main_notebook = GTK_WIDGET(virt_viewer_window_get_notebook(priv->main_window));
|
priv->main_notebook = GTK_WIDGET(virt_viewer_window_get_notebook(priv->main_window));
|
||||||
priv->initial_display_map = virt_viewer_app_get_monitor_mapping_for_section(self, "fallback");
|
priv->initial_display_map = virt_viewer_app_get_monitor_mapping_for_section(self, "fallback");
|
||||||
|
|
||||||
virt_viewer_app_set_kiosk(self, opt_kiosk);
|
virt_viewer_app_set_kiosk(self, opt_kiosk);
|
||||||
|
|
||||||
|
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);
|
||||||
|
gtk_application_set_accels_for_action(GTK_APPLICATION(app),
|
||||||
|
hotkey_defaults[i].action,
|
||||||
|
hotkey_defaults[i].default_accels);
|
||||||
|
}
|
||||||
|
hotkey_names[i] = NULL;
|
||||||
|
|
||||||
virt_viewer_app_set_hotkeys(self, opt_hotkeys);
|
virt_viewer_app_set_hotkeys(self, opt_hotkeys);
|
||||||
|
|
||||||
if (opt_zoom < MIN_ZOOM_LEVEL || opt_zoom > MAX_ZOOM_LEVEL) {
|
if (opt_zoom < MIN_ZOOM_LEVEL || opt_zoom > MAX_ZOOM_LEVEL) {
|
||||||
@ -2816,19 +2821,71 @@ virt_viewer_app_set_enable_accel(VirtViewerApp *self, gboolean enable)
|
|||||||
g_object_notify(G_OBJECT(self), "enable-accel");
|
g_object_notify(G_OBJECT(self), "enable-accel");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gchar**
|
||||||
|
virt_viewer_app_get_hotkey_names(void)
|
||||||
|
{
|
||||||
|
return hotkey_names;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
virt_viewer_app_clear_hotkeys(VirtViewerApp *self)
|
virt_viewer_app_clear_hotkeys(VirtViewerApp *self)
|
||||||
{
|
{
|
||||||
gint i;
|
gint i;
|
||||||
const gchar *no_accels[] = { NULL };
|
const gchar *no_accels[] = { NULL };
|
||||||
|
|
||||||
for (i = 0 ; i < G_N_ELEMENTS(action_accels); i++) {
|
for (i = 0 ; i < G_N_ELEMENTS(hotkey_defaults); i++) {
|
||||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self),
|
gtk_application_set_accels_for_action(GTK_APPLICATION(self),
|
||||||
action_accels[i].action,
|
hotkey_defaults[i].action,
|
||||||
no_accels);
|
no_accels);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
virt_viewer_app_set_hotkey(VirtViewerApp *self, const gchar *hotkey_name,
|
||||||
|
const gchar *hotkey)
|
||||||
|
{
|
||||||
|
g_return_if_fail(VIRT_VIEWER_IS_APP(self));
|
||||||
|
|
||||||
|
const gchar *action = NULL;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < G_N_ELEMENTS(hotkey_defaults); i++) {
|
||||||
|
if (g_str_equal(hotkey_name, hotkey_defaults[i].name)) {
|
||||||
|
action = hotkey_defaults[i].action;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (action == NULL) {
|
||||||
|
g_warning("Unknown hotkey name %s", hotkey_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar *accel = spice_hotkey_to_gtk_accelerator(hotkey);
|
||||||
|
const gchar *accels[] = { accel, NULL };
|
||||||
|
guint accel_key;
|
||||||
|
GdkModifierType accel_mods;
|
||||||
|
/*
|
||||||
|
* First try the spice translated accel.
|
||||||
|
* Works for basic modifiers and single letters/numbers
|
||||||
|
* where forced uppercasing matches GTK key names
|
||||||
|
*/
|
||||||
|
gtk_accelerator_parse(accels[0], &accel_key, &accel_mods);
|
||||||
|
if (accel_key == 0 && accel_mods == 0) {
|
||||||
|
/* Fallback to native GTK accels to cope with
|
||||||
|
* case sensitive accels
|
||||||
|
*/
|
||||||
|
accels[0] = hotkey;
|
||||||
|
gtk_accelerator_parse(accels[0], &accel_key, &accel_mods);
|
||||||
|
}
|
||||||
|
if (accel_key == 0 && accel_mods == 0) {
|
||||||
|
g_warning("Invalid hotkey '%s' for '%s'", hotkey, hotkey_name);
|
||||||
|
g_free(accel);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_application_set_accels_for_action(GTK_APPLICATION(self), action, accels);
|
||||||
|
g_free(accel);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
virt_viewer_app_set_hotkeys(VirtViewerApp *self, const gchar *hotkeys_str)
|
virt_viewer_app_set_hotkeys(VirtViewerApp *self, const gchar *hotkeys_str)
|
||||||
{
|
{
|
||||||
@ -2850,61 +2907,14 @@ virt_viewer_app_set_hotkeys(VirtViewerApp *self, const gchar *hotkeys_str)
|
|||||||
virt_viewer_app_clear_hotkeys(self);
|
virt_viewer_app_clear_hotkeys(self);
|
||||||
|
|
||||||
for (hotkey = hotkeys; *hotkey != NULL; hotkey++) {
|
for (hotkey = hotkeys; *hotkey != NULL; hotkey++) {
|
||||||
gchar *key = strstr(*hotkey, "=");
|
gchar *eq = strstr(*hotkey, "=");
|
||||||
const gchar *value = (key == NULL) ? NULL : (*key = '\0', key + 1);
|
const gchar *value = (eq == NULL) ? NULL : (*eq = '\0', eq + 1);
|
||||||
if (value == NULL || *value == '\0') {
|
if (value == NULL || *value == '\0') {
|
||||||
g_warning("missing value for key '%s'", *hotkey);
|
g_warning("Missing value for hotkey '%s'", *hotkey);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
gchar *accel = spice_hotkey_to_gtk_accelerator(value);
|
virt_viewer_app_set_hotkey(self, *hotkey, value);
|
||||||
guint accel_key;
|
|
||||||
GdkModifierType accel_mods;
|
|
||||||
const gchar *accels[] = { accel, NULL };
|
|
||||||
|
|
||||||
/*
|
|
||||||
* First try the spice translated accel.
|
|
||||||
* Works for basic modifiers and single letters/numbers
|
|
||||||
* where forced uppercasing matches GTK key names
|
|
||||||
*/
|
|
||||||
gtk_accelerator_parse(accels[0], &accel_key, &accel_mods);
|
|
||||||
|
|
||||||
if (accel_key == 0 && accel_mods == 0) {
|
|
||||||
/* Fallback to native GTK accels to cope with
|
|
||||||
* case sensitive accels
|
|
||||||
*/
|
|
||||||
accels[0] = value;
|
|
||||||
gtk_accelerator_parse(accels[0], &accel_key, &accel_mods);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (accel_key == 0 && accel_mods == 0) {
|
|
||||||
g_warning("Invalid value '%s' for key '%s'", value, *hotkey);
|
|
||||||
g_free(accel);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_str_equal(*hotkey, "toggle-fullscreen")) {
|
|
||||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.fullscreen", accels);
|
|
||||||
} else if (g_str_equal(*hotkey, "release-cursor")) {
|
|
||||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.release-cursor", accels);
|
|
||||||
} else if (g_str_equal(*hotkey, "zoom-reset")) {
|
|
||||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.zoom-reset", accels);
|
|
||||||
} else if (g_str_equal(*hotkey, "zoom-out")) {
|
|
||||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.zoom-out", accels);
|
|
||||||
} else if (g_str_equal(*hotkey, "zoom-in")) {
|
|
||||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.zoom-in", accels);
|
|
||||||
} else if (g_str_equal(*hotkey, "secure-attention")) {
|
|
||||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.secure-attention", accels);
|
|
||||||
} else if (g_str_equal(*hotkey, "smartcard-insert")) {
|
|
||||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "app.smartcard-insert", accels);
|
|
||||||
} else if (g_str_equal(*hotkey, "smartcard-remove")) {
|
|
||||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "app.smartcard-remove", accels);
|
|
||||||
} else if (g_str_equal(*hotkey, "usb-device-reset")) {
|
|
||||||
gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.usb-device-reset", accels);
|
|
||||||
} else {
|
|
||||||
g_warning("Unknown hotkey command %s", *hotkey);
|
|
||||||
}
|
|
||||||
g_free(accel);
|
|
||||||
}
|
}
|
||||||
g_strfreev(hotkeys);
|
g_strfreev(hotkeys);
|
||||||
|
|
||||||
|
@ -72,6 +72,8 @@ gboolean virt_viewer_app_activate(VirtViewerApp *self, GError **error);
|
|||||||
gboolean virt_viewer_app_initial_connect(VirtViewerApp *self, GError **error);
|
gboolean virt_viewer_app_initial_connect(VirtViewerApp *self, GError **error);
|
||||||
gboolean virt_viewer_app_get_direct(VirtViewerApp *self);
|
gboolean virt_viewer_app_get_direct(VirtViewerApp *self);
|
||||||
void virt_viewer_app_set_direct(VirtViewerApp *self, gboolean direct);
|
void virt_viewer_app_set_direct(VirtViewerApp *self, gboolean direct);
|
||||||
|
char** virt_viewer_app_get_hotkey_names(void);
|
||||||
|
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_hotkeys(VirtViewerApp *self, const gchar *hotkeys);
|
||||||
void virt_viewer_app_set_attach(VirtViewerApp *self, gboolean attach);
|
void virt_viewer_app_set_attach(VirtViewerApp *self, gboolean attach);
|
||||||
gboolean virt_viewer_app_get_attach(VirtViewerApp *self);
|
gboolean virt_viewer_app_get_attach(VirtViewerApp *self);
|
||||||
|
@ -883,17 +883,6 @@ virt_viewer_file_set_ovirt_admin(VirtViewerFile* self, gint value)
|
|||||||
g_object_notify(G_OBJECT(self), "ovirt-admin");
|
g_object_notify(G_OBJECT(self), "ovirt-admin");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
spice_hotkey_set_accel(VirtViewerApp *app, const gchar *action_name, const gchar *key)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
g_free(accel);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
virt_viewer_file_check_min_version(VirtViewerFile *self, GError **error)
|
virt_viewer_file_check_min_version(VirtViewerFile *self, GError **error)
|
||||||
{
|
{
|
||||||
@ -969,28 +958,14 @@ virt_viewer_file_fill_app(VirtViewerFile* self, VirtViewerApp *app, GError **err
|
|||||||
virt_viewer_app_clear_hotkeys(app);
|
virt_viewer_app_clear_hotkeys(app);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
gchar **hotkey_names = virt_viewer_app_get_hotkey_names();
|
||||||
gchar *val;
|
gchar *val;
|
||||||
static const struct {
|
|
||||||
const char *prop;
|
|
||||||
const char *action_name;
|
|
||||||
} accels[] = {
|
|
||||||
{ "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" },
|
|
||||||
{ "usb-device-reset", "win.usb-device-reset" },
|
|
||||||
};
|
|
||||||
int i;
|
int i;
|
||||||
|
for (i = 0; i < g_strv_length(hotkey_names); i++) {
|
||||||
for (i = 0; i < G_N_ELEMENTS(accels); i++) {
|
if (!virt_viewer_file_is_set(self, hotkey_names[i]))
|
||||||
if (!virt_viewer_file_is_set(self, accels[i].prop))
|
|
||||||
continue;
|
continue;
|
||||||
g_object_get(self, accels[i].prop, &val, NULL);
|
g_object_get(self, hotkey_names[i], &val, NULL);
|
||||||
spice_hotkey_set_accel(app, accels[i].action_name, val);
|
virt_viewer_app_set_hotkey(app, hotkey_names[i], val);
|
||||||
g_free(val);
|
g_free(val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,19 +89,19 @@ test_hotkeys_bad(void)
|
|||||||
{
|
{
|
||||||
"no_value",
|
"no_value",
|
||||||
G_LOG_LEVEL_WARNING,
|
G_LOG_LEVEL_WARNING,
|
||||||
"missing value for key 'no_value'"
|
"Missing value for hotkey 'no_value'"
|
||||||
},{
|
},{
|
||||||
"smartcard-insert=",
|
"smartcard-insert=",
|
||||||
G_LOG_LEVEL_WARNING,
|
G_LOG_LEVEL_WARNING,
|
||||||
"missing value for key 'smartcard-insert'"
|
"Missing value for hotkey 'smartcard-insert'"
|
||||||
},{
|
},{
|
||||||
"toggle-fullscreen=A,unknown_command=B",
|
"toggle-fullscreen=A,unknown_command=B",
|
||||||
G_LOG_LEVEL_WARNING,
|
G_LOG_LEVEL_WARNING,
|
||||||
"Unknown hotkey command unknown_command"
|
"Unknown hotkey name unknown_command"
|
||||||
},{
|
},{
|
||||||
"secure-attention=value",
|
"secure-attention=value",
|
||||||
G_LOG_LEVEL_WARNING,
|
G_LOG_LEVEL_WARNING,
|
||||||
"Invalid value 'value' for key 'secure-attention'"
|
"Invalid hotkey 'value' for 'secure-attention'"
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user