mirror of
https://github.com/brl/mutter.git
synced 2024-11-24 17:10:40 -05:00
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
This commit is contained in:
parent
78849bef04
commit
d42a2a3c27
@ -1,7 +1,6 @@
|
|||||||
# List of source files containing translatable strings.
|
# List of source files containing translatable strings.
|
||||||
# Please keep this file sorted alphabetically.
|
# Please keep this file sorted alphabetically.
|
||||||
src/compositor/compositor.c
|
src/compositor/compositor.c
|
||||||
src/core/all-keybindings.h
|
|
||||||
src/core/bell.c
|
src/core/bell.c
|
||||||
src/core/core.c
|
src/core/core.c
|
||||||
src/core/delete.c
|
src/core/delete.c
|
||||||
|
@ -152,7 +152,6 @@ libmutter_la_SOURCES = \
|
|||||||
meta/theme.h \
|
meta/theme.h \
|
||||||
ui/theme-private.h \
|
ui/theme-private.h \
|
||||||
ui/ui.c \
|
ui/ui.c \
|
||||||
core/all-keybindings.h \
|
|
||||||
meta/preview-widget.h \
|
meta/preview-widget.h \
|
||||||
ui/preview-widget.c \
|
ui/preview-widget.c \
|
||||||
$(mutter_built_sources)
|
$(mutter_built_sources)
|
||||||
|
@ -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 */
|
|
||||||
|
|
@ -31,6 +31,26 @@
|
|||||||
|
|
||||||
#include <meta/keybindings.h>
|
#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_init_keys (MetaDisplay *display);
|
||||||
void meta_display_shutdown_keys (MetaDisplay *display);
|
void meta_display_shutdown_keys (MetaDisplay *display);
|
||||||
void meta_screen_grab_keys (MetaScreen *screen);
|
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,
|
void meta_display_process_mapping_event (MetaDisplay *display,
|
||||||
XEvent *event);
|
XEvent *event);
|
||||||
|
|
||||||
|
gboolean meta_prefs_add_keybinding (const char *name,
|
||||||
|
const char *schema,
|
||||||
|
MetaKeyBindingAction action,
|
||||||
|
MetaKeyBindingFlags flags);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
181
src/core/prefs.c
181
src/core/prefs.c
@ -33,6 +33,7 @@
|
|||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include "keybindings-private.h"
|
||||||
|
|
||||||
/* If you add a key, it needs updating in init() and in the gsettings
|
/* If you add a key, it needs updating in init() and in the gsettings
|
||||||
* notify listener and of course in the .schemas file.
|
* notify listener and of course in the .schemas file.
|
||||||
@ -62,9 +63,6 @@
|
|||||||
#define SCHEMA_MUTTER "org.gnome.mutter"
|
#define SCHEMA_MUTTER "org.gnome.mutter"
|
||||||
#define SCHEMA_INTERFACE "org.gnome.desktop.interface"
|
#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))
|
#define SETTINGS(s) g_hash_table_lookup (settings_schemas, (s))
|
||||||
|
|
||||||
static GList *changes = NULL;
|
static GList *changes = NULL;
|
||||||
@ -831,17 +829,6 @@ meta_prefs_init (void)
|
|||||||
G_CALLBACK (settings_changed), NULL);
|
G_CALLBACK (settings_changed), NULL);
|
||||||
g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_INTERFACE), settings);
|
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)
|
for (tmp = overridden_keys; tmp; tmp = tmp->next)
|
||||||
{
|
{
|
||||||
@ -1644,16 +1631,21 @@ meta_prefs_set_num_workspaces (int n_workspaces)
|
|||||||
n_workspaces);
|
n_workspaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define keybind(name, handler, param, flags) \
|
static GHashTable *key_bindings;
|
||||||
{ #name, NULL, !!(flags & BINDING_REVERSES), !!(flags & BINDING_PER_WINDOW) },
|
|
||||||
static MetaKeyPref key_bindings[] = {
|
|
||||||
#include "all-keybindings.h"
|
|
||||||
{ NULL, NULL, FALSE }
|
|
||||||
};
|
|
||||||
#undef keybind
|
|
||||||
|
|
||||||
static MetaKeyCombo overlay_key_combo = { 0, 0, 0 };
|
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 */
|
/* These bindings are for modifiers alone, so they need special handling */
|
||||||
static void
|
static void
|
||||||
init_special_bindings (void)
|
init_special_bindings (void)
|
||||||
@ -1682,34 +1674,8 @@ init_special_bindings (void)
|
|||||||
static void
|
static void
|
||||||
init_bindings (void)
|
init_bindings (void)
|
||||||
{
|
{
|
||||||
int i;
|
key_bindings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
|
||||||
gchar **keys;
|
(GDestroyNotify)meta_key_pref_free);
|
||||||
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);
|
|
||||||
|
|
||||||
init_special_bindings ();
|
init_special_bindings ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1796,15 +1762,10 @@ static gboolean
|
|||||||
update_key_binding (const char *key,
|
update_key_binding (const char *key,
|
||||||
gchar **strokes)
|
gchar **strokes)
|
||||||
{
|
{
|
||||||
int i;
|
MetaKeyPref *pref = g_hash_table_lookup (key_bindings, key);
|
||||||
|
|
||||||
i = 0;
|
if (pref)
|
||||||
while (key_bindings[i].name &&
|
return update_binding (pref, strokes);
|
||||||
strcmp (key, key_bindings[i].name) != 0)
|
|
||||||
++i;
|
|
||||||
|
|
||||||
if (key_bindings[i].name)
|
|
||||||
return update_binding (&key_bindings[i], strokes);
|
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -1938,13 +1899,56 @@ meta_prefs_get_visual_bell_type (void)
|
|||||||
return visual_bell_type;
|
return visual_bell_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
gboolean
|
||||||
meta_prefs_get_key_bindings (const MetaKeyPref **bindings,
|
meta_prefs_add_keybinding (const char *name,
|
||||||
int *n_bindings)
|
const char *schema,
|
||||||
|
MetaKeyBindingAction action,
|
||||||
|
MetaKeyBindingFlags flags)
|
||||||
{
|
{
|
||||||
|
MetaKeyPref *pref;
|
||||||
*bindings = key_bindings;
|
GSettings *settings;
|
||||||
*n_bindings = (int) G_N_ELEMENTS (key_bindings) - 1;
|
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
|
void
|
||||||
@ -2004,18 +2008,10 @@ meta_prefs_get_edge_tiling ()
|
|||||||
MetaKeyBindingAction
|
MetaKeyBindingAction
|
||||||
meta_prefs_get_keybinding_action (const char *name)
|
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 */
|
return pref ? pref->action
|
||||||
while (i >= 0)
|
: META_KEYBINDING_ACTION_NONE;
|
||||||
{
|
|
||||||
if (strcmp (key_bindings[i].name, name) == 0)
|
|
||||||
return (MetaKeyBindingAction) i;
|
|
||||||
|
|
||||||
--i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return META_KEYBINDING_ACTION_NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is used by the menu system to decide what key binding
|
/* 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,
|
unsigned int *keysym,
|
||||||
MetaVirtualModifier *modifiers)
|
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 */
|
if (pref->per_window)
|
||||||
while (i >= 0)
|
|
||||||
{
|
{
|
||||||
if (key_bindings[i].per_window &&
|
GSList *s = pref->bindings;
|
||||||
strcmp (key_bindings[i].name, name) == 0)
|
|
||||||
|
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;
|
*keysym = c->keysym;
|
||||||
|
*modifiers = c->modifiers;
|
||||||
if (c->keysym!=0 || c->modifiers!=0)
|
return;
|
||||||
{
|
|
||||||
*keysym = c->keysym;
|
|
||||||
*modifiers = c->modifiers;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
s = s->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not found; return the disabled value */
|
s = s->next;
|
||||||
*keysym = *modifiers = 0;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
--i;
|
/* Not found; return the disabled value */
|
||||||
|
*keysym = *modifiers = 0;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
|
@ -23,37 +23,6 @@
|
|||||||
#include <meta/display.h>
|
#include <meta/display.h>
|
||||||
#include <meta/common.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,
|
gboolean meta_keybindings_set_custom_handler (const gchar *name,
|
||||||
MetaKeyHandlerFunc handler,
|
MetaKeyHandlerFunc handler,
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
/* This header is a "common" one between the UI and core side */
|
/* This header is a "common" one between the UI and core side */
|
||||||
#include <meta/common.h>
|
#include <meta/common.h>
|
||||||
|
#include <meta/types.h>
|
||||||
#include <pango/pango-font.h>
|
#include <pango/pango-font.h>
|
||||||
#include <gdesktop-enums.h>
|
#include <gdesktop-enums.h>
|
||||||
|
|
||||||
@ -233,6 +234,14 @@ typedef enum _MetaKeyBindingAction
|
|||||||
META_KEYBINDING_ACTION_LAST
|
META_KEYBINDING_ACTION_LAST
|
||||||
} MetaKeyBindingAction;
|
} 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
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned int keysym;
|
unsigned int keysym;
|
||||||
@ -240,9 +249,27 @@ typedef struct
|
|||||||
MetaVirtualModifier modifiers;
|
MetaVirtualModifier modifiers;
|
||||||
} MetaKeyCombo;
|
} 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
|
typedef struct
|
||||||
{
|
{
|
||||||
const char *name;
|
char *name;
|
||||||
|
char *schema;
|
||||||
|
|
||||||
|
MetaKeyBindingAction action;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of MetaKeyCombos. Each of them is bound to
|
* A list of MetaKeyCombos. Each of them is bound to
|
||||||
* this keypref. If one has keysym==modifiers==0, it is
|
* this keypref. If one has keysym==modifiers==0, it is
|
||||||
@ -257,8 +284,7 @@ typedef struct
|
|||||||
gboolean per_window:1;
|
gboolean per_window:1;
|
||||||
} MetaKeyPref;
|
} MetaKeyPref;
|
||||||
|
|
||||||
void meta_prefs_get_key_bindings (const MetaKeyPref **bindings,
|
GList *meta_prefs_get_keybindings (void);
|
||||||
int *n_bindings);
|
|
||||||
|
|
||||||
MetaKeyBindingAction meta_prefs_get_keybinding_action (const char *name);
|
MetaKeyBindingAction meta_prefs_get_keybinding_action (const char *name);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user