Codebase list virt-viewer / 0a99760
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> Paul Donohue authored 3 years ago Daniel P. Berrangé committed 2 years ago
4 changed file(s) with 94 addition(s) and 107 deletion(s). Raw diff Collapse all Expand all
24282428 .change_state = virt_viewer_app_action_auto_resize },
24292429 };
24302430
2431 struct VirtViewerActionAccels {
2431 static const struct {
2432 const char *name;
24322433 const char *action;
2433 const char *accels[3];
2434 const gchar *default_accels[3];
2435 } hotkey_defaults[] = {
2436 { "toggle-fullscreen", "win.fullscreen", {"F11", NULL, NULL} },
2437 { "zoom-in", "win.zoom-in", { "<Ctrl>plus", "<Ctrl>KP_Add", NULL } },
2438 { "zoom-out", "win.zoom-out", { "<Ctrl>minus", "<Ctrl>KP_Subtract", NULL } },
2439 { "zoom-reset", "win.zoom-reset", { "<Ctrl>0", "<Ctrl>KP_0", NULL } },
2440 { "release-cursor", "win.release-cursor", {"<Shift>F12", NULL, NULL} },
2441 { "smartcard-insert", "app.smartcard-insert", {"<Shift>F8", NULL, NULL} },
2442 { "smartcard-remove", "app.smartcard-remove", {"<Shift>F9", NULL, NULL} },
2443 { "secure-attention", "win.secure-attention", {"<Ctrl><Alt>End", NULL, NULL} },
2444 { "usb-device-reset", "win.usb-device-reset", {"<Ctrl><Shift>r", NULL, NULL} },
24342445 };
24352446
2436 static const struct VirtViewerActionAccels action_accels[] = {
2437 { "win.fullscreen", {"F11", NULL, NULL} },
2438 { "win.zoom-in", { "<Ctrl>plus", "<Ctrl>KP_Add", NULL } },
2439 { "win.zoom-out", { "<Ctrl>minus", "<Ctrl>KP_Subtract", NULL } },
2440 { "win.zoom-reset", { "<Ctrl>0", "<Ctrl>KP_0", NULL } },
2441 { "win.release-cursor", {"<Shift>F12", NULL, NULL} },
2442 { "app.smartcard-insert", {"<Shift>F8", NULL, NULL} },
2443 { "app.smartcard-remove", {"<Shift>F9", NULL, NULL} },
2444 { "win.secure-attention", {"<Ctrl><Alt>End", NULL, NULL} },
2445 { "win.usb-device-reset", {"<Ctrl><Shift>r", NULL, NULL} },
2446 };
2447 static gchar **hotkey_names;
24472448
24482449 static void
24492450 virt_viewer_app_on_application_startup(GApplication *app)
24672468
24682469 priv->resource = virt_viewer_get_resource();
24692470
2470 for (i = 0 ; i < G_N_ELEMENTS(action_accels); i++) {
2471 gtk_application_set_accels_for_action(GTK_APPLICATION(app),
2472 action_accels[i].action,
2473 action_accels[i].accels);
2474 }
2475
24762471 virt_viewer_app_set_debug(opt_debug);
24772472 virt_viewer_app_set_fullscreen(self, opt_fullscreen);
24782473
24822477 priv->quit_on_disconnect = opt_kiosk ? opt_kiosk_quit : TRUE;
24832478
24842479 priv->main_window = virt_viewer_app_window_new(self,
2485 virt_viewer_app_get_first_monitor(self));
2480 virt_viewer_app_get_first_monitor(self));
24862481 priv->main_notebook = GTK_WIDGET(virt_viewer_window_get_notebook(priv->main_window));
24872482 priv->initial_display_map = virt_viewer_app_get_monitor_mapping_for_section(self, "fallback");
24882483
24892484 virt_viewer_app_set_kiosk(self, opt_kiosk);
2485
2486 hotkey_names = g_new(gchar*, G_N_ELEMENTS(hotkey_defaults) + 1);
2487 for (i = 0 ; i < G_N_ELEMENTS(hotkey_defaults); i++) {
2488 hotkey_names[i] = g_strdup(hotkey_defaults[i].name);
2489 gtk_application_set_accels_for_action(GTK_APPLICATION(app),
2490 hotkey_defaults[i].action,
2491 hotkey_defaults[i].default_accels);
2492 }
2493 hotkey_names[i] = NULL;
2494
24902495 virt_viewer_app_set_hotkeys(self, opt_hotkeys);
24912496
24922497 if (opt_zoom < MIN_ZOOM_LEVEL || opt_zoom > MAX_ZOOM_LEVEL) {
28152820 g_object_notify(G_OBJECT(self), "enable-accel");
28162821 }
28172822
2823 gchar**
2824 virt_viewer_app_get_hotkey_names(void)
2825 {
2826 return hotkey_names;
2827 }
2828
28182829 void
28192830 virt_viewer_app_clear_hotkeys(VirtViewerApp *self)
28202831 {
28212832 gint i;
28222833 const gchar *no_accels[] = { NULL };
28232834
2824 for (i = 0 ; i < G_N_ELEMENTS(action_accels); i++) {
2835 for (i = 0 ; i < G_N_ELEMENTS(hotkey_defaults); i++) {
28252836 gtk_application_set_accels_for_action(GTK_APPLICATION(self),
2826 action_accels[i].action,
2837 hotkey_defaults[i].action,
28272838 no_accels);
28282839 }
2840 }
2841
2842 void
2843 virt_viewer_app_set_hotkey(VirtViewerApp *self, const gchar *hotkey_name,
2844 const gchar *hotkey)
2845 {
2846 g_return_if_fail(VIRT_VIEWER_IS_APP(self));
2847
2848 const gchar *action = NULL;
2849 int i;
2850 for (i = 0; i < G_N_ELEMENTS(hotkey_defaults); i++) {
2851 if (g_str_equal(hotkey_name, hotkey_defaults[i].name)) {
2852 action = hotkey_defaults[i].action;
2853 break;
2854 }
2855 }
2856 if (action == NULL) {
2857 g_warning("Unknown hotkey name %s", hotkey_name);
2858 return;
2859 }
2860
2861 gchar *accel = spice_hotkey_to_gtk_accelerator(hotkey);
2862 const gchar *accels[] = { accel, NULL };
2863 guint accel_key;
2864 GdkModifierType accel_mods;
2865 /*
2866 * First try the spice translated accel.
2867 * Works for basic modifiers and single letters/numbers
2868 * where forced uppercasing matches GTK key names
2869 */
2870 gtk_accelerator_parse(accels[0], &accel_key, &accel_mods);
2871 if (accel_key == 0 && accel_mods == 0) {
2872 /* Fallback to native GTK accels to cope with
2873 * case sensitive accels
2874 */
2875 accels[0] = hotkey;
2876 gtk_accelerator_parse(accels[0], &accel_key, &accel_mods);
2877 }
2878 if (accel_key == 0 && accel_mods == 0) {
2879 g_warning("Invalid hotkey '%s' for '%s'", hotkey, hotkey_name);
2880 g_free(accel);
2881 return;
2882 }
2883
2884 gtk_application_set_accels_for_action(GTK_APPLICATION(self), action, accels);
2885 g_free(accel);
28292886 }
28302887
28312888 void
28492906 virt_viewer_app_clear_hotkeys(self);
28502907
28512908 for (hotkey = hotkeys; *hotkey != NULL; hotkey++) {
2852 gchar *key = strstr(*hotkey, "=");
2853 const gchar *value = (key == NULL) ? NULL : (*key = '\0', key + 1);
2909 gchar *eq = strstr(*hotkey, "=");
2910 const gchar *value = (eq == NULL) ? NULL : (*eq = '\0', eq + 1);
28542911 if (value == NULL || *value == '\0') {
2855 g_warning("missing value for key '%s'", *hotkey);
2912 g_warning("Missing value for hotkey '%s'", *hotkey);
28562913 continue;
28572914 }
28582915
2859 gchar *accel = spice_hotkey_to_gtk_accelerator(value);
2860 guint accel_key;
2861 GdkModifierType accel_mods;
2862 const gchar *accels[] = { accel, NULL };
2863
2864 /*
2865 * First try the spice translated accel.
2866 * Works for basic modifiers and single letters/numbers
2867 * where forced uppercasing matches GTK key names
2868 */
2869 gtk_accelerator_parse(accels[0], &accel_key, &accel_mods);
2870
2871 if (accel_key == 0 && accel_mods == 0) {
2872 /* Fallback to native GTK accels to cope with
2873 * case sensitive accels
2874 */
2875 accels[0] = value;
2876 gtk_accelerator_parse(accels[0], &accel_key, &accel_mods);
2877 }
2878
2879 if (accel_key == 0 && accel_mods == 0) {
2880 g_warning("Invalid value '%s' for key '%s'", value, *hotkey);
2881 g_free(accel);
2882 continue;
2883 }
2884
2885 if (g_str_equal(*hotkey, "toggle-fullscreen")) {
2886 gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.fullscreen", accels);
2887 } else if (g_str_equal(*hotkey, "release-cursor")) {
2888 gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.release-cursor", accels);
2889 } else if (g_str_equal(*hotkey, "zoom-reset")) {
2890 gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.zoom-reset", accels);
2891 } else if (g_str_equal(*hotkey, "zoom-out")) {
2892 gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.zoom-out", accels);
2893 } else if (g_str_equal(*hotkey, "zoom-in")) {
2894 gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.zoom-in", accels);
2895 } else if (g_str_equal(*hotkey, "secure-attention")) {
2896 gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.secure-attention", accels);
2897 } else if (g_str_equal(*hotkey, "smartcard-insert")) {
2898 gtk_application_set_accels_for_action(GTK_APPLICATION(self), "app.smartcard-insert", accels);
2899 } else if (g_str_equal(*hotkey, "smartcard-remove")) {
2900 gtk_application_set_accels_for_action(GTK_APPLICATION(self), "app.smartcard-remove", accels);
2901 } else if (g_str_equal(*hotkey, "usb-device-reset")) {
2902 gtk_application_set_accels_for_action(GTK_APPLICATION(self), "win.usb-device-reset", accels);
2903 } else {
2904 g_warning("Unknown hotkey command %s", *hotkey);
2905 }
2906 g_free(accel);
2916 virt_viewer_app_set_hotkey(self, *hotkey, value);
29072917 }
29082918 g_strfreev(hotkeys);
29092919
7171 gboolean virt_viewer_app_initial_connect(VirtViewerApp *self, GError **error);
7272 gboolean virt_viewer_app_get_direct(VirtViewerApp *self);
7373 void virt_viewer_app_set_direct(VirtViewerApp *self, gboolean direct);
74 char** virt_viewer_app_get_hotkey_names(void);
75 void virt_viewer_app_set_hotkey(VirtViewerApp *self, const gchar *hotkey_name, const gchar *hotkey);
7476 void virt_viewer_app_set_hotkeys(VirtViewerApp *self, const gchar *hotkeys);
7577 void virt_viewer_app_set_attach(VirtViewerApp *self, gboolean attach);
7678 gboolean virt_viewer_app_get_attach(VirtViewerApp *self);
882882 g_object_notify(G_OBJECT(self), "ovirt-admin");
883883 }
884884
885 static void
886 spice_hotkey_set_accel(VirtViewerApp *app, const gchar *action_name, const gchar *key)
887 {
888 gchar *accel = spice_hotkey_to_gtk_accelerator(key);
889 const gchar *accels[] = { accel, NULL };
890
891 gtk_application_set_accels_for_action(GTK_APPLICATION(app), action_name, accels);
892
893 g_free(accel);
894 }
895
896885 static gboolean
897886 virt_viewer_file_check_min_version(VirtViewerFile *self, GError **error)
898887 {
968957 virt_viewer_app_clear_hotkeys(app);
969958
970959 {
960 gchar **hotkey_names = virt_viewer_app_get_hotkey_names();
971961 gchar *val;
972 static const struct {
973 const char *prop;
974 const char *action_name;
975 } accels[] = {
976 { "release-cursor", "win.release-cursor" },
977 { "toggle-fullscreen", "win.fullscreen" },
978 { "zoom-in", "win.zoom-in" },
979 { "zoom-out", "win.zoom-out" },
980 { "zoom-reset", "win.zoom-reset" },
981 { "smartcard-insert", "app.smartcard-insert" },
982 { "smartcard-remove", "app.smartcard-remove" },
983 { "secure-attention", "win.secure-attention" },
984 { "usb-device-reset", "win.usb-device-reset" },
985 };
986962 int i;
987
988 for (i = 0; i < G_N_ELEMENTS(accels); i++) {
989 if (!virt_viewer_file_is_set(self, accels[i].prop))
963 for (i = 0; i < g_strv_length(hotkey_names); i++) {
964 if (!virt_viewer_file_is_set(self, hotkey_names[i]))
990965 continue;
991 g_object_get(self, accels[i].prop, &val, NULL);
992 spice_hotkey_set_accel(app, accels[i].action_name, val);
966 g_object_get(self, hotkey_names[i], &val, NULL);
967 virt_viewer_app_set_hotkey(app, hotkey_names[i], val);
993968 g_free(val);
994969 }
995970 }
8888 {
8989 "no_value",
9090 G_LOG_LEVEL_WARNING,
91 "missing value for key 'no_value'"
91 "Missing value for hotkey 'no_value'"
9292 },{
9393 "smartcard-insert=",
9494 G_LOG_LEVEL_WARNING,
95 "missing value for key 'smartcard-insert'"
95 "Missing value for hotkey 'smartcard-insert'"
9696 },{
9797 "toggle-fullscreen=A,unknown_command=B",
9898 G_LOG_LEVEL_WARNING,
99 "Unknown hotkey command unknown_command"
99 "Unknown hotkey name unknown_command"
100100 },{
101101 "secure-attention=value",
102102 G_LOG_LEVEL_WARNING,
103 "Invalid value 'value' for key 'secure-attention'"
103 "Invalid hotkey 'value' for 'secure-attention'"
104104 },
105105 };
106106