Allow the user to bind more than one keycode to a keysym for Ob Menus/Move/Resize
authorDana Jansens <danakj@orodu.net>
Mon, 14 Dec 2009 20:40:09 +0000 (15:40 -0500)
committerDana Jansens <danakj@orodu.net>
Mon, 14 Dec 2009 20:40:33 +0000 (15:40 -0500)
If the user has escape bound to more than one keycode then they can use any of
them to close a menu.  This change applies to the hardcoded keys in openbox,
which are used for the menus and for move/resize, and maybe other places.

openbox/actions/cyclewindows.c
openbox/actions/directionalwindows.c
openbox/event.c
openbox/modkeys.c
openbox/modkeys.h
openbox/moveresize.c
openbox/openbox.c
openbox/openbox.h
openbox/prompt.c

index 6fba17f..32d6a45 100644 (file)
@@ -146,13 +146,13 @@ static gboolean i_input_func(guint initial_state,
 {
     if (e->type == KeyPress) {
         /* Escape cancels no matter what */
-        if (e->xkey.keycode == ob_keycode(OB_KEY_ESCAPE)) {
+        if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE)) {
             end_cycle(TRUE, e->xkey.state, options);
             return FALSE;
         }
 
         /* There were no modifiers and they pressed enter */
-        else if (e->xkey.keycode == ob_keycode(OB_KEY_RETURN) &&
+        else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RETURN) &&
                  !initial_state)
         {
             end_cycle(FALSE, e->xkey.state, options);
index d9f24d6..6559e44 100644 (file)
@@ -169,13 +169,13 @@ static gboolean i_input_func(guint initial_state,
 {
     if (e->type == KeyPress) {
         /* Escape cancels no matter what */
-        if (e->xkey.keycode == ob_keycode(OB_KEY_ESCAPE)) {
+        if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE)) {
             end_cycle(TRUE, e->xkey.state, options);
             return FALSE;
         }
 
         /* There were no modifiers and they pressed enter */
-        else if (e->xkey.keycode == ob_keycode(OB_KEY_RETURN) &&
+        else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RETURN) &&
                  !initial_state)
         {
             end_cycle(FALSE, e->xkey.state, options);
index b4bd827..881c9f8 100644 (file)
@@ -1693,30 +1693,30 @@ static gboolean event_handle_menu_keyboard(XEvent *ev)
     else if (ev->type == KeyPress && (state & ~ControlMask) == 0) {
         frame->got_press = TRUE;
 
-        if (keycode == ob_keycode(OB_KEY_ESCAPE)) {
+        if (ob_keycode_match(keycode, OB_KEY_ESCAPE)) {
             menu_frame_hide_all();
             ret = TRUE;
         }
 
-        else if (keycode == ob_keycode(OB_KEY_LEFT)) {
+        else if (ob_keycode_match(keycode, OB_KEY_LEFT)) {
             /* Left goes to the parent menu */
             if (frame->parent)
                 menu_frame_select(frame, NULL, TRUE);
             ret = TRUE;
         }
 
-        else if (keycode == ob_keycode(OB_KEY_RIGHT)) {
+        else if (ob_keycode_match(keycode, OB_KEY_RIGHT)) {
             /* Right goes to the selected submenu */
             if (frame->child) menu_frame_select_next(frame->child);
             ret = TRUE;
         }
 
-        else if (keycode == ob_keycode(OB_KEY_UP)) {
+        else if (ob_keycode_match(keycode, OB_KEY_UP)) {
             menu_frame_select_previous(frame);
             ret = TRUE;
         }
 
-        else if (keycode == ob_keycode(OB_KEY_DOWN)) {
+        else if (ob_keycode_match(keycode, OB_KEY_DOWN)) {
             menu_frame_select_next(frame);
             ret = TRUE;
         }
@@ -1729,7 +1729,7 @@ static gboolean event_handle_menu_keyboard(XEvent *ev)
     else if (ev->type == KeyRelease && (state & ~ControlMask) == 0 &&
              frame->entries && frame->got_press)
     {
-        if (keycode == ob_keycode(OB_KEY_RETURN)) {
+        if (ob_keycode_match(keycode, OB_KEY_RETURN)) {
             /* Enter runs the active item or goes into the submenu.
                Control-Enter runs it without closing the menu. */
             if (frame->child)
index c52cbef..e897ccb 100644 (file)
@@ -176,14 +176,22 @@ static void set_modkey_mask(guchar mask, KeySym sym)
     /* CapsLock, Shift, and Control are special and hard-coded */
 }
 
-KeyCode modkeys_sym_to_code(KeySym sym)
+KeyCode* modkeys_sym_to_code(KeySym sym)
 {
-    gint i, j;
+    KeyCode *ret;
+    gint i, j, n;
+
+    ret = g_new(KeyCode, 1);
+    n = 0;
+    ret[n] = 0;
 
     /* go through each keycode and look for the keysym */
     for (i = min_keycode; i <= max_keycode; ++i)
         for (j = 0; j < keysyms_per_keycode; ++j)
-            if (sym == keymap[(i-min_keycode) * keysyms_per_keycode + j])
-                return i;
-    return 0;
+            if (sym == keymap[(i-min_keycode) * keysyms_per_keycode + j]) {
+                ret = g_renew(KeyCode, ret, ++n);
+                ret[n-1] = i;
+                ret[n] = 0;
+            }
+    return ret;
 }
index dc72f28..8e795f7 100644 (file)
@@ -53,8 +53,7 @@ guint modkeys_only_modifier_masks(guint mask);
   right keys when there are both. */
 guint modkeys_key_to_mask(ObModkeysKey key);
 
-/*! Convert a KeySym to a KeyCode, because the X function is terrible - says
-  valgrind. */
-KeyCode modkeys_sym_to_code(KeySym sym);
+/*! Convert a KeySym to all the KeyCodes which generate it. */
+KeyCode* modkeys_sym_to_code(KeySym sym);
 
 #endif
index f324818..95d6473 100644 (file)
@@ -601,13 +601,13 @@ static void move_with_keys(gint keycode, gint state)
         gint x, y;
         ObDirection dir;
 
-        if (keycode == ob_keycode(OB_KEY_RIGHT))
+        if (ob_keycode_match(keycode, OB_KEY_RIGHT))
             dir = OB_DIRECTION_EAST;
-        else if (keycode == ob_keycode(OB_KEY_LEFT))
+        else if (ob_keycode_match(keycode, OB_KEY_LEFT))
             dir = OB_DIRECTION_WEST;
-        else if (keycode == ob_keycode(OB_KEY_DOWN))
+        else if (ob_keycode_match(keycode, OB_KEY_DOWN))
             dir = OB_DIRECTION_SOUTH;
-        else /* if (keycode == ob_keycode(OB_KEY_UP)) */
+        else /* if (ob_keycode_match(keycode, OB_KEY_UP)) */
             dir = OB_DIRECTION_NORTH;
 
         client_find_move_directional(moveresize_client, dir, &x, &y);
@@ -620,13 +620,13 @@ static void move_with_keys(gint keycode, gint state)
         else
             dist = KEY_DIST;
 
-        if (keycode == ob_keycode(OB_KEY_RIGHT))
+        if (ob_keycode_match(keycode, OB_KEY_RIGHT))
             dx = dist;
-        else if (keycode == ob_keycode(OB_KEY_LEFT))
+        else if (ob_keycode_match(keycode, OB_KEY_LEFT))
             dx = -dist;
-        else if (keycode == ob_keycode(OB_KEY_DOWN))
+        else if (ob_keycode_match(keycode, OB_KEY_DOWN))
             dy = dist;
-        else /* if (keycode == ob_keycode(OB_KEY_UP)) */
+        else /* if (ob_keycode_match(keycode, OB_KEY_UP)) */
             dy = -dist;
     }
 
@@ -659,7 +659,7 @@ static void resize_with_keys(gint keycode, gint state)
     ObDirection dir;
 
     /* pick the edge if it needs to move */
-    if (keycode == ob_keycode(OB_KEY_RIGHT)) {
+    if (ob_keycode_match(keycode, OB_KEY_RIGHT)) {
         dir = OB_DIRECTION_EAST;
         if (key_resize_edge != OB_DIRECTION_WEST &&
             key_resize_edge != OB_DIRECTION_EAST)
@@ -668,7 +668,7 @@ static void resize_with_keys(gint keycode, gint state)
             return;
         }
     }
-    if (keycode == ob_keycode(OB_KEY_LEFT)) {
+    if (ob_keycode_match(keycode, OB_KEY_LEFT)) {
         dir = OB_DIRECTION_WEST;
         if (key_resize_edge != OB_DIRECTION_WEST &&
             key_resize_edge != OB_DIRECTION_EAST)
@@ -677,7 +677,7 @@ static void resize_with_keys(gint keycode, gint state)
             return;
         }
     }
-    if (keycode == ob_keycode(OB_KEY_UP)) {
+    if (ob_keycode_match(keycode, OB_KEY_UP)) {
         dir = OB_DIRECTION_NORTH;
         if (key_resize_edge != OB_DIRECTION_NORTH &&
             key_resize_edge != OB_DIRECTION_SOUTH)
@@ -686,7 +686,7 @@ static void resize_with_keys(gint keycode, gint state)
             return;
         }
     }
-    if (keycode == ob_keycode(OB_KEY_DOWN)) {
+    if (ob_keycode_match(keycode, OB_KEY_DOWN)) {
         dir = OB_DIRECTION_SOUTH;
         if (key_resize_edge != OB_DIRECTION_NORTH &&
             key_resize_edge != OB_DIRECTION_SOUTH)
@@ -700,13 +700,13 @@ static void resize_with_keys(gint keycode, gint state)
     if (state & modkeys_key_to_mask(OB_MODKEY_KEY_SHIFT)) {
         gint x, y, w, h;
 
-        if (keycode == ob_keycode(OB_KEY_RIGHT))
+        if (ob_keycode_match(keycode, OB_KEY_RIGHT))
             dir = OB_DIRECTION_EAST;
-        else if (keycode == ob_keycode(OB_KEY_LEFT))
+        else if (ob_keycode_match(keycode, OB_KEY_LEFT))
             dir = OB_DIRECTION_WEST;
-        else if (keycode == ob_keycode(OB_KEY_DOWN))
+        else if (ob_keycode_match(keycode, OB_KEY_DOWN))
             dir = OB_DIRECTION_SOUTH;
-        else /* if (keycode == ob_keycode(OB_KEY_UP)) */
+        else /* if (ob_keycode_match(keycode, OB_KEY_UP)) */
             dir = OB_DIRECTION_NORTH;
 
         client_find_resize_directional(moveresize_client, key_resize_edge,
@@ -901,16 +901,16 @@ gboolean moveresize_event(XEvent *e)
         }
         used = TRUE;
     } else if (e->type == KeyPress) {
-        if (e->xkey.keycode == ob_keycode(OB_KEY_ESCAPE)) {
+        if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE)) {
             moveresize_end(TRUE);
             used = TRUE;
-        } else if (e->xkey.keycode == ob_keycode(OB_KEY_RETURN)) {
+        } else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RETURN)) {
             moveresize_end(FALSE);
             used = TRUE;
-        } else if (e->xkey.keycode == ob_keycode(OB_KEY_RIGHT) ||
-                   e->xkey.keycode == ob_keycode(OB_KEY_LEFT) ||
-                   e->xkey.keycode == ob_keycode(OB_KEY_DOWN) ||
-                   e->xkey.keycode == ob_keycode(OB_KEY_UP))
+        } else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RIGHT) ||
+                   ob_keycode_match(e->xkey.keycode, OB_KEY_LEFT) ||
+                   ob_keycode_match(e->xkey.keycode, OB_KEY_DOWN) ||
+                   ob_keycode_match(e->xkey.keycode, OB_KEY_UP))
         {
             if (corner == prop_atoms.net_wm_moveresize_size_keyboard) {
                 resize_with_keys(e->xkey.keycode, e->xkey.state);
index 60e147c..0e33978 100644 (file)
@@ -104,7 +104,7 @@ static gboolean  reconfigure = FALSE;
 static gboolean  restart = FALSE;
 static gchar    *restart_path = NULL;
 static Cursor    cursors[OB_NUM_CURSORS];
-static KeyCode   keys[OB_NUM_KEYS];
+static KeyCode  *keys[OB_NUM_KEYS];
 static gint      exitcode = 0;
 static guint     remote_control = 0;
 static gboolean  being_replaced = FALSE;
@@ -417,6 +417,17 @@ gint main(gint argc, gchar **argv)
             event_shutdown(reconfigure);
             config_shutdown();
             actions_shutdown(reconfigure);
+
+            /* Free the key codes for built in keys */
+            g_free(keys[OB_KEY_RETURN]);
+            g_free(keys[OB_KEY_ESCAPE]);
+            g_free(keys[OB_KEY_LEFT]);
+            g_free(keys[OB_KEY_RIGHT]);
+            g_free(keys[OB_KEY_UP]);
+            g_free(keys[OB_KEY_DOWN]);
+            g_free(keys[OB_KEY_TAB]);
+            g_free(keys[OB_KEY_SPACE]);
+
             modkeys_shutdown(reconfigure);
         } while (reconfigure);
     }
@@ -732,10 +743,14 @@ Cursor ob_cursor(ObCursor cursor)
     return cursors[cursor];
 }
 
-KeyCode ob_keycode(ObKey key)
+gboolean ob_keycode_match(KeyCode code, ObKey key)
 {
+    KeyCode *k;
+    
     g_assert(key < OB_NUM_KEYS);
-    return keys[key];
+    for (k = keys[key]; *k; ++k)
+        if (*k == code) return TRUE;
+    return FALSE;
 }
 
 ObState ob_state()
index 06d3829..76b04ea 100644 (file)
@@ -65,6 +65,6 @@ void ob_exit_with_error(const gchar *msg);
 
 Cursor ob_cursor(ObCursor cursor);
 
-KeyCode ob_keycode(ObKey key);
+gboolean ob_keycode_match(KeyCode code, ObKey key);
 
 #endif
index 53ed2d7..bef06a7 100644 (file)
@@ -532,23 +532,23 @@ gboolean prompt_key_event(ObPrompt *self, XEvent *e)
     if (e->xkey.state != 0 && e->xkey.state != shift_mask)
         return FALSE;
 
-    if (e->xkey.keycode == ob_keycode(OB_KEY_ESCAPE))
+    if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE))
         prompt_cancel(self);
-    else if (e->xkey.keycode == ob_keycode(OB_KEY_RETURN) ||
-             e->xkey.keycode == ob_keycode(OB_KEY_SPACE))
+    else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RETURN) ||
+             ob_keycode_match(e->xkey.keycode, OB_KEY_SPACE))
     {
         prompt_run_callback(self, self->focus->result);
     }
-    else if (e->xkey.keycode == ob_keycode(OB_KEY_TAB) ||
-             e->xkey.keycode == ob_keycode(OB_KEY_LEFT) ||
-             e->xkey.keycode == ob_keycode(OB_KEY_RIGHT))
+    else if (ob_keycode_match(e->xkey.keycode, OB_KEY_TAB) ||
+             ob_keycode_match(e->xkey.keycode, OB_KEY_LEFT) ||
+             ob_keycode_match(e->xkey.keycode, OB_KEY_RIGHT))
     {
         gint i;
         gboolean left;
         ObPromptElement *oldfocus;
 
-        left = e->xkey.keycode == ob_keycode(OB_KEY_LEFT) ||
-            (e->xkey.keycode == ob_keycode(OB_KEY_TAB) && shift);
+        left = ob_keycode_match(e->xkey.keycode, OB_KEY_LEFT) ||
+            (ob_keycode_match(e->xkey.keycode, OB_KEY_TAB) && shift);
         oldfocus = self->focus;
 
         for (i = 0; i < self->n_buttons; ++i)