make the modifier key code a lot better...
1) it can handle more user cases. 2) it can handle binding more modifier keys with their keysym names like Hyper and Super. W is a shortcut for Super, cuz the windows key is generally bound to it. 3) if you change your keymap bindings and reconfigure openbox it will learn your changes. and i dunno.. its just nice and stuff now.. you can actually read it I think..
This commit is contained in:
parent
5784f11132
commit
7e946f68d9
7 changed files with 243 additions and 87 deletions
|
@ -182,6 +182,8 @@ openbox_openbox_SOURCES = \
|
|||
openbox/menu.c \
|
||||
openbox/menu.h \
|
||||
openbox/misc.h \
|
||||
openbox/modkeys.c \
|
||||
openbox/modkeys.h \
|
||||
openbox/mouse.c \
|
||||
openbox/mouse.h \
|
||||
openbox/moveresize.c \
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "menu.h"
|
||||
#include "menuframe.h"
|
||||
#include "keyboard.h"
|
||||
#include "modkeys.h"
|
||||
#include "mouse.h"
|
||||
#include "mainloop.h"
|
||||
#include "framerender.h"
|
||||
|
@ -93,21 +94,7 @@ static gboolean menu_hide_delay_func(gpointer data);
|
|||
/* The time for the current event being processed */
|
||||
Time event_curtime = CurrentTime;
|
||||
|
||||
/*! The value of the mask for the NumLock modifier */
|
||||
guint NumLockMask;
|
||||
/*! The value of the mask for the ScrollLock modifier */
|
||||
guint ScrollLockMask;
|
||||
/*! The key codes for the modifier keys */
|
||||
static XModifierKeymap *modmap;
|
||||
/*! Table of the constant modifier masks */
|
||||
static const gint mask_table[] = {
|
||||
ShiftMask, LockMask, ControlMask, Mod1Mask,
|
||||
Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
|
||||
};
|
||||
static gint mask_table_size;
|
||||
|
||||
static guint ignore_enter_focus = 0;
|
||||
|
||||
static gboolean menu_can_hide;
|
||||
|
||||
#ifdef USE_SM
|
||||
|
@ -136,31 +123,6 @@ void event_startup(gboolean reconfig)
|
|||
{
|
||||
if (reconfig) return;
|
||||
|
||||
mask_table_size = sizeof(mask_table) / sizeof(mask_table[0]);
|
||||
|
||||
/* get lock masks that are defined by the display (not constant) */
|
||||
modmap = XGetModifierMapping(ob_display);
|
||||
g_assert(modmap);
|
||||
if (modmap && modmap->max_keypermod > 0) {
|
||||
size_t cnt;
|
||||
const size_t size = mask_table_size * modmap->max_keypermod;
|
||||
/* get the values of the keyboard lock modifiers
|
||||
Note: Caps lock is not retrieved the same way as Scroll and Num
|
||||
lock since it doesn't need to be. */
|
||||
const KeyCode num_lock = XKeysymToKeycode(ob_display, XK_Num_Lock);
|
||||
const KeyCode scroll_lock = XKeysymToKeycode(ob_display,
|
||||
XK_Scroll_Lock);
|
||||
|
||||
for (cnt = 0; cnt < size; ++cnt) {
|
||||
if (! modmap->modifiermap[cnt]) continue;
|
||||
|
||||
if (num_lock == modmap->modifiermap[cnt])
|
||||
NumLockMask = mask_table[cnt / modmap->max_keypermod];
|
||||
if (scroll_lock == modmap->modifiermap[cnt])
|
||||
ScrollLockMask = mask_table[cnt / modmap->max_keypermod];
|
||||
}
|
||||
}
|
||||
|
||||
ob_main_loop_x_add(ob_main_loop, event_process, NULL, NULL);
|
||||
|
||||
#ifdef USE_SM
|
||||
|
@ -179,7 +141,6 @@ void event_shutdown(gboolean reconfig)
|
|||
#endif
|
||||
|
||||
client_remove_destructor(focus_delay_client_dest);
|
||||
XFreeModifiermap(modmap);
|
||||
}
|
||||
|
||||
static Window event_get_window(XEvent *e)
|
||||
|
@ -271,54 +232,34 @@ static void event_set_curtime(XEvent *e)
|
|||
event_curtime = t;
|
||||
}
|
||||
|
||||
#define STRIP_MODS(s) \
|
||||
s &= ~(LockMask | NumLockMask | ScrollLockMask), \
|
||||
/* kill off the Button1Mask etc, only want the modifiers */ \
|
||||
s &= (ControlMask | ShiftMask | Mod1Mask | \
|
||||
Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask) \
|
||||
|
||||
static void event_hack_mods(XEvent *e)
|
||||
{
|
||||
#ifdef XKB
|
||||
XkbStateRec xkb_state;
|
||||
#endif
|
||||
KeyCode *kp;
|
||||
gint i, k;
|
||||
|
||||
switch (e->type) {
|
||||
case ButtonPress:
|
||||
case ButtonRelease:
|
||||
STRIP_MODS(e->xbutton.state);
|
||||
e->xbutton.state = modkeys_only_modifier_masks(e->xbutton.state);
|
||||
break;
|
||||
case KeyPress:
|
||||
STRIP_MODS(e->xkey.state);
|
||||
e->xkey.state = modkeys_only_modifier_masks(e->xkey.state);
|
||||
break;
|
||||
case KeyRelease:
|
||||
STRIP_MODS(e->xkey.state);
|
||||
/* remove from the state the mask of the modifier being released, if
|
||||
it is a modifier key being released (this is a little ugly..) */
|
||||
e->xkey.state = modkeys_only_modifier_masks(e->xkey.state);
|
||||
#ifdef XKB
|
||||
if (XkbGetState(ob_display, XkbUseCoreKbd, &xkb_state) == Success) {
|
||||
e->xkey.state = xkb_state.compat_state;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
kp = modmap->modifiermap;
|
||||
for (i = 0; i < mask_table_size; ++i) {
|
||||
for (k = 0; k < modmap->max_keypermod; ++k) {
|
||||
if (*kp == e->xkey.keycode) { /* found the keycode */
|
||||
/* remove the mask for it */
|
||||
e->xkey.state &= ~mask_table[i];
|
||||
/* cause the first loop to break; */
|
||||
i = mask_table_size;
|
||||
break; /* get outta here! */
|
||||
}
|
||||
++kp;
|
||||
}
|
||||
}
|
||||
/* remove from the state the mask of the modifier key being released,
|
||||
if it is a modifier key being released that is */
|
||||
e->xkey.state &= ~modkeys_keycode_to_mask(e->xkey.keycode);
|
||||
break;
|
||||
case MotionNotify:
|
||||
STRIP_MODS(e->xmotion.state);
|
||||
e->xmotion.state = modkeys_only_modifier_masks(e->xmotion.state);
|
||||
/* compress events */
|
||||
{
|
||||
XEvent ce;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
#include "grab.h"
|
||||
#include "modkeys.h"
|
||||
#include "openbox.h"
|
||||
#include "event.h"
|
||||
#include "xerror.h"
|
||||
|
@ -135,17 +136,20 @@ gint grab_server(gboolean grab)
|
|||
void grab_startup(gboolean reconfig)
|
||||
{
|
||||
guint i = 0;
|
||||
guint num, caps, scroll;
|
||||
|
||||
if (reconfig) return;
|
||||
num = modkeys_key_to_mask(OB_MODKEY_KEY_NUMLOCK);
|
||||
caps = modkeys_key_to_mask(OB_MODKEY_KEY_CAPSLOCK);
|
||||
scroll = modkeys_key_to_mask(OB_MODKEY_KEY_SCROLLLOCK);
|
||||
|
||||
mask_list[i++] = 0;
|
||||
mask_list[i++] = LockMask;
|
||||
mask_list[i++] = NumLockMask;
|
||||
mask_list[i++] = LockMask | NumLockMask;
|
||||
mask_list[i++] = ScrollLockMask;
|
||||
mask_list[i++] = ScrollLockMask | LockMask;
|
||||
mask_list[i++] = ScrollLockMask | NumLockMask;
|
||||
mask_list[i++] = ScrollLockMask | LockMask | NumLockMask;
|
||||
mask_list[i++] = num;
|
||||
mask_list[i++] = caps;
|
||||
mask_list[i++] = scroll;
|
||||
mask_list[i++] = num | caps;
|
||||
mask_list[i++] = num | scroll;
|
||||
mask_list[i++] = caps | scroll;
|
||||
mask_list[i++] = num | caps | scroll;
|
||||
g_assert(i == MASK_LIST_SIZE);
|
||||
}
|
||||
|
||||
|
|
133
openbox/modkeys.c
Normal file
133
openbox/modkeys.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
|
||||
|
||||
modkeys.c for the Openbox window manager
|
||||
Copyright (c) 2007 Dana Jansens
|
||||
|
||||
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.
|
||||
|
||||
See the COPYING file for a copy of the GNU General Public License.
|
||||
*/
|
||||
|
||||
#include "modkeys.h"
|
||||
#include "openbox.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
/* These masks are constants and the modifier keys are bound to them as
|
||||
anyone sees fit:
|
||||
ShiftMask (1<<0), LockMask (1<<1), ControlMask (1<<2), Mod1Mask (1<<3),
|
||||
Mod2Mask (1<<4), Mod3Mask (1<<5), Mod4Mask (1<<6), Mod5Mask (1<<7)
|
||||
*/
|
||||
#define NUM_MASKS 8
|
||||
#define ALL_MASKS 0xf /* an or'ing of all 8 keyboard masks */
|
||||
|
||||
/* Get the bitflag for the n'th modifier mask */
|
||||
#define nth_mask(n) (1 << n)
|
||||
|
||||
static void set_modkey_mask(guchar mask, KeySym sym);
|
||||
|
||||
static XModifierKeymap *modmap;
|
||||
/* This is a bitmask of the different masks for each modifier key */
|
||||
static guchar modkeys_keys[OB_MODKEY_NUM_KEYS];
|
||||
|
||||
void modkeys_startup(gboolean reconfigure)
|
||||
{
|
||||
/* keycodes for the modifier keys which will be bound to the masks */
|
||||
gint i, j, k;
|
||||
|
||||
modmap = XGetModifierMapping(ob_display);
|
||||
g_assert(modmap->max_keypermod > 0);
|
||||
|
||||
/* reset the keys to not be bound to any masks */
|
||||
for (i = 0; i < OB_MODKEY_NUM_KEYS; ++i)
|
||||
modkeys_keys[i] = 0;
|
||||
|
||||
/* go through each of the modifier masks (eg ShiftMask, CapsMask...) */
|
||||
for (i = 0; i < NUM_MASKS; ++i) {
|
||||
/* go through each keycode that is bound to the mask */
|
||||
for (j = 0; j < modmap->max_keypermod; ++j) {
|
||||
KeySym sym;
|
||||
/* get a keycode that is bound to the mask (i) */
|
||||
KeyCode keycode = modmap->modifiermap[i*modmap->max_keypermod + j];
|
||||
/* go through each keysym bound to the given keycode */
|
||||
for (k = 0; ; ++k) {
|
||||
sym = XKeycodeToKeysym(ob_display, keycode, k);
|
||||
if (sym == NoSymbol) break;
|
||||
|
||||
/* bind the key to the mask (e.g. Alt_L => Mod1Mask) */
|
||||
set_modkey_mask(nth_mask(i), sym);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void modkeys_shutdown(gboolean reconfigure)
|
||||
{
|
||||
XFreeModifiermap(modmap);
|
||||
}
|
||||
|
||||
guint modkeys_keycode_to_mask(guint keycode)
|
||||
{
|
||||
gint i, j;
|
||||
guint mask = 0;
|
||||
|
||||
if (keycode == NoSymbol) return 0;
|
||||
|
||||
/* go through each of the modifier masks (eg ShiftMask, CapsMask...) */
|
||||
for (i = 0; i < NUM_MASKS; ++i) {
|
||||
/* go through each keycode that is bound to the mask */
|
||||
for (j = 0; j < modmap->max_keypermod; ++j) {
|
||||
/* compare with a keycode that is bound to the mask (i) */
|
||||
if (modmap->modifiermap[i*modmap->max_keypermod + j] == keycode)
|
||||
mask |= nth_mask(i);
|
||||
}
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
guint modkeys_only_modifier_masks(guint mask)
|
||||
{
|
||||
mask &= ALL_MASKS;
|
||||
/* strip off these lock keys. they shouldn't affect key bindings */
|
||||
mask &= ~modkeys_key_to_mask(OB_MODKEY_KEY_CAPSLOCK);
|
||||
mask &= ~modkeys_key_to_mask(OB_MODKEY_KEY_NUMLOCK);
|
||||
mask &= ~modkeys_key_to_mask(OB_MODKEY_KEY_SCROLLLOCK);
|
||||
return mask;
|
||||
}
|
||||
|
||||
guint modkeys_key_to_mask(ObModkeysKey key)
|
||||
{
|
||||
return modkeys_keys[key];
|
||||
}
|
||||
|
||||
static void set_modkey_mask(guchar mask, KeySym sym)
|
||||
{
|
||||
/* find what key this is, and bind it to the mask */
|
||||
|
||||
if (sym == XK_Num_Lock)
|
||||
modkeys_keys[OB_MODKEY_KEY_NUMLOCK] |= mask;
|
||||
else if (sym == XK_Scroll_Lock)
|
||||
modkeys_keys[OB_MODKEY_KEY_SCROLLLOCK] |= mask;
|
||||
else if (sym == XK_Caps_Lock)
|
||||
modkeys_keys[OB_MODKEY_KEY_CAPSLOCK] |= mask;
|
||||
else if (sym == XK_Shift_L || sym == XK_Shift_R)
|
||||
modkeys_keys[OB_MODKEY_KEY_SHIFT] |= mask;
|
||||
else if (sym == XK_Control_L || sym == XK_Control_R)
|
||||
modkeys_keys[OB_MODKEY_KEY_CONTROL] |= mask;
|
||||
else if (sym == XK_Super_L || sym == XK_Super_R)
|
||||
modkeys_keys[OB_MODKEY_KEY_SUPER] |= mask;
|
||||
else if (sym == XK_Hyper_L || sym == XK_Hyper_R)
|
||||
modkeys_keys[OB_MODKEY_KEY_HYPER] |= mask;
|
||||
else if (sym == XK_Alt_L || sym == XK_Alt_R)
|
||||
modkeys_keys[OB_MODKEY_KEY_ALT] |= mask;
|
||||
else if (sym == XK_Meta_L || sym == XK_Meta_R)
|
||||
modkeys_keys[OB_MODKEY_KEY_META] |= mask;
|
||||
}
|
54
openbox/modkeys.h
Normal file
54
openbox/modkeys.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
|
||||
|
||||
masks.h for the Openbox window manager
|
||||
Copyright (c) 2007 Dana Jansens
|
||||
|
||||
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.
|
||||
|
||||
See the COPYING file for a copy of the GNU General Public License.
|
||||
*/
|
||||
|
||||
#ifndef ob__modkeys_h
|
||||
#define ob__modkeys_h
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
/*! These keys are bound to the modifier masks in any fashion */
|
||||
typedef enum {
|
||||
OB_MODKEY_KEY_CAPSLOCK,
|
||||
OB_MODKEY_KEY_NUMLOCK,
|
||||
OB_MODKEY_KEY_SCROLLLOCK,
|
||||
OB_MODKEY_KEY_SHIFT,
|
||||
OB_MODKEY_KEY_CONTROL,
|
||||
OB_MODKEY_KEY_SUPER,
|
||||
OB_MODKEY_KEY_HYPER,
|
||||
OB_MODKEY_KEY_META,
|
||||
OB_MODKEY_KEY_ALT,
|
||||
|
||||
OB_MODKEY_NUM_KEYS
|
||||
} ObModkeysKey;
|
||||
|
||||
void modkeys_startup(gboolean reconfigure);
|
||||
void modkeys_shutdown(gboolean reconfigure);
|
||||
|
||||
/*! Get the modifier masks for a keycode. (eg. a keycode bound to Alt_L could
|
||||
return a mask of (Mod1Mask | Mask3Mask)) */
|
||||
guint modkeys_keycode_to_mask(guint keycode);
|
||||
|
||||
/*! Strip off all modifiers except for the modifier keys. This strips stuff
|
||||
like Button1Mask, and also LockMask, NumLockMask, and ScrollLockMask */
|
||||
guint modkeys_only_modifier_masks(guint mask);
|
||||
|
||||
/*! Get the modifier masks for a modifier key. This includes both the left and
|
||||
right keys when there are both. */
|
||||
guint modkeys_key_to_mask(ObModkeysKey key);
|
||||
|
||||
#endif
|
|
@ -21,6 +21,7 @@
|
|||
#include "openbox.h"
|
||||
#include "session.h"
|
||||
#include "dock.h"
|
||||
#include "modkeys.h"
|
||||
#include "event.h"
|
||||
#include "menu.h"
|
||||
#include "client.h"
|
||||
|
@ -215,6 +216,8 @@ gint main(gint argc, gchar **argv)
|
|||
xmlDocPtr doc;
|
||||
xmlNodePtr node;
|
||||
|
||||
modkeys_startup(reconfigure);
|
||||
|
||||
/* startup the parsing so everything can register sections
|
||||
of the rc */
|
||||
i = parse_startup();
|
||||
|
@ -320,6 +323,7 @@ gint main(gint argc, gchar **argv)
|
|||
window_shutdown(reconfigure);
|
||||
event_shutdown(reconfigure);
|
||||
config_shutdown();
|
||||
modkeys_shutdown(reconfigure);
|
||||
} while (reconfigure);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "openbox.h"
|
||||
#include "mouse.h"
|
||||
#include "modkeys.h"
|
||||
#include "gettext.h"
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
|
@ -26,20 +27,37 @@
|
|||
|
||||
static guint translate_modifier(gchar *str)
|
||||
{
|
||||
if (!g_ascii_strcasecmp("Mod1", str) ||
|
||||
!g_ascii_strcasecmp("A", str)) return Mod1Mask;
|
||||
else if (!g_ascii_strcasecmp("Mod2", str)) return Mod2Mask;
|
||||
else if (!g_ascii_strcasecmp("Mod3", str) ||
|
||||
!g_ascii_strcasecmp("M", str)) return Mod3Mask;
|
||||
else if (!g_ascii_strcasecmp("Mod4", str) ||
|
||||
!g_ascii_strcasecmp("W", str)) return Mod4Mask;
|
||||
else if (!g_ascii_strcasecmp("Mod5", str)) return Mod5Mask;
|
||||
guint mask = 0;
|
||||
|
||||
if (!g_ascii_strcasecmp("Mod1", str)) mask = Mod1Mask;
|
||||
else if (!g_ascii_strcasecmp("Mod2", str)) mask = Mod2Mask;
|
||||
else if (!g_ascii_strcasecmp("Mod3", str)) mask = Mod3Mask;
|
||||
else if (!g_ascii_strcasecmp("Mod4", str)) mask = Mod4Mask;
|
||||
else if (!g_ascii_strcasecmp("Mod5", str)) mask = Mod5Mask;
|
||||
|
||||
else if (!g_ascii_strcasecmp("Control", str) ||
|
||||
!g_ascii_strcasecmp("C", str)) return ControlMask;
|
||||
!g_ascii_strcasecmp("C", str))
|
||||
mask = modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL);
|
||||
else if (!g_ascii_strcasecmp("Alt", str) ||
|
||||
!g_ascii_strcasecmp("A", str))
|
||||
mask = modkeys_key_to_mask(OB_MODKEY_KEY_ALT);
|
||||
else if (!g_ascii_strcasecmp("Meta", str) ||
|
||||
!g_ascii_strcasecmp("M", str))
|
||||
mask = modkeys_key_to_mask(OB_MODKEY_KEY_META);
|
||||
/* W = windows key, is linked to the Super_L/R buttons */
|
||||
else if (!g_ascii_strcasecmp("Super", str) ||
|
||||
!g_ascii_strcasecmp("W", str))
|
||||
mask = modkeys_key_to_mask(OB_MODKEY_KEY_SUPER);
|
||||
else if (!g_ascii_strcasecmp("Shift", str) ||
|
||||
!g_ascii_strcasecmp("S", str)) return ShiftMask;
|
||||
g_message(_("Invalid modifier key '%s' in key/pointer binding"), str);
|
||||
return 0;
|
||||
!g_ascii_strcasecmp("S", str))
|
||||
mask = modkeys_key_to_mask(OB_MODKEY_KEY_SHIFT);
|
||||
else if (!g_ascii_strcasecmp("Hyper", str) ||
|
||||
!g_ascii_strcasecmp("H", str))
|
||||
mask = modkeys_key_to_mask(OB_MODKEY_KEY_HYPER);
|
||||
else
|
||||
g_message(_("Invalid modifier key '%s' in key/pointer binding"), str);
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
gboolean translate_button(const gchar *str, guint *state, guint *button)
|
||||
|
|
Loading…
Reference in a new issue