diff options
author | Alberts Muktupāvels <alberts.muktupavels@gmail.com> | 2015-04-15 14:32:00 +0300 |
---|---|---|
committer | Alberts Muktupāvels <alberts.muktupavels@gmail.com> | 2015-04-29 14:53:43 +0300 |
commit | 179549b7cf464114bd155e787e96fc375e049386 (patch) | |
tree | 23de0f869023190b54039fb5a37a7dc758ce2948 | |
parent | 4864daabd8dfa9f3404c45f6917123ead895ac3f (diff) | |
download | metacity-179549b7cf464114bd155e787e96fc375e049386.tar.gz |
keybindings: store keybindings dynamically
Rather than defining keybindings in static arrays generated at compile
time, store them in a hash table initialized in meta_display_init_keys()
and filled in init_builtin_keybindings().
This is a prerequisite for allowing to add/remove keybindings at runtime.
https://bugzilla.gnome.org/show_bug.cgi?id=663428
Based on mutter, mostly on this commit by Florian:
https://git.gnome.org/browse/mutter/commit/?id=d42a2a3c2741b8b44b48f83eb79a82fb4fcd5bbd
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/core/keybindings.c | 859 | ||||
-rw-r--r-- | src/core/keybindings.h | 31 | ||||
-rw-r--r-- | src/core/prefs.c | 153 | ||||
-rw-r--r-- | src/include/all-keybindings.h | 233 | ||||
-rw-r--r-- | src/include/prefs.h | 74 | ||||
-rw-r--r-- | src/include/types.h | 2 |
7 files changed, 881 insertions, 474 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 9663990f..d1a112a6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -109,8 +109,7 @@ libmetacity_private_la_SOURCES= \ ui/theme-parser.h \ ui/theme.c \ ui/theme.h \ - ui/ui.c \ - include/all-keybindings.h + ui/ui.c libmetacity_private_la_LDFLAGS = -no-undefined -version-info 3:0:0 libmetacity_private_la_LIBADD = @METACITY_LIBS@ diff --git a/src/core/keybindings.c b/src/core/keybindings.c index f06a53c7..81b06493 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -45,24 +45,17 @@ #include <X11/XKBlib.h> #endif +#define SCHEMA_COMMON_KEYBINDINGS "org.gnome.desktop.wm.keybindings" + static gboolean all_bindings_disabled = FALSE; -typedef void (* MetaKeyHandlerFunc) (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding); - -/* Prototypes for handlers */ -#define keybind(name, handler, param, flags) \ -static void \ -handler (MetaDisplay *display,\ - MetaScreen *screen,\ - MetaWindow *window,\ - XEvent *event,\ - MetaKeyBinding *binding); -#include "all-keybindings.h" -#undef keybind +static gboolean add_builtin_keybinding (MetaDisplay *display, + const char *name, + const char *schema, + MetaKeyBindingFlags flags, + MetaKeyBindingAction action, + MetaKeyHandlerFunc handler, + int handler_arg); /* These can't be bound to anything, but they are used to handle * various other events. TODO: Possibly we should include them as event @@ -105,30 +98,18 @@ static gboolean process_workspace_switch_grab (MetaDisplay *display, static void regrab_key_bindings (MetaDisplay *display); -typedef struct -{ - const char *name; - MetaKeyHandlerFunc func; - gint data, flags; -} MetaKeyHandler; +static GHashTable *key_handlers; -struct _MetaKeyBinding +#define HANDLER(name) g_hash_table_lookup (key_handlers, (name)) + +static void +key_handler_free (MetaKeyHandler *handler) { - const char *name; - KeySym keysym; - KeyCode keycode; - unsigned int mask; - MetaVirtualModifier modifiers; - const MetaKeyHandler *handler; -}; - -#define keybind(name, handler, param, flags) \ - { #name, handler, param, flags }, -static const MetaKeyHandler key_handlers[] = { -#include "all-keybindings.h" - { NULL, NULL, 0, 0 } -}; -#undef keybind + g_free (handler->name); + if (handler->user_data_free_func && handler->user_data) + handler->user_data_free_func (handler->user_data); + g_free (handler); +} static void reload_keymap (MetaDisplay *display) @@ -343,19 +324,18 @@ reload_modifiers (MetaDisplay *display) } } - static int -count_bindings (const MetaKeyPref *prefs, - int n_prefs) +count_bindings (GList *prefs) { - int i; + GList *p; int count; count = 0; - i = 0; - while (i < n_prefs) + p = prefs; + while (p) { - GSList *tmp = prefs[i].bindings; + MetaKeyPref *pref = (MetaKeyPref*) p->data; + GSList *tmp = pref->bindings; while (tmp) { @@ -365,58 +345,39 @@ count_bindings (const MetaKeyPref *prefs, { count += 1; - if (prefs[i].add_shift && - (combo->modifiers & META_VIRTUAL_SHIFT_MASK) == 0) + if (pref->add_shift && (combo->modifiers & META_VIRTUAL_SHIFT_MASK) == 0) count += 1; } tmp = tmp->next; } - ++i; + p = p->next; } return count; } -/* FIXME: replace this with a temporary hash */ -static const MetaKeyHandler* -find_handler (const MetaKeyHandler *handlers, - const char *name) -{ - const MetaKeyHandler *iter; - - iter = handlers; - while (iter->name) - { - if (strcmp (iter->name, name) == 0) - return iter; - - ++iter; - } - - return NULL; -} - static void -rebuild_binding_table (MetaDisplay *display, - MetaKeyBinding **bindings_p, - int *n_bindings_p, - const MetaKeyPref *prefs, - int n_prefs) +rebuild_binding_table (MetaDisplay *display, + MetaKeyBinding **bindings_p, + int *n_bindings_p, + GList *prefs) { + GList *p; int n_bindings; - int src, dest; + int i; - n_bindings = count_bindings (prefs, n_prefs); + n_bindings = count_bindings (prefs); g_free (*bindings_p); *bindings_p = g_new0 (MetaKeyBinding, n_bindings); - src = 0; - dest = 0; - while (src < n_prefs) + i = 0; + p = prefs; + while (p) { - GSList *tmp = prefs[src].bindings; + MetaKeyPref *pref = (MetaKeyPref*) p->data; + GSList *tmp = pref->bindings; while (tmp) { @@ -424,45 +385,43 @@ rebuild_binding_table (MetaDisplay *display, if (combo && (combo->keysym != None || combo->keycode != 0)) { - const MetaKeyHandler *handler = find_handler (key_handlers, prefs[src].name); + MetaKeyHandler *handler = HANDLER (pref->name); - (*bindings_p)[dest].name = prefs[src].name; - (*bindings_p)[dest].handler = handler; - (*bindings_p)[dest].keysym = combo->keysym; - (*bindings_p)[dest].keycode = combo->keycode; - (*bindings_p)[dest].modifiers = combo->modifiers; - (*bindings_p)[dest].mask = 0; + (*bindings_p)[i].name = pref->name; + (*bindings_p)[i].handler = handler; + (*bindings_p)[i].keysym = combo->keysym; + (*bindings_p)[i].keycode = combo->keycode; + (*bindings_p)[i].modifiers = combo->modifiers; + (*bindings_p)[i].mask = 0; - ++dest; + ++i; - if (prefs[src].add_shift && - (combo->modifiers & META_VIRTUAL_SHIFT_MASK) == 0) + if (pref->add_shift && (combo->modifiers & META_VIRTUAL_SHIFT_MASK) == 0) { meta_topic (META_DEBUG_KEYBINDINGS, "Binding %s also needs Shift grabbed\n", - prefs[src].name); + pref->name); - (*bindings_p)[dest].name = prefs[src].name; - (*bindings_p)[dest].handler = handler; - (*bindings_p)[dest].keysym = combo->keysym; - (*bindings_p)[dest].keycode = combo->keycode; - (*bindings_p)[dest].modifiers = combo->modifiers | - META_VIRTUAL_SHIFT_MASK; - (*bindings_p)[dest].mask = 0; + (*bindings_p)[i].name = pref->name; + (*bindings_p)[i].handler = handler; + (*bindings_p)[i].keysym = combo->keysym; + (*bindings_p)[i].keycode = combo->keycode; + (*bindings_p)[i].modifiers = combo->modifiers | META_VIRTUAL_SHIFT_MASK; + (*bindings_p)[i].mask = 0; - ++dest; + ++i; } } tmp = tmp->next; } - ++src; + p = p->next; } - g_assert (dest == n_bindings); + g_assert (i == n_bindings); - *n_bindings_p = dest; + *n_bindings_p = i; meta_topic (META_DEBUG_KEYBINDINGS, " %d bindings in table\n", @@ -472,17 +431,17 @@ rebuild_binding_table (MetaDisplay *display, static void rebuild_key_binding_table (MetaDisplay *display) { - const MetaKeyPref *prefs; - int n_prefs; + GList *prefs; meta_topic (META_DEBUG_KEYBINDINGS, "Rebuilding key binding table from preferences\n"); - meta_prefs_get_key_bindings (&prefs, &n_prefs); + prefs = meta_prefs_get_keybindings (); rebuild_binding_table (display, &display->key_bindings, &display->n_key_bindings, - prefs, n_prefs); + prefs); + g_list_free (prefs); } static void @@ -520,6 +479,32 @@ regrab_key_bindings (MetaDisplay *display) g_slist_free (windows); } +static gboolean +add_builtin_keybinding (MetaDisplay *display, + const char *name, + const char *schema, + MetaKeyBindingFlags flags, + MetaKeyBindingAction action, + MetaKeyHandlerFunc func, + int data) +{ + MetaKeyHandler *handler; + + if (!meta_prefs_add_keybinding (name, schema, action, flags)) + return FALSE; + + handler = g_new0 (MetaKeyHandler, 1); + handler->name = g_strdup (name); + handler->func = func; + handler->default_func = func; + handler->data = data; + handler->flags = flags; + + g_hash_table_insert (key_handlers, g_strdup (name), handler); + + return TRUE; +} + static MetaKeyBindingAction display_get_keybinding_action (MetaDisplay *display, unsigned int keysym, @@ -619,55 +604,6 @@ bindings_changed_callback (MetaPreference pref, } } - -void -meta_display_init_keys (MetaDisplay *display) -{ - /* Keybindings */ - display->keymap = NULL; - display->keysyms_per_keycode = 0; - display->modmap = NULL; - display->min_keycode = 0; - display->max_keycode = 0; - display->ignored_modifier_mask = 0; - display->num_lock_mask = 0; - display->scroll_lock_mask = 0; - display->hyper_mask = 0; - display->super_mask = 0; - display->meta_mask = 0; - display->key_bindings = NULL; - display->n_key_bindings = 0; - - XDisplayKeycodes (display->xdisplay, - &display->min_keycode, - &display->max_keycode); - - meta_topic (META_DEBUG_KEYBINDINGS, - "Display has keycode range %d to %d\n", - display->min_keycode, - display->max_keycode); - - reload_keymap (display); - reload_modmap (display); - - rebuild_key_binding_table (display); - - reload_keycodes (display); - reload_modifiers (display); - - /* Keys are actually grabbed in meta_screen_grab_keys() */ - - meta_prefs_add_listener (bindings_changed_callback, display); - -#ifdef HAVE_XKB - /* meta_display_init_keys() should have already called XkbQueryExtension() */ - if (display->xkb_base_event_type != -1) - XkbSelectEvents (display->xdisplay, XkbUseCoreKbd, - XkbNewKeyboardNotifyMask | XkbMapNotifyMask, - XkbNewKeyboardNotifyMask | XkbMapNotifyMask); -#endif -} - void meta_display_shutdown_keys (MetaDisplay *display) { @@ -792,7 +728,7 @@ grab_keys (MetaKeyBinding *bindings, while (i < n_bindings) { if (!!binding_per_window == - !!(bindings[i].handler->flags & BINDING_PER_WINDOW) && + !!(bindings[i].handler->flags & META_KEY_BINDING_PER_WINDOW) && bindings[i].keycode != 0) { meta_grab_key (display, xwindow, @@ -1264,7 +1200,7 @@ process_event (MetaKeyBinding *bindings, { const MetaKeyHandler *handler = bindings[i].handler; - if ((!on_window && handler->flags & BINDING_PER_WINDOW) || + if ((!on_window && handler->flags & META_KEY_BINDING_PER_WINDOW) || event->type != KeyPress || bindings[i].keycode != event->xkey.keycode || ((event->xkey.state & 0xff & ~(display->ignored_modifier_mask)) != @@ -1274,7 +1210,7 @@ process_event (MetaKeyBinding *bindings, /* * window must be non-NULL for on_window to be true, * and so also window must be non-NULL if we get here and - * this is a BINDING_PER_WINDOW binding. + * this is a META_KEY_BINDING_PER_WINDOW binding. */ meta_topic (META_DEBUG_KEYBINDINGS, @@ -1296,9 +1232,10 @@ process_event (MetaKeyBinding *bindings, display->allow_terminal_deactivation = TRUE; (* handler->func) (display, screen, - bindings[i].handler->flags & BINDING_PER_WINDOW? window: NULL, + bindings[i].handler->flags & META_KEY_BINDING_PER_WINDOW ? window: NULL, event, - &bindings[i]); + &bindings[i], + NULL); return TRUE; } @@ -2898,7 +2835,7 @@ handle_switch (MetaDisplay *display, XEvent *event, MetaKeyBinding *binding) { - gint backwards = binding->handler->flags & BINDING_IS_REVERSED; + gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0; do_choose_window (display, screen, event_window, event, binding, backwards, TRUE); @@ -2911,7 +2848,7 @@ handle_cycle (MetaDisplay *display, XEvent *event, MetaKeyBinding *binding) { - gint backwards = binding->handler->flags & BINDING_IS_REVERSED; + gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0; do_choose_window (display, screen, event_window, event, binding, backwards, FALSE); @@ -3272,3 +3209,605 @@ meta_set_keybindings_disabled (MetaDisplay *display, meta_topic (META_DEBUG_KEYBINDINGS, "Keybindings %s\n", all_bindings_disabled ? "disabled" : "enabled"); } + +static void +init_builtin_key_bindings (MetaDisplay *display) +{ +#define REVERSES_AND_REVERSED (META_KEY_BINDING_REVERSES | \ + META_KEY_BINDING_IS_REVERSED) + + add_builtin_keybinding (display, + "switch-to-workspace-1", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_WORKSPACE_1, + (MetaKeyHandlerFunc) handle_switch_to_workspace, 0); + add_builtin_keybinding (display, + "switch-to-workspace-2", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_WORKSPACE_2, + (MetaKeyHandlerFunc) handle_switch_to_workspace, 1); + add_builtin_keybinding (display, + "switch-to-workspace-3", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_WORKSPACE_3, + (MetaKeyHandlerFunc) handle_switch_to_workspace, 2); + add_builtin_keybinding (display, + "switch-to-workspace-4", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_WORKSPACE_4, + (MetaKeyHandlerFunc) handle_switch_to_workspace, 3); + add_builtin_keybinding (display, + "switch-to-workspace-5", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_WORKSPACE_5, + (MetaKeyHandlerFunc) handle_switch_to_workspace, 4); + add_builtin_keybinding (display, + "switch-to-workspace-6", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_WORKSPACE_6, + (MetaKeyHandlerFunc) handle_switch_to_workspace, 5); + add_builtin_keybinding (display, + "switch-to-workspace-7", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_WORKSPACE_7, + (MetaKeyHandlerFunc) handle_switch_to_workspace, 6); + add_builtin_keybinding (display, + "switch-to-workspace-8", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_WORKSPACE_8, + (MetaKeyHandlerFunc) handle_switch_to_workspace, 7); + add_builtin_keybinding (display, + "switch-to-workspace-9", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_WORKSPACE_9, + (MetaKeyHandlerFunc) handle_switch_to_workspace, 8); + add_builtin_keybinding (display, + "switch-to-workspace-10", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_WORKSPACE_10, + (MetaKeyHandlerFunc) handle_switch_to_workspace, 9); + add_builtin_keybinding (display, + "switch-to-workspace-11", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_WORKSPACE_11, + (MetaKeyHandlerFunc) handle_switch_to_workspace, 10); + add_builtin_keybinding (display, + "switch-to-workspace-12", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_WORKSPACE_12, + (MetaKeyHandlerFunc) handle_switch_to_workspace, 11); + + add_builtin_keybinding (display, + "switch-to-workspace-left", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_WORKSPACE_LEFT, + (MetaKeyHandlerFunc) handle_switch_to_workspace, META_MOTION_LEFT); + + add_builtin_keybinding (display, + "switch-to-workspace-right", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_WORKSPACE_RIGHT, + (MetaKeyHandlerFunc) handle_switch_to_workspace, META_MOTION_RIGHT); + + add_builtin_keybinding (display, + "switch-to-workspace-up", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_WORKSPACE_UP, + (MetaKeyHandlerFunc) handle_switch_to_workspace, META_MOTION_UP); + + add_builtin_keybinding (display, + "switch-to-workspace-down", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_WORKSPACE_DOWN, + (MetaKeyHandlerFunc) handle_switch_to_workspace, META_MOTION_DOWN); + + + /* The ones which have inverses. These can't be bound to any keystroke + * containing Shift because Shift will invert their "backward" state. + * + * TODO: "NORMAL" and "DOCKS" should be renamed to the same name as their + * action, for obviousness. + * + * TODO: handle_switch and handle_cycle should probably really be the + * same function checking a bit in the parameter for difference. + */ + + add_builtin_keybinding (display, + "switch-applications", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_REVERSES, + META_KEYBINDING_ACTION_SWITCH_APPLICATIONS, + (MetaKeyHandlerFunc) handle_switch, META_TAB_LIST_NORMAL); + + add_builtin_keybinding (display, + "switch-applications-backward", + SCHEMA_COMMON_KEYBINDINGS, + REVERSES_AND_REVERSED, + META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD, + (MetaKeyHandlerFunc) handle_switch, META_TAB_LIST_NORMAL); + + add_builtin_keybinding (display, + "switch-group", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_REVERSES, + META_KEYBINDING_ACTION_SWITCH_GROUP, + (MetaKeyHandlerFunc) handle_switch, META_TAB_LIST_GROUP); + + add_builtin_keybinding (display, + "switch-group-backward", + SCHEMA_COMMON_KEYBINDINGS, + REVERSES_AND_REVERSED, + META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD, + (MetaKeyHandlerFunc) handle_switch, META_TAB_LIST_GROUP); + + add_builtin_keybinding (display, + "switch-windows", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_REVERSES, + META_KEYBINDING_ACTION_SWITCH_WINDOWS, + (MetaKeyHandlerFunc) handle_switch, META_TAB_LIST_NORMAL); + + add_builtin_keybinding (display, + "switch-windows-backward", + SCHEMA_COMMON_KEYBINDINGS, + REVERSES_AND_REVERSED, + META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD, + (MetaKeyHandlerFunc) handle_switch, META_TAB_LIST_NORMAL); + + add_builtin_keybinding (display, + "switch-panels", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_REVERSES, + META_KEYBINDING_ACTION_SWITCH_PANELS, + (MetaKeyHandlerFunc) handle_switch, META_TAB_LIST_DOCKS); + + add_builtin_keybinding (display, + "switch-panels-backward", + SCHEMA_COMMON_KEYBINDINGS, + REVERSES_AND_REVERSED, + META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD, + (MetaKeyHandlerFunc) handle_switch, META_TAB_LIST_DOCKS); + + add_builtin_keybinding (display, + "cycle-group", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_REVERSES, + META_KEYBINDING_ACTION_CYCLE_GROUP, + (MetaKeyHandlerFunc) handle_cycle, META_TAB_LIST_GROUP); + + add_builtin_keybinding (display, + "cycle-group-backward", + SCHEMA_COMMON_KEYBINDINGS, + REVERSES_AND_REVERSED, + META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD, + (MetaKeyHandlerFunc) handle_cycle, META_TAB_LIST_GROUP); + + add_builtin_keybinding (display, + "cycle-windows", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_REVERSES, + META_KEYBINDING_ACTION_CYCLE_WINDOWS, + (MetaKeyHandlerFunc) handle_cycle, META_TAB_LIST_NORMAL); + + add_builtin_keybinding (display, + "cycle-windows-backward", + SCHEMA_COMMON_KEYBINDINGS, + REVERSES_AND_REVERSED, + META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD, + (MetaKeyHandlerFunc) handle_cycle, META_TAB_LIST_NORMAL); + + add_builtin_keybinding (display, + "cycle-panels", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_REVERSES, + META_KEYBINDING_ACTION_CYCLE_PANELS, + (MetaKeyHandlerFunc) handle_cycle, META_TAB_LIST_DOCKS); + + add_builtin_keybinding (display, + "cycle-panels-backward", + SCHEMA_COMMON_KEYBINDINGS, + REVERSES_AND_REVERSED, + META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD, + (MetaKeyHandlerFunc) handle_cycle, META_TAB_LIST_DOCKS); + + +/***********************************/ + + add_builtin_keybinding (display, + "show-desktop", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_SHOW_DESKTOP, + (MetaKeyHandlerFunc) handle_show_desktop, 0); + + add_builtin_keybinding (display, + "panel-main-menu", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_PANEL_MAIN_MENU, + (MetaKeyHandlerFunc) handle_panel, META_KEYBINDING_ACTION_PANEL_MAIN_MENU); + + add_builtin_keybinding (display, + "panel-run-dialog", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_PANEL_RUN_DIALOG, + (MetaKeyHandlerFunc) handle_panel, META_KEYBINDING_ACTION_PANEL_RUN_DIALOG); + + add_builtin_keybinding (display, + "set-spew-mark", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_SET_SPEW_MARK, + (MetaKeyHandlerFunc) handle_set_spew_mark, 0); + +#undef REVERSES_AND_REVERSED + +/************************ PER WINDOW BINDINGS ************************/ + +/* These take a window as an extra parameter; they have no effect + * if no window is active. + */ + + add_builtin_keybinding (display, + "activate-window-menu", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_ACTIVATE_WINDOW_MENU, + (MetaKeyHandlerFunc) handle_activate_window_menu, 0); + + add_builtin_keybinding (display, + "toggle-fullscreen", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_TOGGLE_FULLSCREEN, + (MetaKeyHandlerFunc) handle_toggle_fullscreen, 0); + + add_builtin_keybinding (display, + "toggle-maximized", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_TOGGLE_MAXIMIZED, + (MetaKeyHandlerFunc) handle_toggle_maximized, 0); + + add_builtin_keybinding (display, + "toggle-above", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_TOGGLE_ABOVE, + (MetaKeyHandlerFunc) handle_toggle_above, 0); + + add_builtin_keybinding (display, + "maximize", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MAXIMIZE, + (MetaKeyHandlerFunc) handle_maximize, 0); + + add_builtin_keybinding (display, + "unmaximize", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_UNMAXIMIZE, + (MetaKeyHandlerFunc) handle_unmaximize, 0); + + add_builtin_keybinding (display, + "toggle-shaded", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_TOGGLE_SHADED, + (MetaKeyHandlerFunc) handle_toggle_shaded, 0); + + add_builtin_keybinding (display, + "minimize", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MINIMIZE, + (MetaKeyHandlerFunc) handle_minimize, 0); + + add_builtin_keybinding (display, + "close", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_CLOSE, + (MetaKeyHandlerFunc) handle_close, 0); + + add_builtin_keybinding (display, + "begin-move", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_BEGIN_MOVE, + (MetaKeyHandlerFunc) handle_begin_move, 0); + + add_builtin_keybinding (display, + "begin-resize", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_BEGIN_RESIZE, + (MetaKeyHandlerFunc) handle_begin_resize, 0); + + add_builtin_keybinding (display, + "toggle-on-all-workspaces", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_TOGGLE_ON_ALL_WORKSPACES, + (MetaKeyHandlerFunc) handle_toggle_on_all_workspaces, 0); + + add_builtin_keybinding (display, + "move-to-workspace-1", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_1, + (MetaKeyHandlerFunc) handle_move_to_workspace, 0); + + add_builtin_keybinding (display, + "move-to-workspace-2", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_2, + (MetaKeyHandlerFunc) handle_move_to_workspace, 1); + + add_builtin_keybinding (display, + "move-to-workspace-3", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_3, + (MetaKeyHandlerFunc) handle_move_to_workspace, 2); + + add_builtin_keybinding (display, + "move-to-workspace-4", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_4, + (MetaKeyHandlerFunc) handle_move_to_workspace, 3); + + add_builtin_keybinding (display, + "move-to-workspace-5", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_5, + (MetaKeyHandlerFunc) handle_move_to_workspace, 4); + + add_builtin_keybinding (display, + "move-to-workspace-6", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_6, + (MetaKeyHandlerFunc) handle_move_to_workspace, 5); + + add_builtin_keybinding (display, + "move-to-workspace-7", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_7, + (MetaKeyHandlerFunc) handle_move_to_workspace, 6); + + add_builtin_keybinding (display, + "move-to-workspace-8", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_8, + (MetaKeyHandlerFunc) handle_move_to_workspace, 7); + + add_builtin_keybinding (display, + "move-to-workspace-9", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_9, + (MetaKeyHandlerFunc) handle_move_to_workspace, 8); + + add_builtin_keybinding (display, + "move-to-workspace-10", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_10, + (MetaKeyHandlerFunc) handle_move_to_workspace, 9); + + add_builtin_keybinding (display, + "move-to-workspace-11", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_11, + (MetaKeyHandlerFunc) handle_move_to_workspace, 10); + + add_builtin_keybinding (display, + "move-to-workspace-12", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_12, + (MetaKeyHandlerFunc) handle_move_to_workspace, 11); + + add_builtin_keybinding (display, + "move-to-workspace-left", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_LEFT, + (MetaKeyHandlerFunc) handle_move_to_workspace, META_MOTION_LEFT); + + add_builtin_keybinding (display, + "move-to-workspace-right", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_RIGHT, + (MetaKeyHandlerFunc) handle_move_to_workspace, META_MOTION_RIGHT); + + add_builtin_keybinding (display, + "move-to-workspace-up", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_UP, + (MetaKeyHandlerFunc) handle_move_to_workspace, META_MOTION_UP); + + add_builtin_keybinding (display, + "move-to-workspace-down", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_DOWN, + (MetaKeyHandlerFunc) handle_move_to_workspace, META_MOTION_DOWN); + + add_builtin_keybinding (display, + "raise-or-lower", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_RAISE_OR_LOWER, + (MetaKeyHandlerFunc) handle_raise_or_lower, 0); + + add_builtin_keybinding (display, + "raise", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_RAISE, + (MetaKeyHandlerFunc) handle_raise, 0); + + add_builtin_keybinding (display, + "lower", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_LOWER, + (MetaKeyHandlerFunc) handle_lower, 0); + + add_builtin_keybinding (display, + "maximize-vertically", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MAXIMIZE_VERTICALLY, + (MetaKeyHandlerFunc) handle_maximize_vertically, 0); + + add_builtin_keybinding (display, + "maximize-horizontally", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MAXIMIZE_HORIZONTALLY, + (MetaKeyHandlerFunc) handle_maximize_horizontally, 0); + + add_builtin_keybinding (display, + "move-to-corner-nw", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_CORNER_NW, + (MetaKeyHandlerFunc) handle_move_to_corner_nw, 0); + + add_builtin_keybinding (display, + "move-to-corner-ne", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_CORNER_NE, + (MetaKeyHandlerFunc) handle_move_to_corner_ne, 0); + + add_builtin_keybinding (display, + "move-to-corner-sw", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_CORNER_SW, + (MetaKeyHandlerFunc) handle_move_to_corner_sw, 0); + + add_builtin_keybinding (display, + "move-to-corner-se", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_CORNER_SE, + (MetaKeyHandlerFunc) handle_move_to_corner_se, 0); + + add_builtin_keybinding (display, + "move-to-side-n", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_SIDE_N, + (MetaKeyHandlerFunc) handle_move_to_side_n, 0); + + add_builtin_keybinding (display, + "move-to-side-s", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_SIDE_S, + (MetaKeyHandlerFunc) handle_move_to_side_s, 0); + + add_builtin_keybinding (display, + "move-to-side-e", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_SIDE_E, + (MetaKeyHandlerFunc) handle_move_to_side_e, 0); + + add_builtin_keybinding (display, + "move-to-side-w", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_SIDE_W, + (MetaKeyHandlerFunc) handle_move_to_side_w, 0); + + add_builtin_keybinding (display, + "move-to-center", + SCHEMA_COMMON_KEYBINDINGS, + META_KEY_BINDING_PER_WINDOW, + META_KEYBINDING_ACTION_MOVE_TO_CENTER, + (MetaKeyHandlerFunc) handle_move_to_center, 0); +} + +void +meta_display_init_keys (MetaDisplay *display) +{ + /* Keybindings */ + display->keymap = NULL; + display->keysyms_per_keycode = 0; + display->modmap = NULL; + display->min_keycode = 0; + display->max_keycode = 0; + display->ignored_modifier_mask = 0; + display->num_lock_mask = 0; + display->scroll_lock_mask = 0; + display->hyper_mask = 0; + display->super_mask = 0; + display->meta_mask = 0; + display->key_bindings = NULL; + display->n_key_bindings = 0; + + XDisplayKeycodes (display->xdisplay, + &display->min_keycode, + &display->max_keycode); + + meta_topic (META_DEBUG_KEYBINDINGS, + "Display has keycode range %d to %d\n", + display->min_keycode, + display->max_keycode); + + reload_keymap (display); + reload_modmap (display); + + key_handlers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, + (GDestroyNotify) key_handler_free); + init_builtin_key_bindings (display); + + rebuild_key_binding_table (display); + + reload_keycodes (display); + reload_modifiers (display); + + /* Keys are actually grabbed in meta_screen_grab_keys() */ + + meta_prefs_add_listener (bindings_changed_callback, display); + +#ifdef HAVE_XKB + /* meta_display_init_keys() should have already called XkbQueryExtension() */ + if (display->xkb_base_event_type != -1) + XkbSelectEvents (display->xdisplay, XkbUseCoreKbd, + XkbNewKeyboardNotifyMask | XkbMapNotifyMask, + XkbNewKeyboardNotifyMask | XkbMapNotifyMask); +#endif +} diff --git a/src/core/keybindings.h b/src/core/keybindings.h index d1078bde..5e38af54 100644 --- a/src/core/keybindings.h +++ b/src/core/keybindings.h @@ -29,6 +29,28 @@ #include "display-private.h" #include "window.h" +#include "prefs.h" + +struct _MetaKeyHandler +{ + char *name; + MetaKeyHandlerFunc func; + MetaKeyHandlerFunc default_func; + gint data; + gint flags; + gpointer user_data; + GDestroyNotify user_data_free_func; +}; + +struct _MetaKeyBinding +{ + const char *name; + KeySym keysym; + KeyCode keycode; + unsigned int mask; + MetaVirtualModifier modifiers; + MetaKeyHandler *handler; +}; void meta_display_init_keys (MetaDisplay *display); void meta_display_shutdown_keys (MetaDisplay *display); @@ -52,8 +74,9 @@ void meta_set_keybindings_disabled (MetaDisplay *display, void meta_display_process_mapping_event (MetaDisplay *display, XEvent *event); -#endif - - - +gboolean meta_prefs_add_keybinding (const char *name, + const char *schema, + MetaKeyBindingAction action, + MetaKeyBindingFlags flags); +#endif diff --git a/src/core/prefs.c b/src/core/prefs.c index e95249dd..bad04181 100644 --- a/src/core/prefs.c +++ b/src/core/prefs.c @@ -30,6 +30,7 @@ #include <gio/gio.h> #include <string.h> #include <stdlib.h> +#include "keybindings.h" /* If you add a key, it needs updating in init() and in the gsettings * notify listener and of course in the .schemas file. @@ -55,7 +56,6 @@ #define SCHEMA_GENERAL "org.gnome.desktop.wm.preferences" #define SCHEMA_METACITY "org.gnome.metacity" #define SCHEMA_INTERFACE "org.gnome.desktop.interface" -#define SCHEMA_BINDINGS "org.gnome.desktop.wm.keybindings" #define SETTINGS(s) g_hash_table_lookup (settings_schemas, (s)) @@ -791,15 +791,7 @@ meta_prefs_init (void) G_CALLBACK (settings_changed), NULL); g_hash_table_insert (settings_schemas, SCHEMA_INTERFACE, settings); - /* Bindings have a separate handler, since they are in separate schemas - * and work differently */ - settings = g_settings_new (SCHEMA_BINDINGS); - g_signal_connect (settings, "changed", G_CALLBACK (bindings_changed), NULL); - g_hash_table_insert (settings_schemas, SCHEMA_BINDINGS, settings); - - /* Pick up initial values. */ - handle_preference_init_enum (); handle_preference_init_bool (); handle_preference_init_string (); @@ -1449,29 +1441,24 @@ meta_prefs_set_num_workspaces (int n_workspaces) n_workspaces); } -#define keybind(name, handler, param, flags) \ - { #name, NULL, !!(flags & BINDING_REVERSES), !!(flags & BINDING_PER_WINDOW) }, -static MetaKeyPref key_bindings[] = { -#include "all-keybindings.h" - { NULL, NULL, FALSE } -}; -#undef keybind - +static GHashTable *key_bindings; static void -init_bindings (void) +meta_key_pref_free (MetaKeyPref *pref) { - int i; - gchar **strokes; + update_binding (pref, NULL); - for (i = 0; key_bindings[i].name; i++) - { - strokes = g_settings_get_strv (SETTINGS (SCHEMA_BINDINGS), - key_bindings[i].name); - update_key_binding (key_bindings[i].name, strokes); + g_free (pref->name); + g_free (pref->schema); - g_strfreev (strokes); - } + g_free (pref); +} + +static void +init_bindings (void) +{ + key_bindings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, + (GDestroyNotify) meta_key_pref_free); } static void @@ -1558,15 +1545,10 @@ static gboolean update_key_binding (const char *key, gchar **strokes) { - int i; - - i = 0; - while (key_bindings[i].name && - strcmp (key, key_bindings[i].name) != 0) - i++; + MetaKeyPref *pref = g_hash_table_lookup (key_bindings, key); - if (key_bindings[i].name) - return update_binding (&key_bindings[i], strokes); + if (pref) + return update_binding (pref, strokes); else return FALSE; } @@ -1703,13 +1685,56 @@ meta_prefs_get_visual_bell_type (void) return visual_bell_type; } -void -meta_prefs_get_key_bindings (const MetaKeyPref **bindings, - int *n_bindings) +gboolean +meta_prefs_add_keybinding (const char *name, + const char *schema, + MetaKeyBindingAction action, + MetaKeyBindingFlags flags) { + MetaKeyPref *pref; + GSettings *settings; + char **strokes; - *bindings = key_bindings; - *n_bindings = (int) G_N_ELEMENTS (key_bindings) - 1; + if (g_hash_table_lookup (key_bindings, name)) + { + meta_warning ("Trying to re-add keybinding \"%s\".\n", name); + return FALSE; + } + + settings = SETTINGS (schema); + if (settings == NULL) + { + settings = g_settings_new (schema); + g_signal_connect (settings, "changed", + G_CALLBACK (bindings_changed), NULL); + g_hash_table_insert (settings_schemas, g_strdup (schema), settings); + } + + pref = g_new0 (MetaKeyPref, 1); + pref->name = g_strdup (name); + pref->schema = g_strdup (schema); + pref->action = action; + pref->bindings = NULL; + pref->add_shift = (flags & META_KEY_BINDING_REVERSES) != 0; + pref->per_window = (flags & META_KEY_BINDING_PER_WINDOW) != 0; + + strokes = g_settings_get_strv (settings, name); + update_binding (pref, strokes); + g_strfreev (strokes); + + g_hash_table_insert (key_bindings, g_strdup (name), pref); + + return TRUE; +} + +/** + * meta_prefs_get_keybindings: (skip) + * Return: (element-type MetaKeyPref) (transfer container): + */ +GList * +meta_prefs_get_keybindings () +{ + return g_hash_table_get_values (key_bindings); } GDesktopTitlebarAction @@ -1769,18 +1794,9 @@ meta_prefs_get_edge_tiling () MetaKeyBindingAction meta_prefs_get_keybinding_action (const char *name) { - int i; + MetaKeyPref *pref = g_hash_table_lookup (key_bindings, name); - i = G_N_ELEMENTS (key_bindings) - 2; /* -2 for dummy entry at end */ - while (i >= 0) - { - if (strcmp (key_bindings[i].name, name) == 0) - return (MetaKeyBindingAction) i; - - --i; - } - - return META_KEYBINDING_ACTION_NONE; + return pref ? pref->action : META_KEYBINDING_ACTION_NONE; } /* This is used by the menu system to decide what key binding @@ -1792,36 +1808,29 @@ meta_prefs_get_window_binding (const char *name, unsigned int *keysym, MetaVirtualModifier *modifiers) { - int i; + MetaKeyPref *pref = g_hash_table_lookup (key_bindings, name); - i = G_N_ELEMENTS (key_bindings) - 2; /* -2 for dummy entry at end */ - while (i >= 0) + if (pref->per_window) { - if (key_bindings[i].per_window && - strcmp (key_bindings[i].name, name) == 0) + GSList *s = pref->bindings; + + while (s) { - GSList *s = key_bindings[i].bindings; + MetaKeyCombo *c = s->data; - while (s) + if (c->keysym != 0 || c->modifiers != 0) { - MetaKeyCombo *c = s->data; - - if (c->keysym!=0 || c->modifiers!=0) - { - *keysym = c->keysym; - *modifiers = c->modifiers; - return; - } - - s = s->next; + *keysym = c->keysym; + *modifiers = c->modifiers; + return; } - /* Not found; return the disabled value */ - *keysym = *modifiers = 0; - return; + s = s->next; } - --i; + /* Not found; return the disabled value */ + *keysym = *modifiers = 0; + return; } g_assert_not_reached (); diff --git a/src/include/all-keybindings.h b/src/include/all-keybindings.h deleted file mode 100644 index 0ff0f30f..00000000 --- a/src/include/all-keybindings.h +++ /dev/null @@ -1,233 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* - * Copyright (C) 2008 Thomas Thurman - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -/** - * A list of screen keybinding information. - * - * Each action which can have a keystroke bound to it is listed below. - * To use this file, define keybind() to be a seven-argument macro (you can - * throw any of the arguments you please away), include this file, - * and then undefine the macro again. - * - * (If you aren't familiar with this technique, sometimes called "x-macros", - * see DDJ of May 2001: <http://www.ddj.com/cpp/184401387>.) - * - * This makes it possible to keep all information about all the keybindings - * in the same place. The only exception is the code to run when an action - * is actually invoked; while we *could* have put that in this file, it would - * have made debugging ridiculously difficult. Instead, each action should - * have a corresponding static function named handle_<name>() in - * keybindings.c. - * - * The arguments to keybind() are: - * 1) the name of the binding; a bareword identifier - * (it's fine if it happens to clash with a C reserved word) - * 2) the name of the function which implements it. - * Clearly we could have guessed this from the binding very often, - * but we choose to write it in full for the benefit of grep. - * 3) an integer parameter to pass to the handler - * 4) a set of boolean flags, ORed together: - * BINDING_PER_WINDOW - this is a window-based binding. - * It is only valid if there is a - * current window, and will operate in - * some way on that window. - * BINDING_REVERSES - the binding can reverse if you hold down Shift - * BINDING_IS_REVERSED - the same, but the senses are reversed from the - * handler's point of view (let me know if I should - * explain this better) - * or 0 if no flag applies. - * - * Don't try to do XML entity escaping anywhere in the strings. - */ - -#ifndef keybind -#error "keybind () must be defined when you include screen-bindings.h" -#endif - -/***********************************/ - -#ifndef _BINDINGS_DEFINED_CONSTANTS -#define _BINDINGS_DEFINED_CONSTANTS 1 - -#define BINDING_PER_WINDOW 0x01 -#define BINDING_REVERSES 0x02 -#define BINDING_IS_REVERSED 0x04 - -#endif /* _BINDINGS_DEFINED_CONSTANTS */ - -/***********************************/ - -/* convenience, since in this file they must always be set together */ -#define REVERSES_AND_REVERSED (BINDING_REVERSES | BINDING_IS_REVERSED) - -keybind (switch-to-workspace-1, handle_switch_to_workspace, 0, 0) -keybind (switch-to-workspace-2, handle_switch_to_workspace, 1, 0) -keybind (switch-to-workspace-3, handle_switch_to_workspace, 2, 0) -keybind (switch-to-workspace-4, handle_switch_to_workspace, 3, 0) -keybind (switch-to-workspace-5, handle_switch_to_workspace, 4, 0) -keybind (switch-to-workspace-6, handle_switch_to_workspace, 5, 0) -keybind (switch-to-workspace-7, handle_switch_to_workspace, 6, 0) -keybind (switch-to-workspace-8, handle_switch_to_workspace, 7, 0) -keybind (switch-to-workspace-9, handle_switch_to_workspace, 8, 0) -keybind (switch-to-workspace-10, handle_switch_to_workspace, 9, 0) -keybind (switch-to-workspace-11, handle_switch_to_workspace, 10, 0) -keybind (switch-to-workspace-12, handle_switch_to_workspace, 11, 0) - -/* META_MOTION_* are negative, and so distinct from workspace numbers, - * which are always zero or positive. - * If you make use of these constants, you will need to include workspace.h - * (which you're probably using already for other reasons anyway). - * If your definition of keybind() throws them away, you don't need to include - * workspace.h, of course. - */ - -keybind (switch-to-workspace-left, handle_switch_to_workspace, - META_MOTION_LEFT, 0) - -keybind (switch-to-workspace-right, handle_switch_to_workspace, - META_MOTION_RIGHT, 0) - -keybind (switch-to-workspace-up, handle_switch_to_workspace, - META_MOTION_UP, 0) - -keybind (switch-to-workspace-down, handle_switch_to_workspace, - META_MOTION_DOWN, 0) - -/***********************************/ - -/* The ones which have inverses. These can't be bound to any keystroke - * containing Shift because Shift will invert their "backward" state. - * - * TODO: "NORMAL" and "DOCKS" should be renamed to the same name as their - * action, for obviousness. - * - * TODO: handle_switch and handle_cycle should probably really be the - * same function checking a bit in the parameter for difference. - */ - -keybind (switch-applications, handle_switch, META_TAB_LIST_NORMAL, - BINDING_REVERSES) -keybind (switch-applications-backward, handle_switch, META_TAB_LIST_NORMAL, - REVERSES_AND_REVERSED) -keybind (switch-group, handle_switch, META_TAB_LIST_GROUP, BINDING_REVERSES) -keybind (switch-group-backward, handle_switch, META_TAB_LIST_GROUP, - REVERSES_AND_REVERSED) -keybind (switch-windows, handle_switch, META_TAB_LIST_NORMAL, BINDING_REVERSES) -keybind (switch-windows-backward, handle_switch, META_TAB_LIST_NORMAL, - REVERSES_AND_REVERSED) -keybind (switch-panels, handle_switch, META_TAB_LIST_DOCKS, BINDING_REVERSES) -keybind (switch-panels-backward, handle_switch, META_TAB_LIST_DOCKS, - REVERSES_AND_REVERSED) - -keybind (cycle-group, handle_cycle, META_TAB_LIST_GROUP, BINDING_REVERSES) -keybind (cycle-group-backward, handle_cycle, META_TAB_LIST_GROUP, - REVERSES_AND_REVERSED) -keybind (cycle-windows, handle_cycle, META_TAB_LIST_NORMAL, BINDING_REVERSES) -keybind (cycle-windows-backward, handle_cycle, META_TAB_LIST_NORMAL, - REVERSES_AND_REVERSED) -keybind (cycle-panels, handle_cycle, META_TAB_LIST_DOCKS, BINDING_REVERSES) -keybind (cycle-panels-backward, handle_cycle, META_TAB_LIST_DOCKS, - REVERSES_AND_REVERSED) - -/***********************************/ - -keybind (show-desktop, handle_show_desktop, 0, 0) -keybind (panel-main-menu, handle_panel, - META_KEYBINDING_ACTION_PANEL_MAIN_MENU, 0) -keybind (panel-run-dialog, handle_panel, - META_KEYBINDING_ACTION_PANEL_RUN_DIALOG, 0) - -/* FIXME: No description because this is undocumented */ -keybind (set-spew-mark, handle_set_spew_mark, 0, 0) - -#undef REVERSES_AND_REVERSED - -/************************ PER WINDOW BINDINGS ************************/ - -/* These take a window as an extra parameter; they have no effect - * if no window is active. - */ - -keybind (activate-window-menu, handle_activate_window_menu, 0, - BINDING_PER_WINDOW) -keybind (toggle-fullscreen, handle_toggle_fullscreen, 0, BINDING_PER_WINDOW) -keybind (toggle-maximized, handle_toggle_maximized, 0, BINDING_PER_WINDOW) -keybind (toggle-above, handle_toggle_above, 0, BINDING_PER_WINDOW) -keybind (maximize, handle_maximize, 0, BINDING_PER_WINDOW) -keybind (unmaximize, handle_unmaximize, 0, BINDING_PER_WINDOW) -keybind (toggle-shaded, handle_toggle_shaded, 0, BINDING_PER_WINDOW) -keybind (minimize, handle_minimize, 0, BINDING_PER_WINDOW) -keybind (close, handle_close, 0, BINDING_PER_WINDOW) -keybind (begin-move, handle_begin_move, 0, BINDING_PER_WINDOW) -keybind (begin-resize, handle_begin_resize, 0, BINDING_PER_WINDOW) -keybind (toggle-on-all-workspaces, handle_toggle_on_all_workspaces, 0, - BINDING_PER_WINDOW) - -keybind (move-to-workspace-1, handle_move_to_workspace, 0, BINDING_PER_WINDOW) -keybind (move-to-workspace-2, handle_move_to_workspace, 1, BINDING_PER_WINDOW) -keybind (move-to-workspace-3, handle_move_to_workspace, 2, BINDING_PER_WINDOW) -keybind (move-to-workspace-4, handle_move_to_workspace, 3, BINDING_PER_WINDOW) -keybind (move-to-workspace-5, handle_move_to_workspace, 4, BINDING_PER_WINDOW) -keybind (move-to-workspace-6, handle_move_to_workspace, 5, BINDING_PER_WINDOW) -keybind (move-to-workspace-7, handle_move_to_workspace, 6, BINDING_PER_WINDOW) -keybind (move-to-workspace-8, handle_move_to_workspace, 7, BINDING_PER_WINDOW) -keybind (move-to-workspace-9, handle_move_to_workspace, 8, BINDING_PER_WINDOW) -keybind (move-to-workspace-10, handle_move_to_workspace, 9, BINDING_PER_WINDOW) -keybind (move-to-workspace-11, handle_move_to_workspace, 10, BINDING_PER_WINDOW) -keybind (move-to-workspace-12, handle_move_to_workspace, 11, BINDING_PER_WINDOW) - -/* META_MOTION_* are negative, and so distinct from workspace numbers, - * which are always zero or positive. - * If you make use of these constants, you will need to include workspace.h - * (which you're probably using already for other reasons anyway). - * If your definition of keybind() throws them away, you don't need to include - * workspace.h, of course. - */ - -keybind (move-to-workspace-left, handle_move_to_workspace, - META_MOTION_LEFT, BINDING_PER_WINDOW) -keybind (move-to-workspace-right, handle_move_to_workspace, - META_MOTION_RIGHT, BINDING_PER_WINDOW) -keybind (move-to-workspace-up, handle_move_to_workspace, - META_MOTION_UP, BINDING_PER_WINDOW) -keybind (move-to-workspace-down, handle_move_to_workspace, - META_MOTION_DOWN, BINDING_PER_WINDOW) - -keybind (raise-or-lower, handle_raise_or_lower, 0, BINDING_PER_WINDOW) -keybind (raise, handle_raise, 0, BINDING_PER_WINDOW) -keybind (lower, handle_lower, 0, BINDING_PER_WINDOW) - -keybind (maximize-vertically, handle_maximize_vertically, 0, BINDING_PER_WINDOW) - -keybind (maximize-horizontally, handle_maximize_horizontally, 0, - BINDING_PER_WINDOW) - -keybind (move-to-corner-nw, handle_move_to_corner_nw, 0, BINDING_PER_WINDOW) -keybind (move-to-corner-ne, handle_move_to_corner_ne, 0, BINDING_PER_WINDOW) -keybind (move-to-corner-sw, handle_move_to_corner_sw, 0, BINDING_PER_WINDOW) -keybind (move-to-corner-se, handle_move_to_corner_se, 0, BINDING_PER_WINDOW) - -keybind (move-to-side-n, handle_move_to_side_n, 0, BINDING_PER_WINDOW) -keybind (move-to-side-s, handle_move_to_side_s, 0, BINDING_PER_WINDOW) -keybind (move-to-side-e, handle_move_to_side_e, 0, BINDING_PER_WINDOW) -keybind (move-to-side-w, handle_move_to_side_w, 0, BINDING_PER_WINDOW) -keybind (move-to-center, handle_move_to_center, 0, BINDING_PER_WINDOW) - -/* eof all-keybindings.h */ - diff --git a/src/include/prefs.h b/src/include/prefs.h index b03557e5..6ce6fd39 100644 --- a/src/include/prefs.h +++ b/src/include/prefs.h @@ -25,6 +25,7 @@ /* This header is a "common" one between the UI and core side */ #include "common.h" +#include "types.h" #include <pango/pango-font.h> #include <gdesktop-enums.h> @@ -181,8 +182,59 @@ typedef enum _MetaKeyBindingAction META_KEYBINDING_ACTION_SHOW_DESKTOP, META_KEYBINDING_ACTION_PANEL_MAIN_MENU, META_KEYBINDING_ACTION_PANEL_RUN_DIALOG, + META_KEYBINDING_ACTION_SET_SPEW_MARK, + META_KEYBINDING_ACTION_ACTIVATE_WINDOW_MENU, + META_KEYBINDING_ACTION_TOGGLE_FULLSCREEN, + META_KEYBINDING_ACTION_TOGGLE_MAXIMIZED, + META_KEYBINDING_ACTION_TOGGLE_ABOVE, + META_KEYBINDING_ACTION_MAXIMIZE, + META_KEYBINDING_ACTION_UNMAXIMIZE, + META_KEYBINDING_ACTION_TOGGLE_SHADED, + META_KEYBINDING_ACTION_MINIMIZE, + META_KEYBINDING_ACTION_CLOSE, + META_KEYBINDING_ACTION_BEGIN_MOVE, + META_KEYBINDING_ACTION_BEGIN_RESIZE, + META_KEYBINDING_ACTION_TOGGLE_ON_ALL_WORKSPACES, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_1, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_2, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_3, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_4, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_5, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_6, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_7, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_8, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_9, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_10, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_11, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_12, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_LEFT, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_RIGHT, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_UP, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_DOWN, + META_KEYBINDING_ACTION_RAISE_OR_LOWER, + META_KEYBINDING_ACTION_RAISE, + META_KEYBINDING_ACTION_LOWER, + META_KEYBINDING_ACTION_MAXIMIZE_VERTICALLY, + META_KEYBINDING_ACTION_MAXIMIZE_HORIZONTALLY, + META_KEYBINDING_ACTION_MOVE_TO_CORNER_NW, + META_KEYBINDING_ACTION_MOVE_TO_CORNER_NE, + META_KEYBINDING_ACTION_MOVE_TO_CORNER_SW, + META_KEYBINDING_ACTION_MOVE_TO_CORNER_SE, + META_KEYBINDING_ACTION_MOVE_TO_SIDE_N, + META_KEYBINDING_ACTION_MOVE_TO_SIDE_S, + META_KEYBINDING_ACTION_MOVE_TO_SIDE_E, + META_KEYBINDING_ACTION_MOVE_TO_SIDE_W, + META_KEYBINDING_ACTION_MOVE_TO_CENTER, } MetaKeyBindingAction; +typedef enum +{ + META_KEY_BINDING_NONE, + META_KEY_BINDING_PER_WINDOW = 1 << 0, + META_KEY_BINDING_REVERSES = 1 << 1, + META_KEY_BINDING_IS_REVERSED = 1 << 2 +} MetaKeyBindingFlags; + typedef struct { unsigned int keysym; @@ -190,9 +242,26 @@ typedef struct MetaVirtualModifier modifiers; } MetaKeyCombo; +/** + * MetaKeyHandlerFunc: (skip) + * + */ +typedef void (* MetaKeyHandlerFunc) (MetaDisplay *display, + MetaScreen *screen, + MetaWindow *window, + XEvent *event, + MetaKeyBinding *binding, + gpointer user_data); + +typedef struct _MetaKeyHandler MetaKeyHandler; + typedef struct { - const char *name; + char *name; + char *schema; + + MetaKeyBindingAction action; + /** * A list of MetaKeyCombos. Each of them is bound to * this keypref. If one has keysym==modifiers==0, it is @@ -209,8 +278,7 @@ typedef struct gboolean per_window:1; } MetaKeyPref; -void meta_prefs_get_key_bindings (const MetaKeyPref **bindings, - int *n_bindings); +GList *meta_prefs_get_keybindings (void); MetaKeyBindingAction meta_prefs_get_keybinding_action (const char *name); diff --git a/src/include/types.h b/src/include/types.h index 738521a3..a779a1fe 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -26,4 +26,6 @@ typedef struct _MetaFrame MetaFrame; typedef struct _MetaScreen MetaScreen; typedef struct _MetaWindow MetaWindow; +typedef struct _MetaKeyBinding MetaKeyBinding; + #endif |