mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	Merge pull request #2381 from frsfnrrg/key-repeat
Implement key repeat for keybindings
This commit is contained in:
		
						commit
						6c30b3fcc8
					
				
					 2 changed files with 43 additions and 0 deletions
				
			
		| 
						 | 
					@ -38,6 +38,9 @@ struct sway_keyboard {
 | 
				
			||||||
	struct sway_shortcut_state state_keysyms_raw;
 | 
						struct sway_shortcut_state state_keysyms_raw;
 | 
				
			||||||
	struct sway_shortcut_state state_keycodes;
 | 
						struct sway_shortcut_state state_keycodes;
 | 
				
			||||||
	struct sway_binding *held_binding;
 | 
						struct sway_binding *held_binding;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wl_event_source *key_repeat_source;
 | 
				
			||||||
 | 
						struct sway_binding *repeat_binding;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat,
 | 
					struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -264,6 +264,7 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Identify and execute active pressed binding
 | 
						// Identify and execute active pressed binding
 | 
				
			||||||
 | 
						struct sway_binding *next_repeat_binding = NULL;
 | 
				
			||||||
	if (event->state == WLR_KEY_PRESSED) {
 | 
						if (event->state == WLR_KEY_PRESSED) {
 | 
				
			||||||
		struct sway_binding *binding_pressed = NULL;
 | 
							struct sway_binding *binding_pressed = NULL;
 | 
				
			||||||
		get_active_binding(&keyboard->state_keycodes,
 | 
							get_active_binding(&keyboard->state_keycodes,
 | 
				
			||||||
| 
						 | 
					@ -279,6 +280,21 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) {
 | 
				
			||||||
		if (binding_pressed) {
 | 
							if (binding_pressed) {
 | 
				
			||||||
			seat_execute_command(seat, binding_pressed);
 | 
								seat_execute_command(seat, binding_pressed);
 | 
				
			||||||
			handled = true;
 | 
								handled = true;
 | 
				
			||||||
 | 
								next_repeat_binding = binding_pressed;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Set up (or clear) keyboard repeat for a pressed binding
 | 
				
			||||||
 | 
						if (next_repeat_binding && wlr_device->keyboard->repeat_info.delay > 0) {
 | 
				
			||||||
 | 
							keyboard->repeat_binding = next_repeat_binding;
 | 
				
			||||||
 | 
							if (wl_event_source_timer_update(keyboard->key_repeat_source,
 | 
				
			||||||
 | 
									wlr_device->keyboard->repeat_info.delay) < 0) {
 | 
				
			||||||
 | 
								wlr_log(WLR_DEBUG, "failed to set key repeat timer");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else if (keyboard->repeat_binding) {
 | 
				
			||||||
 | 
							keyboard->repeat_binding = NULL;
 | 
				
			||||||
 | 
							if (wl_event_source_timer_update(keyboard->key_repeat_source, 0) < 0) {
 | 
				
			||||||
 | 
								wlr_log(WLR_DEBUG, "failed to disarm key repeat timer");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -303,6 +319,26 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	transaction_commit_dirty();
 | 
						transaction_commit_dirty();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int handle_keyboard_repeat(void *data) {
 | 
				
			||||||
 | 
						struct sway_keyboard *keyboard = (struct sway_keyboard *)data;
 | 
				
			||||||
 | 
						struct wlr_keyboard *wlr_device =
 | 
				
			||||||
 | 
								keyboard->seat_device->input_device->wlr_device->keyboard;
 | 
				
			||||||
 | 
						if (keyboard->repeat_binding) {
 | 
				
			||||||
 | 
							if (wlr_device->repeat_info.rate > 0) {
 | 
				
			||||||
 | 
								// We queue the next event first, as the command might cancel it
 | 
				
			||||||
 | 
								if (wl_event_source_timer_update(keyboard->key_repeat_source,
 | 
				
			||||||
 | 
										1000 / wlr_device->repeat_info.rate) < 0) {
 | 
				
			||||||
 | 
									wlr_log(WLR_DEBUG, "failed to update key repeat timer");
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							seat_execute_command(keyboard->seat_device->sway_seat,
 | 
				
			||||||
 | 
									keyboard->repeat_binding);
 | 
				
			||||||
 | 
							transaction_commit_dirty();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_keyboard_modifiers(struct wl_listener *listener,
 | 
					static void handle_keyboard_modifiers(struct wl_listener *listener,
 | 
				
			||||||
		void *data) {
 | 
							void *data) {
 | 
				
			||||||
	struct sway_keyboard *keyboard =
 | 
						struct sway_keyboard *keyboard =
 | 
				
			||||||
| 
						 | 
					@ -328,6 +364,9 @@ struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat,
 | 
				
			||||||
	wl_list_init(&keyboard->keyboard_key.link);
 | 
						wl_list_init(&keyboard->keyboard_key.link);
 | 
				
			||||||
	wl_list_init(&keyboard->keyboard_modifiers.link);
 | 
						wl_list_init(&keyboard->keyboard_modifiers.link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						keyboard->key_repeat_source = wl_event_loop_add_timer(server.wl_event_loop,
 | 
				
			||||||
 | 
								handle_keyboard_repeat, keyboard);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return keyboard;
 | 
						return keyboard;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -441,5 +480,6 @@ void sway_keyboard_destroy(struct sway_keyboard *keyboard) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	wl_list_remove(&keyboard->keyboard_key.link);
 | 
						wl_list_remove(&keyboard->keyboard_key.link);
 | 
				
			||||||
	wl_list_remove(&keyboard->keyboard_modifiers.link);
 | 
						wl_list_remove(&keyboard->keyboard_modifiers.link);
 | 
				
			||||||
 | 
						wl_event_source_remove(keyboard->key_repeat_source);
 | 
				
			||||||
	free(keyboard);
 | 
						free(keyboard);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue