summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Müllner <fmuellner@gnome.org>2011-10-28 03:05:43 +0200
committerFlorian Müllner <fmuellner@gnome.org>2011-11-22 00:42:30 +0100
commitd42a2a3c2741b8b44b48f83eb79a82fb4fcd5bbd (patch)
treec1cb82b42fd0853e5fb25bfec88c2186b05ace59
parent78849bef047bea6c8530e4cbc6ae04d00d03c2ee (diff)
downloadmutter-d42a2a3c2741b8b44b48f83eb79a82fb4fcd5bbd.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
-rw-r--r--po/POTFILES.in1
-rw-r--r--src/Makefile.am1
-rw-r--r--src/core/all-keybindings.h243
-rw-r--r--src/core/keybindings-private.h25
-rw-r--r--src/core/keybindings.c867
-rw-r--r--src/core/prefs.c181
-rw-r--r--src/meta/keybindings.h31
-rw-r--r--src/meta/prefs.h32
8 files changed, 861 insertions, 520 deletions
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 638417b36..40cab83ec 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,7 +1,6 @@
# List of source files containing translatable strings.
# Please keep this file sorted alphabetically.
src/compositor/compositor.c
-src/core/all-keybindings.h
src/core/bell.c
src/core/core.c
src/core/delete.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 2db6b8c6d..7291a20b5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -152,7 +152,6 @@ libmutter_la_SOURCES = \
meta/theme.h \
ui/theme-private.h \
ui/ui.c \
- core/all-keybindings.h \
meta/preview-widget.h \
ui/preview-widget.c \
$(mutter_built_sources)
diff --git a/src/core/all-keybindings.h b/src/core/all-keybindings.h
deleted file mode 100644
index 7339465d7..000000000
--- a/src/core/all-keybindings.h
+++ /dev/null
@@ -1,243 +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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-/**
- * 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-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)
-
-/***********************************/
-
-/* These two are special pseudo-bindings that are provided for allowing
- * custom handlers, but will never be bound to a key. While a tab
- * grab is in effect, they are invoked for releasing the primary modifier
- * or pressing some unbound key, respectively.
- */
-keybind (tab-popup-select, handle_tab_popup_select, 0, 0)
-keybind (tab-popup-cancel, handle_tab_popup_cancel, 0, 0)
-
-/***********************************/
-
-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)
-keybind (toggle-recording, handle_toggle_recording, 0, 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/core/keybindings-private.h b/src/core/keybindings-private.h
index 9571100b4..a3dbfcc2d 100644
--- a/src/core/keybindings-private.h
+++ b/src/core/keybindings-private.h
@@ -31,6 +31,26 @@
#include <meta/keybindings.h>
+struct _MetaKeyHandler
+{
+ char *name;
+ MetaKeyHandlerFunc func;
+ MetaKeyHandlerFunc default_func;
+ gint data, 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);
void meta_screen_grab_keys (MetaScreen *screen);
@@ -52,6 +72,11 @@ void meta_set_keybindings_disabled (gboolean setting);
void meta_display_process_mapping_event (MetaDisplay *display,
XEvent *event);
+gboolean meta_prefs_add_keybinding (const char *name,
+ const char *schema,
+ MetaKeyBindingAction action,
+ MetaKeyBindingFlags flags);
+
#endif
diff --git a/src/core/keybindings.c b/src/core/keybindings.c
index 886905380..8897eacff 100644
--- a/src/core/keybindings.c
+++ b/src/core/keybindings.c
@@ -46,19 +46,18 @@
#include <X11/XKBlib.h>
#endif
+#define SCHEMA_COMMON_KEYBINDINGS "org.gnome.desktop.wm.keybindings"
+#define SCHEMA_MUTTER_KEYBINDINGS "org.gnome.mutter.keybindings"
+
static gboolean all_bindings_disabled = FALSE;
-/* Prototypes for handlers */
-#define keybind(name, handler, param, flags) \
-static void \
-handler (MetaDisplay *display,\
- MetaScreen *screen,\
- MetaWindow *window,\
- XEvent *event,\
- MetaKeyBinding *binding, \
- gpointer user_data);
-#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
@@ -103,13 +102,18 @@ static gboolean process_workspace_switch_grab (MetaDisplay *display,
static void regrab_key_bindings (MetaDisplay *display);
-#define keybind(name, handler, param, flags) \
- { #name, handler, handler, param, flags, NULL, NULL },
-static MetaKeyHandler key_handlers[] = {
-#include "all-keybindings.h"
- { NULL, NULL, NULL, 0, 0, NULL, NULL }
-};
-#undef keybind
+static GHashTable *key_handlers;
+
+#define HANDLER(name) g_hash_table_lookup (key_handlers, (name))
+
+static void
+key_handler_free (MetaKeyHandler *handler)
+{
+ 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)
@@ -302,17 +306,17 @@ 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)
{
@@ -322,58 +326,40 @@ count_bindings (const MetaKeyPref *prefs,
{
count += 1;
- if (prefs[i].add_shift &&
+ if (pref->add_shift &&
(combo->modifiers & META_VIRTUAL_SHIFT_MASK) == 0)
count += 1;
}
tmp = tmp->next;
}
-
- ++i;
- }
- return count;
-}
-
-/* FIXME: replace this with a temporary hash */
-static MetaKeyHandler*
-find_handler (MetaKeyHandler *handlers,
- const char *name)
-{
- MetaKeyHandler *iter;
-
- iter = handlers;
- while (iter->name)
- {
- if (strcmp (iter->name, name) == 0)
- return iter;
-
- ++iter;
+ p = p->next;
}
- return NULL;
+ return count;
}
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)
{
@@ -381,45 +367,45 @@ rebuild_binding_table (MetaDisplay *display,
if (combo && (combo->keysym != None || combo->keycode != 0))
{
- MetaKeyHandler *handler = find_handler (key_handlers, prefs[src].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;
+ MetaKeyHandler *handler = HANDLER (pref->name);
+
+ (*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 &&
+ 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 |
+ (*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)[dest].mask = 0;
+ (*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",
@@ -429,17 +415,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
@@ -514,6 +500,32 @@ display_get_keybinding (MetaDisplay *display,
return NULL;
}
+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;
+}
+
/**
* meta_display_get_keybinding_action:
* @display: A #MetaDisplay
@@ -622,55 +634,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);
- rebuild_special_bindings (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)
{
/* Note that display->xdisplay is invalid in this function */
@@ -797,7 +760,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,
@@ -1261,14 +1224,14 @@ invoke_handler (MetaDisplay *display,
{
if (handler->func)
(* handler->func) (display, screen,
- handler->flags & BINDING_PER_WINDOW ?
+ handler->flags & META_KEY_BINDING_PER_WINDOW ?
window : NULL,
event,
binding,
handler->user_data);
else
(* handler->default_func) (display, screen,
- handler->flags & BINDING_PER_WINDOW ?
+ handler->flags & META_KEY_BINDING_PER_WINDOW ?
window: NULL,
event,
binding,
@@ -1284,7 +1247,7 @@ invoke_handler_by_name (MetaDisplay *display,
{
MetaKeyHandler *handler;
- handler = find_handler (key_handlers, handler_name);
+ handler = HANDLER (handler_name);
if (handler)
invoke_handler (display, screen, handler, window, event, NULL);
}
@@ -1314,17 +1277,17 @@ process_event (MetaKeyBinding *bindings,
{
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)) !=
bindings[i].mask))
continue;
-
+
/*
* 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,
@@ -1338,7 +1301,7 @@ process_event (MetaKeyBinding *bindings,
meta_topic (META_DEBUG_KEYBINDINGS,
"Running handler for %s\n",
bindings[i].name);
-
+
/* Global keybindings count as a let-the-terminal-lose-focus
* due to new window mapping until the user starts
* interacting with the terminal again.
@@ -3069,7 +3032,7 @@ handle_switch (MetaDisplay *display,
MetaKeyBinding *binding,
gpointer dummy)
{
- 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);
@@ -3083,7 +3046,7 @@ handle_cycle (MetaDisplay *display,
MetaKeyBinding *binding,
gpointer dummy)
{
- 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);
@@ -3476,7 +3439,7 @@ meta_keybindings_set_custom_handler (const gchar *name,
gpointer user_data,
GDestroyNotify free_data)
{
- MetaKeyHandler *key_handler = find_handler (key_handlers, name);
+ MetaKeyHandler *key_handler = HANDLER (name);
if (!key_handler)
return FALSE;
@@ -3502,9 +3465,623 @@ meta_keybindings_switch_window (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);
}
+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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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-group",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_REVERSES,
+ META_KEYBINDING_ACTION_SWITCH_GROUP,
+ 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,
+ handle_switch, META_TAB_LIST_GROUP);
+
+ add_builtin_keybinding (display,
+ "switch-windows",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_REVERSES,
+ META_KEYBINDING_ACTION_SWITCH_WINDOWS,
+ 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,
+ handle_switch, META_TAB_LIST_NORMAL);
+
+ add_builtin_keybinding (display,
+ "switch-panels",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_REVERSES,
+ META_KEYBINDING_ACTION_SWITCH_PANELS,
+ 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,
+ handle_switch, META_TAB_LIST_DOCKS);
+
+ add_builtin_keybinding (display,
+ "cycle-group",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_REVERSES,
+ META_KEYBINDING_ACTION_CYCLE_GROUP,
+ 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,
+ handle_cycle, META_TAB_LIST_GROUP);
+
+ add_builtin_keybinding (display,
+ "cycle-windows",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_REVERSES,
+ META_KEYBINDING_ACTION_CYCLE_WINDOWS,
+ 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,
+ handle_cycle, META_TAB_LIST_NORMAL);
+
+ add_builtin_keybinding (display,
+ "cycle-panels",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_REVERSES,
+ META_KEYBINDING_ACTION_CYCLE_PANELS,
+ 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,
+ handle_cycle, META_TAB_LIST_DOCKS);
+
+
+/* These two are special pseudo-bindings that are provided for allowing
+ * custom handlers, but will never be bound to a key. While a tab
+ * grab is in effect, they are invoked for releasing the primary modifier
+ * or pressing some unbound key, respectively.
+ */
+ add_builtin_keybinding (display,
+ "tab-popup-select",
+ SCHEMA_MUTTER_KEYBINDINGS,
+ META_KEY_BINDING_NONE,
+ META_KEYBINDING_ACTION_TAB_POPUP_SELECT,
+ handle_tab_popup_select, 0);
+
+ add_builtin_keybinding (display,
+ "tab-popup-cancel",
+ SCHEMA_MUTTER_KEYBINDINGS,
+ META_KEY_BINDING_NONE,
+ META_KEYBINDING_ACTION_TAB_POPUP_CANCEL,
+ handle_tab_popup_cancel, 0);
+
+/***********************************/
+
+ add_builtin_keybinding (display,
+ "show-desktop",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_NONE,
+ META_KEYBINDING_ACTION_SHOW_DESKTOP,
+ handle_show_desktop, 0);
+
+ add_builtin_keybinding (display,
+ "panel-main-menu",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_NONE,
+ META_KEYBINDING_ACTION_PANEL_MAIN_MENU,
+ 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,
+ handle_panel, META_KEYBINDING_ACTION_PANEL_RUN_DIALOG);
+
+ add_builtin_keybinding (display,
+ "toggle-recording",
+ SCHEMA_MUTTER_KEYBINDINGS,
+ META_KEY_BINDING_NONE,
+ META_KEYBINDING_ACTION_TOGGLE_RECORDING,
+ handle_toggle_recording, 0);
+
+ add_builtin_keybinding (display,
+ "set-spew-mark",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_NONE,
+ META_KEYBINDING_ACTION_SET_SPEW_MARK,
+ 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,
+ handle_activate_window_menu, 0);
+
+ add_builtin_keybinding (display,
+ "toggle-fullscreen",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_PER_WINDOW,
+ META_KEYBINDING_ACTION_TOGGLE_FULLSCREEN,
+ handle_toggle_fullscreen, 0);
+
+ add_builtin_keybinding (display,
+ "toggle-maximized",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_PER_WINDOW,
+ META_KEYBINDING_ACTION_TOGGLE_MAXIMIZED,
+ handle_toggle_maximized, 0);
+
+ add_builtin_keybinding (display,
+ "toggle-above",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_PER_WINDOW,
+ META_KEYBINDING_ACTION_TOGGLE_ABOVE,
+ handle_toggle_above, 0);
+
+ add_builtin_keybinding (display,
+ "maximize",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_PER_WINDOW,
+ META_KEYBINDING_ACTION_MAXIMIZE,
+ handle_maximize, 0);
+
+ add_builtin_keybinding (display,
+ "unmaximize",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_PER_WINDOW,
+ META_KEYBINDING_ACTION_UNMAXIMIZE,
+ handle_unmaximize, 0);
+
+ add_builtin_keybinding (display,
+ "toggle-shaded",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_PER_WINDOW,
+ META_KEYBINDING_ACTION_TOGGLE_SHADED,
+ handle_toggle_shaded, 0);
+
+ add_builtin_keybinding (display,
+ "minimize",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_PER_WINDOW,
+ META_KEYBINDING_ACTION_MINIMIZE,
+ handle_minimize, 0);
+
+ add_builtin_keybinding (display,
+ "close",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_PER_WINDOW,
+ META_KEYBINDING_ACTION_CLOSE,
+ handle_close, 0);
+
+ add_builtin_keybinding (display,
+ "begin-move",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_PER_WINDOW,
+ META_KEYBINDING_ACTION_BEGIN_MOVE,
+ handle_begin_move, 0);
+
+ add_builtin_keybinding (display,
+ "begin-resize",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_PER_WINDOW,
+ META_KEYBINDING_ACTION_BEGIN_RESIZE,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ handle_raise_or_lower, 0);
+
+ add_builtin_keybinding (display,
+ "raise",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_PER_WINDOW,
+ META_KEYBINDING_ACTION_RAISE,
+ handle_raise, 0);
+
+ add_builtin_keybinding (display,
+ "lower",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_PER_WINDOW,
+ META_KEYBINDING_ACTION_LOWER,
+ handle_lower, 0);
+
+ add_builtin_keybinding (display,
+ "maximize-vertically",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_PER_WINDOW,
+ META_KEYBINDING_ACTION_MAXIMIZE_VERTICALLY,
+ handle_maximize_vertically, 0);
+
+ add_builtin_keybinding (display,
+ "maximize-horizontally",
+ SCHEMA_COMMON_KEYBINDINGS,
+ META_KEY_BINDING_PER_WINDOW,
+ META_KEYBINDING_ACTION_MAXIMIZE_HORIZONTALLY,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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);
+ rebuild_special_bindings (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/prefs.c b/src/core/prefs.c
index fd76102da..3455de0af 100644
--- a/src/core/prefs.c
+++ b/src/core/prefs.c
@@ -33,6 +33,7 @@
#include <gio/gio.h>
#include <string.h>
#include <stdlib.h>
+#include "keybindings-private.h"
/* If you add a key, it needs updating in init() and in the gsettings
* notify listener and of course in the .schemas file.
@@ -62,9 +63,6 @@
#define SCHEMA_MUTTER "org.gnome.mutter"
#define SCHEMA_INTERFACE "org.gnome.desktop.interface"
-#define SCHEMA_COMMON_KEYBINDINGS "org.gnome.desktop.wm.keybindings"
-#define SCHEMA_MUTTER_KEYBINDINGS "org.gnome.mutter.keybindings"
-
#define SETTINGS(s) g_hash_table_lookup (settings_schemas, (s))
static GList *changes = NULL;
@@ -831,17 +829,6 @@ meta_prefs_init (void)
G_CALLBACK (settings_changed), NULL);
g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_INTERFACE), settings);
- /* Bindings have a separate handler, since they are in separate schemas
- * and work differently */
- settings = g_settings_new (SCHEMA_COMMON_KEYBINDINGS);
- g_signal_connect (settings, "changed", G_CALLBACK (bindings_changed), NULL);
- g_hash_table_insert (settings_schemas,
- g_strdup (SCHEMA_COMMON_KEYBINDINGS), settings);
-
- settings = g_settings_new (SCHEMA_MUTTER_KEYBINDINGS);
- g_signal_connect (settings, "changed", G_CALLBACK (bindings_changed), NULL);
- g_hash_table_insert (settings_schemas,
- g_strdup (SCHEMA_MUTTER_KEYBINDINGS), settings);
for (tmp = overridden_keys; tmp; tmp = tmp->next)
{
@@ -1644,16 +1631,21 @@ 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 MetaKeyCombo overlay_key_combo = { 0, 0, 0 };
+static void
+meta_key_pref_free (MetaKeyPref *pref)
+{
+ update_binding (pref, NULL);
+
+ g_free (pref->name);
+ g_free (pref->schema);
+
+ g_free (pref);
+}
+
/* These bindings are for modifiers alone, so they need special handling */
static void
init_special_bindings (void)
@@ -1682,34 +1674,8 @@ init_special_bindings (void)
static void
init_bindings (void)
{
- int i;
- gchar **keys;
- gchar **strokes;
-
- g_assert (G_N_ELEMENTS (key_bindings) == META_KEYBINDING_ACTION_LAST + 1);
-
- keys = g_settings_list_keys (SETTINGS (SCHEMA_COMMON_KEYBINDINGS));
- for (i = 0; (guint)i < g_strv_length (keys); i++)
- {
- strokes = g_settings_get_strv (SETTINGS (SCHEMA_COMMON_KEYBINDINGS),
- keys[i]);
- update_key_binding (keys[i], strokes);
-
- g_strfreev (strokes);
- }
- g_strfreev (keys);
-
- keys = g_settings_list_keys (SETTINGS (SCHEMA_MUTTER_KEYBINDINGS));
- for (i = 0; (guint)i < g_strv_length (keys); i++)
- {
- strokes = g_settings_get_strv (SETTINGS (SCHEMA_MUTTER_KEYBINDINGS),
- keys[i]);
- update_key_binding (keys[i], strokes);
-
- g_strfreev (strokes);
- }
- g_strfreev (keys);
-
+ key_bindings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
+ (GDestroyNotify)meta_key_pref_free);
init_special_bindings ();
}
@@ -1796,15 +1762,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;
}
@@ -1938,13 +1899,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)
{
-
- *bindings = key_bindings;
- *n_bindings = (int) G_N_ELEMENTS (key_bindings) - 1;
+ MetaKeyPref *pref;
+ GSettings *settings;
+ char **strokes;
+
+ 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);
}
void
@@ -2004,18 +2008,10 @@ 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
@@ -2027,36 +2023,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/meta/keybindings.h b/src/meta/keybindings.h
index cf93aed98..7b5171bff 100644
--- a/src/meta/keybindings.h
+++ b/src/meta/keybindings.h
@@ -23,37 +23,6 @@
#include <meta/display.h>
#include <meta/common.h>
-/**
- * MetaKeyHandlerFunc: (skip)
- *
- */
-typedef void (* MetaKeyHandlerFunc) (MetaDisplay *display,
- MetaScreen *screen,
- MetaWindow *window,
- XEvent *event,
- MetaKeyBinding *binding,
- gpointer user_data);
-
-typedef struct
-{
- const char *name;
- MetaKeyHandlerFunc func;
- MetaKeyHandlerFunc default_func;
- gint data, flags;
- gpointer user_data;
- GDestroyNotify user_data_free_func;
-} MetaKeyHandler;
-
-struct _MetaKeyBinding
-{
- const char *name;
- KeySym keysym;
- KeyCode keycode;
- unsigned int mask;
- MetaVirtualModifier modifiers;
- MetaKeyHandler *handler;
-};
-
gboolean meta_keybindings_set_custom_handler (const gchar *name,
MetaKeyHandlerFunc handler,
diff --git a/src/meta/prefs.h b/src/meta/prefs.h
index a54a96be8..d973e4b22 100644
--- a/src/meta/prefs.h
+++ b/src/meta/prefs.h
@@ -27,6 +27,7 @@
/* This header is a "common" one between the UI and core side */
#include <meta/common.h>
+#include <meta/types.h>
#include <pango/pango-font.h>
#include <gdesktop-enums.h>
@@ -233,6 +234,14 @@ typedef enum _MetaKeyBindingAction
META_KEYBINDING_ACTION_LAST
} 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;
@@ -240,9 +249,27 @@ 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
@@ -257,8 +284,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);