mirror of
https://github.com/brl/mutter.git
synced 2024-11-26 01:50:42 -05:00
keybindings: Rewrite the modmap code so that it uses libxkbcommon
This removes our Xwayland dependency in the native path. The direct grabs are still there for the X11 backend and are a bit disgusting, but that's OK. We can refactor it out later. This introduces some pretty lousy hackery because it depends on https://github.com/xkbcommon/libxkbcommon/pull/10 , and I really don't want to wait on that to squash this dep.
This commit is contained in:
parent
04ddfe0a6f
commit
3645c63c08
@ -153,6 +153,8 @@ libmutter_la_SOURCES = \
|
|||||||
meta/gradient.h \
|
meta/gradient.h \
|
||||||
core/meta-gesture-tracker.c \
|
core/meta-gesture-tracker.c \
|
||||||
core/meta-gesture-tracker-private.h \
|
core/meta-gesture-tracker-private.h \
|
||||||
|
core/xkbcommon-hacks.c \
|
||||||
|
core/xkbcommon-hacks.h \
|
||||||
core/keybindings.c \
|
core/keybindings.c \
|
||||||
core/keybindings-private.h \
|
core/keybindings-private.h \
|
||||||
core/main.c \
|
core/main.c \
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
#include <meta/keybindings.h>
|
#include <meta/keybindings.h>
|
||||||
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
typedef struct _MetaKeyHandler MetaKeyHandler;
|
typedef struct _MetaKeyHandler MetaKeyHandler;
|
||||||
struct _MetaKeyHandler
|
struct _MetaKeyHandler
|
||||||
@ -97,10 +98,10 @@ typedef struct
|
|||||||
int max_keycode;
|
int max_keycode;
|
||||||
KeySym *keymap;
|
KeySym *keymap;
|
||||||
int keysyms_per_keycode;
|
int keysyms_per_keycode;
|
||||||
unsigned int ignored_modifier_mask;
|
xkb_mod_mask_t ignored_modifier_mask;
|
||||||
unsigned int hyper_mask;
|
xkb_mod_mask_t hyper_mask;
|
||||||
unsigned int super_mask;
|
xkb_mod_mask_t super_mask;
|
||||||
unsigned int meta_mask;
|
xkb_mod_mask_t meta_mask;
|
||||||
MetaKeyCombo overlay_key_combo;
|
MetaKeyCombo overlay_key_combo;
|
||||||
gboolean overlay_key_only_pressed;
|
gboolean overlay_key_only_pressed;
|
||||||
MetaKeyCombo *iso_next_group_combos;
|
MetaKeyCombo *iso_next_group_combos;
|
||||||
|
@ -39,11 +39,10 @@
|
|||||||
#include "screen-private.h"
|
#include "screen-private.h"
|
||||||
#include <meta/prefs.h>
|
#include <meta/prefs.h>
|
||||||
#include "meta-accel-parse.h"
|
#include "meta-accel-parse.h"
|
||||||
|
#include "xkbcommon-hacks.h"
|
||||||
|
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
|
|
||||||
#include <xkbcommon/xkbcommon.h>
|
|
||||||
|
|
||||||
#include "backends/x11/meta-backend-x11.h"
|
#include "backends/x11/meta-backend-x11.h"
|
||||||
#include "x11/window-x11.h"
|
#include "x11/window-x11.h"
|
||||||
|
|
||||||
@ -201,73 +200,31 @@ keysym_name (xkb_keysym_t keysym)
|
|||||||
static void
|
static void
|
||||||
reload_modmap (MetaKeyBindingManager *keys)
|
reload_modmap (MetaKeyBindingManager *keys)
|
||||||
{
|
{
|
||||||
XModifierKeymap *modmap;
|
MetaBackend *backend = meta_get_backend ();
|
||||||
int map_size;
|
struct xkb_keymap *keymap = meta_backend_get_keymap (backend);
|
||||||
int i;
|
xkb_mod_mask_t scroll_lock_mask;
|
||||||
int scroll_lock_mask = 0;
|
|
||||||
|
|
||||||
modmap = XGetModifierMapping (keys->xdisplay);
|
/* Modifiers to find. */
|
||||||
keys->ignored_modifier_mask = 0;
|
struct {
|
||||||
|
char *name;
|
||||||
|
xkb_mod_mask_t *mask_p;
|
||||||
|
} mods[] = {
|
||||||
|
{ "ScrollLock", &scroll_lock_mask },
|
||||||
|
{ "Meta", &keys->meta_mask },
|
||||||
|
{ "Hyper", &keys->hyper_mask },
|
||||||
|
{ "Super", &keys->super_mask },
|
||||||
|
};
|
||||||
|
|
||||||
/* Multiple bits may get set in each of these */
|
gsize i;
|
||||||
keys->meta_mask = 0;
|
for (i = 0; i < G_N_ELEMENTS (mods); i++)
|
||||||
keys->hyper_mask = 0;
|
{
|
||||||
keys->super_mask = 0;
|
xkb_mod_mask_t *mask_p = mods[i].mask_p;
|
||||||
|
xkb_mod_index_t idx = xkb_keymap_mod_get_index (keymap, mods[i].name);
|
||||||
|
|
||||||
/* there are 8 modifiers, and the first 3 are shift, shift lock,
|
if (idx != XKB_MOD_INVALID)
|
||||||
* and control
|
*mask_p = my_xkb_keymap_mod_get_mask (keymap, idx);
|
||||||
*/
|
else
|
||||||
map_size = 8 * modmap->max_keypermod;
|
*mask_p = 0;
|
||||||
i = 3 * modmap->max_keypermod;
|
|
||||||
while (i < map_size)
|
|
||||||
{
|
|
||||||
/* get the key code at this point in the map,
|
|
||||||
* see if its keysym is one we're interested in
|
|
||||||
*/
|
|
||||||
int keycode = modmap->modifiermap[i];
|
|
||||||
|
|
||||||
if (keycode >= keys->min_keycode &&
|
|
||||||
keycode <= keys->max_keycode)
|
|
||||||
{
|
|
||||||
int j = 0;
|
|
||||||
KeySym *syms = keys->keymap +
|
|
||||||
(keycode - keys->min_keycode) * keys->keysyms_per_keycode;
|
|
||||||
|
|
||||||
while (j < keys->keysyms_per_keycode)
|
|
||||||
{
|
|
||||||
if (syms[j] != 0)
|
|
||||||
{
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
||||||
"Keysym %s bound to modifier 0x%x\n",
|
|
||||||
keysym_name (syms[j]),
|
|
||||||
(1 << ( i / modmap->max_keypermod)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (syms[j] == XKB_KEY_Scroll_Lock)
|
|
||||||
{
|
|
||||||
scroll_lock_mask |= (1 << ( i / modmap->max_keypermod));
|
|
||||||
}
|
|
||||||
else if (syms[j] == XKB_KEY_Super_L ||
|
|
||||||
syms[j] == XKB_KEY_Super_R)
|
|
||||||
{
|
|
||||||
keys->super_mask |= (1 << ( i / modmap->max_keypermod));
|
|
||||||
}
|
|
||||||
else if (syms[j] == XKB_KEY_Hyper_L ||
|
|
||||||
syms[j] == XKB_KEY_Hyper_R)
|
|
||||||
{
|
|
||||||
keys->hyper_mask |= (1 << ( i / modmap->max_keypermod));
|
|
||||||
}
|
|
||||||
else if (syms[j] == XKB_KEY_Meta_L ||
|
|
||||||
syms[j] == XKB_KEY_Meta_R)
|
|
||||||
{
|
|
||||||
keys->meta_mask |= (1 << ( i / modmap->max_keypermod));
|
|
||||||
}
|
|
||||||
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
keys->ignored_modifier_mask = (scroll_lock_mask | Mod2Mask | LockMask);
|
keys->ignored_modifier_mask = (scroll_lock_mask | Mod2Mask | LockMask);
|
||||||
@ -279,8 +236,6 @@ reload_modmap (MetaKeyBindingManager *keys)
|
|||||||
keys->hyper_mask,
|
keys->hyper_mask,
|
||||||
keys->super_mask,
|
keys->super_mask,
|
||||||
keys->meta_mask);
|
keys->meta_mask);
|
||||||
|
|
||||||
XFreeModifiermap (modmap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Original code from gdk_x11_keymap_get_entries_for_keyval() in
|
/* Original code from gdk_x11_keymap_get_entries_for_keyval() in
|
||||||
|
112
src/core/xkbcommon-hacks.c
Normal file
112
src/core/xkbcommon-hacks.c
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Red Hat
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* Written by:
|
||||||
|
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "xkbcommon-hacks.h"
|
||||||
|
|
||||||
|
/* Terrible, gross hackery to provide an implementation for xkb_keymap_mod_get_mask.
|
||||||
|
* Delete when https://github.com/xkbcommon/libxkbcommon/pull/10 is pushed. */
|
||||||
|
|
||||||
|
/* The structures here have been pulled from libxkbcommon. */
|
||||||
|
|
||||||
|
enum xkb_action_controls {
|
||||||
|
CONTROL_REPEAT = (1 << 0),
|
||||||
|
CONTROL_SLOW = (1 << 1),
|
||||||
|
CONTROL_DEBOUNCE = (1 << 2),
|
||||||
|
CONTROL_STICKY = (1 << 3),
|
||||||
|
CONTROL_MOUSEKEYS = (1 << 4),
|
||||||
|
CONTROL_MOUSEKEYS_ACCEL = (1 << 5),
|
||||||
|
CONTROL_AX = (1 << 6),
|
||||||
|
CONTROL_AX_TIMEOUT = (1 << 7),
|
||||||
|
CONTROL_AX_FEEDBACK = (1 << 8),
|
||||||
|
CONTROL_BELL = (1 << 9),
|
||||||
|
CONTROL_IGNORE_GROUP_LOCK = (1 << 10),
|
||||||
|
CONTROL_ALL = \
|
||||||
|
(CONTROL_REPEAT | CONTROL_SLOW | CONTROL_DEBOUNCE | CONTROL_STICKY | \
|
||||||
|
CONTROL_MOUSEKEYS | CONTROL_MOUSEKEYS_ACCEL | CONTROL_AX | \
|
||||||
|
CONTROL_AX_TIMEOUT | CONTROL_AX_FEEDBACK | CONTROL_BELL | \
|
||||||
|
CONTROL_IGNORE_GROUP_LOCK)
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef uint32_t xkb_atom_t;
|
||||||
|
|
||||||
|
/* Don't allow more modifiers than we can hold in xkb_mod_mask_t. */
|
||||||
|
#define XKB_MAX_MODS ((xkb_mod_index_t) (sizeof(xkb_mod_mask_t) * 8))
|
||||||
|
|
||||||
|
/* These should all go away. */
|
||||||
|
enum mod_type {
|
||||||
|
MOD_REAL = (1 << 0),
|
||||||
|
MOD_VIRT = (1 << 1),
|
||||||
|
MOD_BOTH = (MOD_REAL | MOD_VIRT),
|
||||||
|
};
|
||||||
|
|
||||||
|
struct xkb_mod {
|
||||||
|
xkb_atom_t name;
|
||||||
|
enum mod_type type;
|
||||||
|
xkb_mod_mask_t mapping; /* vmod -> real mod mapping */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct xkb_mod_set {
|
||||||
|
struct xkb_mod mods[XKB_MAX_MODS];
|
||||||
|
unsigned int num_mods;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Common keyboard description structure */
|
||||||
|
struct xkb_keymap_real {
|
||||||
|
struct xkb_context *ctx;
|
||||||
|
|
||||||
|
int refcnt;
|
||||||
|
enum xkb_keymap_compile_flags flags;
|
||||||
|
enum xkb_keymap_format format;
|
||||||
|
|
||||||
|
enum xkb_action_controls enabled_ctrls;
|
||||||
|
|
||||||
|
xkb_keycode_t min_key_code;
|
||||||
|
xkb_keycode_t max_key_code;
|
||||||
|
void *keys;
|
||||||
|
|
||||||
|
/* aliases in no particular order */
|
||||||
|
unsigned int num_key_aliases;
|
||||||
|
void *key_aliases;
|
||||||
|
|
||||||
|
void *types;
|
||||||
|
unsigned int num_types;
|
||||||
|
|
||||||
|
unsigned int num_sym_interprets;
|
||||||
|
void *sym_interprets;
|
||||||
|
|
||||||
|
struct xkb_mod_set mods;
|
||||||
|
};
|
||||||
|
|
||||||
|
xkb_mod_mask_t
|
||||||
|
my_xkb_keymap_mod_get_mask(struct xkb_keymap *_keymap, xkb_mod_index_t idx)
|
||||||
|
{
|
||||||
|
struct xkb_keymap_real *keymap = (struct xkb_keymap_real *) _keymap;
|
||||||
|
|
||||||
|
if (idx >= keymap->mods.num_mods)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return keymap->mods.mods[idx].mapping;
|
||||||
|
}
|
34
src/core/xkbcommon-hacks.h
Normal file
34
src/core/xkbcommon-hacks.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Red Hat
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* Written by:
|
||||||
|
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef XKBCOMMON_HACKS_H
|
||||||
|
#define XKBCOMMON_HACKS_H
|
||||||
|
|
||||||
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
|
xkb_mod_mask_t
|
||||||
|
my_xkb_keymap_mod_get_mask(struct xkb_keymap *keymap, xkb_mod_index_t idx);
|
||||||
|
|
||||||
|
#endif /* XKBCOMMON_HACKS_H */
|
Loading…
Reference in New Issue
Block a user