i3 - improved tiling WM


Move keyboard binding accessor to bindings.[ch]

Patch status: merged

Patch by Tony Crisci

Long description:

Rename `get_binding` to `get_keyboard_binding` and ensure that this
function only accesses bindings of type B_KEYBOARD. Other types of
bindings (e.g. mouse bindings) will be accessed by a different function.

To apply this patch, use:
curl http://cr.i3wm.org/patch/432/raw.patch | git am

b/include/bindings.h

20
@@ -29,3 +29,10 @@ Binding *configure_binding(const char *bindtype, const char *modifiers, const ch
21
  *
22
  */
23
 void grab_all_keys(xcb_connection_t *conn, bool bind_mode_switch);
24
+
25
+/**
26
+ * Returns a pointer to the keyboard Binding with the specified modifiers and
27
+ * keycode or NULL if no such binding exists.
28
+ *
29
+ */
30
+Binding *get_keyboard_binding(uint16_t modifiers, bool key_release, xcb_keycode_t keycode);

b/include/config.h

35
@@ -334,13 +334,6 @@ void switch_mode(const char *new_mode);
36
  */void update_barconfig();
37
 
38
 /**
39
- * Returns a pointer to the Binding with the specified modifiers and keycode
40
- * or NULL if no such binding exists.
41
- *
42
- */
43
-Binding *get_binding(uint16_t modifiers, bool key_release, xcb_keycode_t keycode);
44
-
45
-/**
46
  * Kills the configerror i3-nagbar process, if any.
47
  *
48
  * Called when reloading/restarting.

b/src/bindings.c

53
@@ -117,3 +117,65 @@ void grab_all_keys(xcb_connection_t *conn, bool bind_mode_switch) {
54
             grab_keycode_for_binding(conn, bind, *walk++);
55
     }
56
 }
57
+
58
+/*
59
+ * Returns a pointer to the keyboard Binding with the specified modifiers and
60
+ * keycode or NULL if no such binding exists.
61
+ *
62
+ */
63
+Binding *get_keyboard_binding(uint16_t modifiers, bool key_release, xcb_keycode_t keycode) {
64
+    Binding *bind;
65
+
66
+    if (!key_release) {
67
+        /* On a KeyPress event, we first reset all
68
+         * B_UPON_KEYRELEASE_IGNORE_MODS bindings back to B_UPON_KEYRELEASE */
69
+        TAILQ_FOREACH(bind, bindings, bindings) {
70
+            if (bind->input_type != B_KEYBOARD)
71
+                continue;
72
+            if (bind->release == B_UPON_KEYRELEASE_IGNORE_MODS)
73
+                bind->release = B_UPON_KEYRELEASE;
74
+        }
75
+    }
76
+
77
+    TAILQ_FOREACH(bind, bindings, bindings) {
78
+        /* First compare the modifiers (unless this is a
79
+         * B_UPON_KEYRELEASE_IGNORE_MODS binding and this is a KeyRelease
80
+         * event) */
81
+        if (bind->input_type != B_KEYBOARD)
82
+            continue;
83
+        if (bind->mods != modifiers &&
84
+            (bind->release != B_UPON_KEYRELEASE_IGNORE_MODS ||
85
+             !key_release))
86
+            continue;
87
+
88
+        /* If a symbol was specified by the user, we need to look in
89
+         * the array of translated keycodes for the event’s keycode */
90
+        if (bind->symbol != NULL) {
91
+            if (memmem(bind->translated_to,
92
+                       bind->number_keycodes * sizeof(xcb_keycode_t),
93
+                       &keycode, sizeof(xcb_keycode_t)) == NULL)
94
+                continue;
95
+        } else {
96
+            /* This case is easier: The user specified a keycode */
97
+            if (bind->keycode != keycode)
98
+                continue;
99
+        }
100
+
101
+        /* If this keybinding is a KeyRelease binding, it matches the key which
102
+         * the user pressed. We therefore mark it as
103
+         * B_UPON_KEYRELEASE_IGNORE_MODS for later, so that the user can
104
+         * release the modifiers before the actual key and the KeyRelease will
105
+         * still be matched. */
106
+        if (bind->release == B_UPON_KEYRELEASE && !key_release)
107
+            bind->release = B_UPON_KEYRELEASE_IGNORE_MODS;
108
+
109
+        /* Check if the binding is for a KeyPress or a KeyRelease event */
110
+        if ((bind->release == B_UPON_KEYPRESS && key_release) ||
111
+            (bind->release >= B_UPON_KEYRELEASE && !key_release))
112
+            continue;
113
+
114
+        break;
115
+    }
116
+
117
+    return (bind == TAILQ_END(bindings) ? NULL : bind);
118
+}

b/src/config.c

123
@@ -31,64 +31,6 @@ void ungrab_all_keys(xcb_connection_t *conn) {
124
 }
125
 
126
 /*
127
- * Returns a pointer to the Binding with the specified modifiers and keycode
128
- * or NULL if no such binding exists.
129
- *
130
- */
131
-Binding *get_binding(uint16_t modifiers, bool key_release, xcb_keycode_t keycode) {
132
-    Binding *bind;
133
-
134
-    if (!key_release) {
135
-        /* On a KeyPress event, we first reset all
136
-         * B_UPON_KEYRELEASE_IGNORE_MODS bindings back to B_UPON_KEYRELEASE */
137
-        TAILQ_FOREACH(bind, bindings, bindings) {
138
-            if (bind->release == B_UPON_KEYRELEASE_IGNORE_MODS)
139
-                bind->release = B_UPON_KEYRELEASE;
140
-        }
141
-    }
142
-
143
-    TAILQ_FOREACH(bind, bindings, bindings) {
144
-        /* First compare the modifiers (unless this is a
145
-         * B_UPON_KEYRELEASE_IGNORE_MODS binding and this is a KeyRelease
146
-         * event) */
147
-        if (bind->mods != modifiers &&
148
-            (bind->release != B_UPON_KEYRELEASE_IGNORE_MODS ||
149
-             !key_release))
150
-            continue;
151
-
152
-        /* If a symbol was specified by the user, we need to look in
153
-         * the array of translated keycodes for the event’s keycode */
154
-        if (bind->symbol != NULL) {
155
-            if (memmem(bind->translated_to,
156
-                       bind->number_keycodes * sizeof(xcb_keycode_t),
157
-                       &keycode, sizeof(xcb_keycode_t)) == NULL)
158
-                continue;
159
-        } else {
160
-            /* This case is easier: The user specified a keycode */
161
-            if (bind->keycode != keycode)
162
-                continue;
163
-        }
164
-
165
-        /* If this keybinding is a KeyRelease binding, it matches the key which
166
-         * the user pressed. We therefore mark it as
167
-         * B_UPON_KEYRELEASE_IGNORE_MODS for later, so that the user can
168
-         * release the modifiers before the actual key and the KeyRelease will
169
-         * still be matched. */
170
-        if (bind->release == B_UPON_KEYRELEASE && !key_release)
171
-            bind->release = B_UPON_KEYRELEASE_IGNORE_MODS;
172
-
173
-        /* Check if the binding is for a KeyPress or a KeyRelease event */
174
-        if ((bind->release == B_UPON_KEYPRESS && key_release) ||
175
-            (bind->release >= B_UPON_KEYRELEASE && !key_release))
176
-            continue;
177
-
178
-        break;
179
-    }
180
-
181
-    return (bind == TAILQ_END(bindings) ? NULL : bind);
182
-}
183
-
184
-/*
185
  * Translates keysymbols to keycodes for all bindings which use keysyms.
186
  *
187
  */

b/src/key_press.c

192
@@ -84,7 +84,7 @@ void handle_key_press(xcb_key_press_event_t *event) {
193
     DLOG("(checked mode_switch, state %d)\n", state_filtered);
194
 
195
     /* Find the binding */
196
-    Binding *bind = get_binding(state_filtered, key_release, event->detail);
197
+    Binding *bind = get_keyboard_binding(state_filtered, key_release, event->detail);
198
 
199
     /* No match? Then the user has Mode_switch enabled but does not have a
200
      * specific keybinding. Fall back to the default keybindings (without
201
@@ -93,7 +93,7 @@ void handle_key_press(xcb_key_press_event_t *event) {
202
     if (bind == NULL) {
203
         state_filtered &= ~(BIND_MODE_SWITCH);
204
         DLOG("no match, new state_filtered = %d\n", state_filtered);
205
-        if ((bind = get_binding(state_filtered, key_release, event->detail)) == NULL) {
206
+        if ((bind = get_keyboard_binding(state_filtered, key_release, event->detail)) == NULL) {
207
             /* This is not a real error since we can have release and
208
              * non-release keybindings. On a KeyPress event for which there is
209
              * only a !release-binding, but no release-binding, the