]> Dogcows Code - chaz/openbox/commitdiff
make the modifier key code a lot better...
authorDana Jansens <danakj@orodu.net>
Fri, 4 May 2007 01:10:03 +0000 (01:10 +0000)
committerDana Jansens <danakj@orodu.net>
Fri, 4 May 2007 01:10:03 +0000 (01:10 +0000)
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..

Makefile.am
openbox/event.c
openbox/grab.c
openbox/modkeys.c [new file with mode: 0644]
openbox/modkeys.h [new file with mode: 0644]
openbox/openbox.c
openbox/translate.c

index e7802d486bc34249bad24e8b694e58664bf7f419..9bef49a53b342360385a0185704dfe09ede185a6 100644 (file)
@@ -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 \
index cbc9aaf8a9e6af37c0fd7f87efa707d93278a936..d4ac2176e0e408ae580ae92c7b8bcac7ba0b5190 100644 (file)
@@ -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;
index eaf65f6be9765b8ec539158b86500df581a75027..3e1066ba0f31eda4379ce8321778123c2047a4c6 100644 (file)
@@ -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);
 }
 
diff --git a/openbox/modkeys.c b/openbox/modkeys.c
new file mode 100644 (file)
index 0000000..4f0ddca
--- /dev/null
@@ -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;
+}
diff --git a/openbox/modkeys.h b/openbox/modkeys.h
new file mode 100644 (file)
index 0000000..cfa95b0
--- /dev/null
@@ -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
index 9de780dd47aa4d07999ef175ea6349265c1967ab..052929a5b5f9df36f93c8e400d3d27225e76a528 100644 (file)
@@ -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);
     }
 
index a7cac55721328e0da76eeb14bfc272ccde86172e..1ef8e7d58ed4b17dd81a268bc4e1818c8d5800f1 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "openbox.h"
 #include "mouse.h"
+#include "modkeys.h"
 #include "gettext.h"
 #include <glib.h>
 #include <string.h>
 
 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)
This page took 0.039057 seconds and 4 git commands to generate.