diff options
author | Tony Crisci <tony@dubstepdish.com> | 2017-12-28 14:51:17 -0500 |
---|---|---|
committer | Tony Crisci <tony@dubstepdish.com> | 2017-12-28 16:24:23 -0500 |
commit | 8d567cd06202b4d68bf45af6e76e5bdc49bfffee (patch) | |
tree | 55ffcc2f5d47ee7de17cf2bd8dee2491d48ebc7e | |
parent | run compositor bindings last (diff) | |
download | sway-8d567cd06202b4d68bf45af6e76e5bdc49bfffee.tar.gz sway-8d567cd06202b4d68bf45af6e76e5bdc49bfffee.tar.zst sway-8d567cd06202b4d68bf45af6e76e5bdc49bfffee.zip |
bindcode
-rw-r--r-- | sway/input/keyboard.c | 128 |
1 files changed, 106 insertions, 22 deletions
diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index 032083e9..2464db12 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c | |||
@@ -26,7 +26,6 @@ static ssize_t pressed_keysyms_index(xkb_keysym_t *pressed_keysyms, | |||
26 | return -1; | 26 | return -1; |
27 | } | 27 | } |
28 | 28 | ||
29 | |||
30 | /** | 29 | /** |
31 | * Execute a built-in, hardcoded compositor binding. These are triggered from a | 30 | * Execute a built-in, hardcoded compositor binding. These are triggered from a |
32 | * single keysym. | 31 | * single keysym. |
@@ -56,8 +55,7 @@ static bool keyboard_execute_compositor_binding(struct sway_keyboard *keyboard, | |||
56 | } | 55 | } |
57 | 56 | ||
58 | /** | 57 | /** |
59 | * Execute keyboard bindings. These include compositor bindings and user-defined | 58 | * Execute keyboard bindings bound with `bindysm`. |
60 | * bindings. | ||
61 | * | 59 | * |
62 | * Returns true if the keysym was handled by a binding and false if the event | 60 | * Returns true if the keysym was handled by a binding and false if the event |
63 | * should be propagated to clients. | 61 | * should be propagated to clients. |
@@ -99,7 +97,110 @@ static bool keyboard_execute_bindsym(struct sway_keyboard *keyboard, | |||
99 | return false; | 97 | return false; |
100 | } | 98 | } |
101 | 99 | ||
102 | /* | 100 | static bool keysym_is_modifier(xkb_keysym_t keysym) { |
101 | switch (keysym) { | ||
102 | case XKB_KEY_Shift_L: case XKB_KEY_Shift_R: | ||
103 | case XKB_KEY_Control_L: case XKB_KEY_Control_R: | ||
104 | case XKB_KEY_Caps_Lock: | ||
105 | case XKB_KEY_Shift_Lock: | ||
106 | case XKB_KEY_Meta_L: case XKB_KEY_Meta_R: | ||
107 | case XKB_KEY_Alt_L: case XKB_KEY_Alt_R: | ||
108 | case XKB_KEY_Super_L: case XKB_KEY_Super_R: | ||
109 | case XKB_KEY_Hyper_L: case XKB_KEY_Hyper_R: | ||
110 | return true; | ||
111 | default: | ||
112 | return false; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | static bool binding_matches_keycodes(struct wlr_keyboard *keyboard, | ||
117 | struct sway_binding *binding) { | ||
118 | uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard); | ||
119 | if (modifiers ^ binding->modifiers) { | ||
120 | return false; | ||
121 | } | ||
122 | |||
123 | // every keycode in the binding must be present in the pressed keys on the | ||
124 | // keyboard | ||
125 | for (int i = 0; i < binding->keys->length; ++i) { | ||
126 | uint32_t binding_keycode = *(uint32_t*)binding->keys->items[i] + 8; | ||
127 | bool found = false; | ||
128 | for (size_t j = 0; j < keyboard->num_keycodes; ++j) { | ||
129 | xkb_keycode_t keycode = keyboard->keycodes[j] + 8; | ||
130 | if (keycode == binding_keycode) { | ||
131 | found = true; | ||
132 | break; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | if (!found) { | ||
137 | return false; | ||
138 | } | ||
139 | } | ||
140 | |||
141 | // every keycode pressed on the keyboard must be present within the binding | ||
142 | // keys (unless it is a modifier) | ||
143 | for (size_t i = 0; i < keyboard->num_keycodes; ++i) { | ||
144 | xkb_keycode_t keycode = keyboard->keycodes[i] + 8; | ||
145 | bool found = false; | ||
146 | for (int j = 0; j < binding->keys->length; ++j) { | ||
147 | uint32_t binding_keycode = *(uint32_t*)binding->keys->items[j] + 8; | ||
148 | if (binding_keycode == keycode) { | ||
149 | found = true; | ||
150 | break; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | if (!found) { | ||
155 | if (!binding->modifiers) { | ||
156 | return false; | ||
157 | } | ||
158 | |||
159 | // check if it is a modifier, which we know matched from the check | ||
160 | // above | ||
161 | const xkb_keysym_t *keysyms; | ||
162 | int num_keysyms = | ||
163 | xkb_state_key_get_syms(keyboard->xkb_state, | ||
164 | keycode, &keysyms); | ||
165 | if (num_keysyms != 1 || !keysym_is_modifier(keysyms[0])) { | ||
166 | return false; | ||
167 | } | ||
168 | } | ||
169 | } | ||
170 | |||
171 | return true; | ||
172 | } | ||
173 | |||
174 | /** | ||
175 | * Execute keyboard bindings bound with `bindcode`. | ||
176 | * | ||
177 | * Returns true if the keysym was handled by a binding and false if the event | ||
178 | * should be propagated to clients. | ||
179 | */ | ||
180 | static bool keyboard_execute_bindcode(struct sway_keyboard *keyboard) { | ||
181 | struct wlr_keyboard *wlr_keyboard = | ||
182 | keyboard->seat_device->input_device->wlr_device->keyboard; | ||
183 | list_t *keycode_bindings = config->current_mode->keycode_bindings; | ||
184 | for (int i = 0; i < keycode_bindings->length; ++i) { | ||
185 | struct sway_binding *binding = keycode_bindings->items[i]; | ||
186 | //bool match = true; | ||
187 | for (int j = 0; j < binding->keys->length; ++j) { | ||
188 | if (binding_matches_keycodes(wlr_keyboard, binding)) { | ||
189 | struct cmd_results *results = handle_command(binding->command); | ||
190 | if (results->status != CMD_SUCCESS) { | ||
191 | sway_log(L_DEBUG, "could not run command for binding: %s", | ||
192 | binding->command); | ||
193 | } | ||
194 | free_cmd_results(results); | ||
195 | return true; | ||
196 | } | ||
197 | } | ||
198 | } | ||
199 | |||
200 | return false; | ||
201 | } | ||
202 | |||
203 | /** | ||
103 | * Get keysyms and modifiers from the keyboard as xkb sees them. | 204 | * Get keysyms and modifiers from the keyboard as xkb sees them. |
104 | * | 205 | * |
105 | * This uses the xkb keysyms translation based on pressed modifiers and clears | 206 | * This uses the xkb keysyms translation based on pressed modifiers and clears |
@@ -122,7 +223,7 @@ static size_t keyboard_keysyms_translated(struct sway_keyboard *keyboard, | |||
122 | keycode, keysyms); | 223 | keycode, keysyms); |
123 | } | 224 | } |
124 | 225 | ||
125 | /* | 226 | /** |
126 | * Get keysyms and modifiers from the keyboard as if modifiers didn't change | 227 | * Get keysyms and modifiers from the keyboard as if modifiers didn't change |
127 | * keysyms. | 228 | * keysyms. |
128 | * | 229 | * |
@@ -163,22 +264,6 @@ static void pressed_keysyms_remove(xkb_keysym_t *pressed_keysyms, | |||
163 | } | 264 | } |
164 | } | 265 | } |
165 | 266 | ||
166 | static bool keysym_is_modifier(xkb_keysym_t keysym) { | ||
167 | switch (keysym) { | ||
168 | case XKB_KEY_Shift_L: case XKB_KEY_Shift_R: | ||
169 | case XKB_KEY_Control_L: case XKB_KEY_Control_R: | ||
170 | case XKB_KEY_Caps_Lock: | ||
171 | case XKB_KEY_Shift_Lock: | ||
172 | case XKB_KEY_Meta_L: case XKB_KEY_Meta_R: | ||
173 | case XKB_KEY_Alt_L: case XKB_KEY_Alt_R: | ||
174 | case XKB_KEY_Super_L: case XKB_KEY_Super_R: | ||
175 | case XKB_KEY_Hyper_L: case XKB_KEY_Hyper_R: | ||
176 | return true; | ||
177 | default: | ||
178 | return false; | ||
179 | } | ||
180 | } | ||
181 | |||
182 | static void pressed_keysyms_update(xkb_keysym_t *pressed_keysyms, | 267 | static void pressed_keysyms_update(xkb_keysym_t *pressed_keysyms, |
183 | const xkb_keysym_t *keysyms, size_t keysyms_len, | 268 | const xkb_keysym_t *keysyms, size_t keysyms_len, |
184 | enum wlr_key_state state) { | 269 | enum wlr_key_state state) { |
@@ -207,7 +292,6 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) { | |||
207 | const xkb_keysym_t *keysyms; | 292 | const xkb_keysym_t *keysyms; |
208 | 293 | ||
209 | // handle keycodes | 294 | // handle keycodes |
210 | // TODO | ||
211 | handled = keyboard_execute_bindcode(keyboard); | 295 | handled = keyboard_execute_bindcode(keyboard); |
212 | 296 | ||
213 | // handle translated keysyms | 297 | // handle translated keysyms |