diff options
author | frsfnrrg <frsfnrrg@users.noreply.github.com> | 2018-07-29 16:25:43 -0400 |
---|---|---|
committer | frsfnrrg <frsfnrrg@users.noreply.github.com> | 2018-07-29 19:15:02 -0400 |
commit | e33dfbfa758fb899c276135d06f25359ceee0002 (patch) | |
tree | 2ac9007d59e001f16c92dd43cb9e961fd043257f /sway | |
parent | Merge pull request #2379 from emersion/xwayland-unmanaged (diff) | |
download | sway-e33dfbfa758fb899c276135d06f25359ceee0002.tar.gz sway-e33dfbfa758fb899c276135d06f25359ceee0002.tar.zst sway-e33dfbfa758fb899c276135d06f25359ceee0002.zip |
Implement key repeat for pressed key bindings
Each sway_keyboard is provided with a wayland timer event source.
When a valid keypress binding has been found, a callback to
handle_keyboard_repeat is set. Any key event will either clear
the callback or (if the new key event is a valid keypress binding)
delay the callback again.
Diffstat (limited to 'sway')
-rw-r--r-- | sway/input/keyboard.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index 8dc8239c..be000fb9 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c | |||
@@ -264,6 +264,7 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) { | |||
264 | } | 264 | } |
265 | 265 | ||
266 | // Identify and execute active pressed binding | 266 | // Identify and execute active pressed binding |
267 | struct sway_binding *next_repeat_binding = NULL; | ||
267 | if (event->state == WLR_KEY_PRESSED) { | 268 | if (event->state == WLR_KEY_PRESSED) { |
268 | struct sway_binding *binding_pressed = NULL; | 269 | struct sway_binding *binding_pressed = NULL; |
269 | get_active_binding(&keyboard->state_keycodes, | 270 | get_active_binding(&keyboard->state_keycodes, |
@@ -279,6 +280,21 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) { | |||
279 | if (binding_pressed) { | 280 | if (binding_pressed) { |
280 | seat_execute_command(seat, binding_pressed); | 281 | seat_execute_command(seat, binding_pressed); |
281 | handled = true; | 282 | handled = true; |
283 | next_repeat_binding = binding_pressed; | ||
284 | } | ||
285 | } | ||
286 | |||
287 | // Set up (or clear) keyboard repeat for a pressed binding | ||
288 | if (next_repeat_binding) { | ||
289 | keyboard->repeat_binding = next_repeat_binding; | ||
290 | if (wl_event_source_timer_update(keyboard->key_repeat_source, | ||
291 | keyboard->key_repeat_initial_delay) < 0) { | ||
292 | wlr_log(WLR_DEBUG, "failed to set key repeat timer"); | ||
293 | } | ||
294 | } else if (keyboard->repeat_binding) { | ||
295 | keyboard->repeat_binding = NULL; | ||
296 | if (wl_event_source_timer_update(keyboard->key_repeat_source, 0) < 0) { | ||
297 | wlr_log(WLR_DEBUG, "failed to disarm key repeat timer"); | ||
282 | } | 298 | } |
283 | } | 299 | } |
284 | 300 | ||
@@ -303,6 +319,22 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) { | |||
303 | transaction_commit_dirty(); | 319 | transaction_commit_dirty(); |
304 | } | 320 | } |
305 | 321 | ||
322 | static int handle_keyboard_repeat(void *data) { | ||
323 | struct sway_keyboard *keyboard = (struct sway_keyboard *)data; | ||
324 | if (keyboard->repeat_binding) { | ||
325 | // We queue the next event first, as the command might cancel it | ||
326 | if (wl_event_source_timer_update(keyboard->key_repeat_source, | ||
327 | keyboard->key_repeat_step_delay) < 0) { | ||
328 | wlr_log(WLR_DEBUG, "failed to update key repeat timer"); | ||
329 | } | ||
330 | |||
331 | seat_execute_command(keyboard->seat_device->sway_seat, | ||
332 | keyboard->repeat_binding); | ||
333 | transaction_commit_dirty(); | ||
334 | } | ||
335 | return 0; | ||
336 | } | ||
337 | |||
306 | static void handle_keyboard_modifiers(struct wl_listener *listener, | 338 | static void handle_keyboard_modifiers(struct wl_listener *listener, |
307 | void *data) { | 339 | void *data) { |
308 | struct sway_keyboard *keyboard = | 340 | struct sway_keyboard *keyboard = |
@@ -328,6 +360,11 @@ struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat, | |||
328 | wl_list_init(&keyboard->keyboard_key.link); | 360 | wl_list_init(&keyboard->keyboard_key.link); |
329 | wl_list_init(&keyboard->keyboard_modifiers.link); | 361 | wl_list_init(&keyboard->keyboard_modifiers.link); |
330 | 362 | ||
363 | keyboard->key_repeat_source = wl_event_loop_add_timer(server.wl_event_loop, | ||
364 | handle_keyboard_repeat, keyboard); | ||
365 | keyboard->key_repeat_initial_delay = 660; | ||
366 | keyboard->key_repeat_step_delay = 40; | ||
367 | |||
331 | return keyboard; | 368 | return keyboard; |
332 | } | 369 | } |
333 | 370 | ||
@@ -441,5 +478,6 @@ void sway_keyboard_destroy(struct sway_keyboard *keyboard) { | |||
441 | } | 478 | } |
442 | wl_list_remove(&keyboard->keyboard_key.link); | 479 | wl_list_remove(&keyboard->keyboard_key.link); |
443 | wl_list_remove(&keyboard->keyboard_modifiers.link); | 480 | wl_list_remove(&keyboard->keyboard_modifiers.link); |
481 | wl_event_source_remove(keyboard->key_repeat_source); | ||
444 | free(keyboard); | 482 | free(keyboard); |
445 | } | 483 | } |