mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	cmd_bind{sym,code}: Implement per-device bindings
bindsym --input-device=<identifier> ... bindcode --input-device=<identifier> ...
This commit is contained in:
		
							parent
							
								
									30dbb8eba0
								
							
						
					
					
						commit
						2e637b7368
					
				
					 9 changed files with 77 additions and 36 deletions
				
			
		| 
						 | 
					@ -43,6 +43,7 @@ enum binding_flags {
 | 
				
			||||||
struct sway_binding {
 | 
					struct sway_binding {
 | 
				
			||||||
	enum binding_input_type type;
 | 
						enum binding_input_type type;
 | 
				
			||||||
	int order;
 | 
						int order;
 | 
				
			||||||
 | 
						char *input;
 | 
				
			||||||
	uint32_t flags;
 | 
						uint32_t flags;
 | 
				
			||||||
	list_t *keys; // sorted in ascending order
 | 
						list_t *keys; // sorted in ascending order
 | 
				
			||||||
	uint32_t modifiers;
 | 
						uint32_t modifiers;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,8 +42,9 @@ void sway_cursor_destroy(struct sway_cursor *cursor);
 | 
				
			||||||
struct sway_cursor *sway_cursor_create(struct sway_seat *seat);
 | 
					struct sway_cursor *sway_cursor_create(struct sway_seat *seat);
 | 
				
			||||||
void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
 | 
					void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
 | 
				
			||||||
	bool allow_refocusing);
 | 
						bool allow_refocusing);
 | 
				
			||||||
void dispatch_cursor_button(struct sway_cursor *cursor, uint32_t time_msec,
 | 
					void dispatch_cursor_button(struct sway_cursor *cursor,
 | 
				
			||||||
	uint32_t button, enum wlr_button_state state);
 | 
						struct wlr_input_device *device, uint32_t time_msec, uint32_t button,
 | 
				
			||||||
 | 
						enum wlr_button_state state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cursor_set_image(struct sway_cursor *cursor, const char *image,
 | 
					void cursor_set_image(struct sway_cursor *cursor, const char *image,
 | 
				
			||||||
	struct wl_client *client);
 | 
						struct wl_client *client);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,5 +63,6 @@ struct sway_seat *input_manager_current_seat(struct sway_input_manager *input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct input_config *input_device_get_config(struct sway_input_device *device);
 | 
					struct input_config *input_device_get_config(struct sway_input_device *device);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *input_device_get_identifier(struct wlr_input_device *device);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,6 +26,7 @@ void free_sway_binding(struct sway_binding *binding) {
 | 
				
			||||||
	if (binding->keys) {
 | 
						if (binding->keys) {
 | 
				
			||||||
		free_flat_list(binding->keys);
 | 
							free_flat_list(binding->keys);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						free(binding->input);
 | 
				
			||||||
	free(binding->command);
 | 
						free(binding->command);
 | 
				
			||||||
	free(binding);
 | 
						free(binding);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -37,6 +38,10 @@ void free_sway_binding(struct sway_binding *binding) {
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static bool binding_key_compare(struct sway_binding *binding_a,
 | 
					static bool binding_key_compare(struct sway_binding *binding_a,
 | 
				
			||||||
		struct sway_binding *binding_b) {
 | 
							struct sway_binding *binding_b) {
 | 
				
			||||||
 | 
						if (strcmp(binding_a->input, binding_b->input) != 0) {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (binding_a->type != binding_b->type) {
 | 
						if (binding_a->type != binding_b->type) {
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -149,6 +154,7 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
 | 
				
			||||||
		return cmd_results_new(CMD_FAILURE, bindtype,
 | 
							return cmd_results_new(CMD_FAILURE, bindtype,
 | 
				
			||||||
				"Unable to allocate binding");
 | 
									"Unable to allocate binding");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						binding->input = strdup("*");
 | 
				
			||||||
	binding->keys = create_list();
 | 
						binding->keys = create_list();
 | 
				
			||||||
	binding->modifiers = 0;
 | 
						binding->modifiers = 0;
 | 
				
			||||||
	binding->flags = 0;
 | 
						binding->flags = 0;
 | 
				
			||||||
| 
						 | 
					@ -168,6 +174,10 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
 | 
				
			||||||
			binding->flags |= BINDING_BORDER;
 | 
								binding->flags |= BINDING_BORDER;
 | 
				
			||||||
		} else if (strcmp("--exclude-titlebar", argv[0]) == 0) {
 | 
							} else if (strcmp("--exclude-titlebar", argv[0]) == 0) {
 | 
				
			||||||
			exclude_titlebar = true;
 | 
								exclude_titlebar = true;
 | 
				
			||||||
 | 
							} else if (strncmp("--input-device=", argv[0],
 | 
				
			||||||
 | 
										strlen("--input-device=")) == 0) {
 | 
				
			||||||
 | 
								free(binding->input);
 | 
				
			||||||
 | 
								binding->input = strdup(argv[0] + strlen("--input-device="));
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -257,8 +267,8 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
 | 
				
			||||||
		list_add(mode_bindings, binding);
 | 
							list_add(mode_bindings, binding);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_log(WLR_DEBUG, "%s - Bound %s to command %s",
 | 
						wlr_log(WLR_DEBUG, "%s - Bound %s to command `%s` for device '%s'",
 | 
				
			||||||
		bindtype, argv[0], binding->command);
 | 
							bindtype, argv[0], binding->command, binding->input);
 | 
				
			||||||
	return cmd_results_new(CMD_SUCCESS, NULL, NULL);
 | 
						return cmd_results_new(CMD_SUCCESS, NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -80,6 +80,6 @@ static struct cmd_results *press_or_release(struct sway_cursor *cursor,
 | 
				
			||||||
			return cmd_results_new(CMD_INVALID, "cursor", expected_syntax);
 | 
								return cmd_results_new(CMD_INVALID, "cursor", expected_syntax);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	dispatch_cursor_button(cursor, 0, button, state);
 | 
						dispatch_cursor_button(cursor, NULL, 0, button, state);
 | 
				
			||||||
	return cmd_results_new(CMD_SUCCESS, NULL, NULL);
 | 
						return cmd_results_new(CMD_SUCCESS, NULL, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -727,19 +727,23 @@ static void state_add_button(struct sway_cursor *cursor, uint32_t button) {
 | 
				
			||||||
 * Return the mouse binding which matches modifier, click location, release,
 | 
					 * Return the mouse binding which matches modifier, click location, release,
 | 
				
			||||||
 * and pressed button state, otherwise return null.
 | 
					 * and pressed button state, otherwise return null.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static struct sway_binding* get_active_mouse_binding(const struct sway_cursor *cursor,
 | 
					static struct sway_binding* get_active_mouse_binding(
 | 
				
			||||||
		list_t *bindings, uint32_t modifiers, bool release, bool on_titlebar,
 | 
							const struct sway_cursor *cursor, list_t *bindings, uint32_t modifiers,
 | 
				
			||||||
				     bool on_border, bool on_content) {
 | 
							bool release, bool on_titlebar, bool on_border, bool on_content,
 | 
				
			||||||
 | 
							const char *identifier) {
 | 
				
			||||||
	uint32_t click_region = (on_titlebar ? BINDING_TITLEBAR : 0) |
 | 
						uint32_t click_region = (on_titlebar ? BINDING_TITLEBAR : 0) |
 | 
				
			||||||
			(on_border ? BINDING_BORDER : 0) |
 | 
								(on_border ? BINDING_BORDER : 0) |
 | 
				
			||||||
			(on_content ? BINDING_CONTENTS : 0);
 | 
								(on_content ? BINDING_CONTENTS : 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct sway_binding *current = NULL;
 | 
				
			||||||
	for (int i = 0; i < bindings->length; ++i) {
 | 
						for (int i = 0; i < bindings->length; ++i) {
 | 
				
			||||||
		struct sway_binding *binding = bindings->items[i];
 | 
							struct sway_binding *binding = bindings->items[i];
 | 
				
			||||||
		if (modifiers ^ binding->modifiers ||
 | 
							if (modifiers ^ binding->modifiers ||
 | 
				
			||||||
				cursor->pressed_button_count != (size_t)binding->keys->length ||
 | 
									cursor->pressed_button_count != (size_t)binding->keys->length ||
 | 
				
			||||||
				release != (binding->flags & BINDING_RELEASE) ||
 | 
									release != (binding->flags & BINDING_RELEASE) ||
 | 
				
			||||||
				!(click_region & binding->flags)) {
 | 
									!(click_region & binding->flags) ||
 | 
				
			||||||
 | 
									(strcmp(binding->input, identifier) != 0 &&
 | 
				
			||||||
 | 
									 strcmp(binding->input, "*") != 0)) {
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -755,13 +759,20 @@ static struct sway_binding* get_active_mouse_binding(const struct sway_cursor *c
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return binding;
 | 
							if (!current || strcmp(current->input, "*") == 0) {
 | 
				
			||||||
 | 
								current = binding;
 | 
				
			||||||
 | 
								if (strcmp(current->input, identifier) == 0) {
 | 
				
			||||||
 | 
									// If a binding is found for the exact input, quit searching
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return NULL;
 | 
						return current;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void dispatch_cursor_button(struct sway_cursor *cursor,
 | 
					void dispatch_cursor_button(struct sway_cursor *cursor,
 | 
				
			||||||
		uint32_t time_msec, uint32_t button, enum wlr_button_state state) {
 | 
							struct wlr_input_device *device, uint32_t time_msec, uint32_t button,
 | 
				
			||||||
 | 
							enum wlr_button_state state) {
 | 
				
			||||||
	if (time_msec == 0) {
 | 
						if (time_msec == 0) {
 | 
				
			||||||
		time_msec = get_current_time_msec();
 | 
							time_msec = get_current_time_msec();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -797,18 +808,21 @@ void dispatch_cursor_button(struct sway_cursor *cursor,
 | 
				
			||||||
	struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat);
 | 
						struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat);
 | 
				
			||||||
	uint32_t modifiers = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
 | 
						uint32_t modifiers = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char *device_identifier = device ? input_device_get_identifier(device)
 | 
				
			||||||
 | 
							: strdup("*");
 | 
				
			||||||
	struct sway_binding *binding = NULL;
 | 
						struct sway_binding *binding = NULL;
 | 
				
			||||||
	if (state == WLR_BUTTON_PRESSED) {
 | 
						if (state == WLR_BUTTON_PRESSED) {
 | 
				
			||||||
		state_add_button(cursor, button);
 | 
							state_add_button(cursor, button);
 | 
				
			||||||
		binding = get_active_mouse_binding(cursor,
 | 
							binding = get_active_mouse_binding(cursor,
 | 
				
			||||||
			config->current_mode->mouse_bindings, modifiers, false,
 | 
								config->current_mode->mouse_bindings, modifiers, false,
 | 
				
			||||||
			on_titlebar, on_border, on_contents);
 | 
								on_titlebar, on_border, on_contents, device_identifier);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		binding = get_active_mouse_binding(cursor,
 | 
							binding = get_active_mouse_binding(cursor,
 | 
				
			||||||
			config->current_mode->mouse_bindings, modifiers, true,
 | 
								config->current_mode->mouse_bindings, modifiers, true,
 | 
				
			||||||
			on_titlebar, on_border, on_contents);
 | 
								on_titlebar, on_border, on_contents, device_identifier);
 | 
				
			||||||
		state_erase_button(cursor, button);
 | 
							state_erase_button(cursor, button);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						free(device_identifier);
 | 
				
			||||||
	if (binding) {
 | 
						if (binding) {
 | 
				
			||||||
		seat_execute_command(seat, binding);
 | 
							seat_execute_command(seat, binding);
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					@ -942,7 +956,7 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct sway_cursor *cursor = wl_container_of(listener, cursor, button);
 | 
						struct sway_cursor *cursor = wl_container_of(listener, cursor, button);
 | 
				
			||||||
	wlr_idle_notify_activity(cursor->seat->input->server->idle, cursor->seat->wlr_seat);
 | 
						wlr_idle_notify_activity(cursor->seat->input->server->idle, cursor->seat->wlr_seat);
 | 
				
			||||||
	struct wlr_event_pointer_button *event = data;
 | 
						struct wlr_event_pointer_button *event = data;
 | 
				
			||||||
	dispatch_cursor_button(cursor,
 | 
						dispatch_cursor_button(cursor, event->device,
 | 
				
			||||||
			event->time_msec, event->button, event->state);
 | 
								event->time_msec, event->button, event->state);
 | 
				
			||||||
	transaction_commit_dirty();
 | 
						transaction_commit_dirty();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1128,7 +1142,7 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_tip);
 | 
						struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_tip);
 | 
				
			||||||
	wlr_idle_notify_activity(cursor->seat->input->server->idle, cursor->seat->wlr_seat);
 | 
						wlr_idle_notify_activity(cursor->seat->input->server->idle, cursor->seat->wlr_seat);
 | 
				
			||||||
	struct wlr_event_tablet_tool_tip *event = data;
 | 
						struct wlr_event_tablet_tool_tip *event = data;
 | 
				
			||||||
	dispatch_cursor_button(cursor, event->time_msec,
 | 
						dispatch_cursor_button(cursor, event->device, event->time_msec,
 | 
				
			||||||
			BTN_LEFT, event->state == WLR_TABLET_TOOL_TIP_DOWN ?
 | 
								BTN_LEFT, event->state == WLR_TABLET_TOOL_TIP_DOWN ?
 | 
				
			||||||
				WLR_BUTTON_PRESSED : WLR_BUTTON_RELEASED);
 | 
									WLR_BUTTON_PRESSED : WLR_BUTTON_RELEASED);
 | 
				
			||||||
	transaction_commit_dirty();
 | 
						transaction_commit_dirty();
 | 
				
			||||||
| 
						 | 
					@ -1143,14 +1157,14 @@ static void handle_tool_button(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	switch (event->state) {
 | 
						switch (event->state) {
 | 
				
			||||||
	case WLR_BUTTON_PRESSED:
 | 
						case WLR_BUTTON_PRESSED:
 | 
				
			||||||
		if (cursor->tool_buttons == 0) {
 | 
							if (cursor->tool_buttons == 0) {
 | 
				
			||||||
			dispatch_cursor_button(cursor,
 | 
								dispatch_cursor_button(cursor, event->device,
 | 
				
			||||||
					event->time_msec, BTN_RIGHT, event->state);
 | 
										event->time_msec, BTN_RIGHT, event->state);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		cursor->tool_buttons++;
 | 
							cursor->tool_buttons++;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case WLR_BUTTON_RELEASED:
 | 
						case WLR_BUTTON_RELEASED:
 | 
				
			||||||
		if (cursor->tool_buttons == 1) {
 | 
							if (cursor->tool_buttons == 1) {
 | 
				
			||||||
			dispatch_cursor_button(cursor,
 | 
								dispatch_cursor_button(cursor, event->device,
 | 
				
			||||||
					event->time_msec, BTN_RIGHT, event->state);
 | 
										event->time_msec, BTN_RIGHT, event->state);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		cursor->tool_buttons--;
 | 
							cursor->tool_buttons--;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,7 +45,7 @@ struct sway_seat *input_manager_get_seat(
 | 
				
			||||||
	return seat_create(input, seat_name);
 | 
						return seat_create(input, seat_name);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char *get_device_identifier(struct wlr_input_device *device) {
 | 
					char *input_device_get_identifier(struct wlr_input_device *device) {
 | 
				
			||||||
	int vendor = device->vendor;
 | 
						int vendor = device->vendor;
 | 
				
			||||||
	int product = device->product;
 | 
						int product = device->product;
 | 
				
			||||||
	char *name = strdup(device->name);
 | 
						char *name = strdup(device->name);
 | 
				
			||||||
| 
						 | 
					@ -278,7 +278,7 @@ static void handle_new_input(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	device->data = input_device;
 | 
						device->data = input_device;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	input_device->wlr_device = device;
 | 
						input_device->wlr_device = device;
 | 
				
			||||||
	input_device->identifier = get_device_identifier(device);
 | 
						input_device->identifier = input_device_get_identifier(device);
 | 
				
			||||||
	wl_list_insert(&input->devices, &input_device->link);
 | 
						wl_list_insert(&input->devices, &input_device->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_log(WLR_DEBUG, "adding device: '%s'",
 | 
						wlr_log(WLR_DEBUG, "adding device: '%s'",
 | 
				
			||||||
| 
						 | 
					@ -375,7 +375,7 @@ void handle_virtual_keyboard(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	device->data = input_device;
 | 
						device->data = input_device;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	input_device->wlr_device = device;
 | 
						input_device->wlr_device = device;
 | 
				
			||||||
	input_device->identifier = get_device_identifier(device);
 | 
						input_device->identifier = input_device_get_identifier(device);
 | 
				
			||||||
	wl_list_insert(&input_manager->devices, &input_device->link);
 | 
						wl_list_insert(&input_manager->devices, &input_device->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_log(WLR_DEBUG, "adding virtual keyboard: '%s'",
 | 
						wlr_log(WLR_DEBUG, "adding virtual keyboard: '%s'",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,7 +87,7 @@ static void update_shortcut_state(struct sway_shortcut_state *state,
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void get_active_binding(const struct sway_shortcut_state *state,
 | 
					static void get_active_binding(const struct sway_shortcut_state *state,
 | 
				
			||||||
		list_t *bindings, struct sway_binding **current_binding,
 | 
							list_t *bindings, struct sway_binding **current_binding,
 | 
				
			||||||
		uint32_t modifiers, bool release, bool locked) {
 | 
							uint32_t modifiers, bool release, bool locked, const char *input) {
 | 
				
			||||||
	for (int i = 0; i < bindings->length; ++i) {
 | 
						for (int i = 0; i < bindings->length; ++i) {
 | 
				
			||||||
		struct sway_binding *binding = bindings->items[i];
 | 
							struct sway_binding *binding = bindings->items[i];
 | 
				
			||||||
		bool binding_locked = binding->flags & BINDING_LOCKED;
 | 
							bool binding_locked = binding->flags & BINDING_LOCKED;
 | 
				
			||||||
| 
						 | 
					@ -96,7 +96,9 @@ static void get_active_binding(const struct sway_shortcut_state *state,
 | 
				
			||||||
		if (modifiers ^ binding->modifiers ||
 | 
							if (modifiers ^ binding->modifiers ||
 | 
				
			||||||
				state->npressed != (size_t)binding->keys->length ||
 | 
									state->npressed != (size_t)binding->keys->length ||
 | 
				
			||||||
				release != binding_release ||
 | 
									release != binding_release ||
 | 
				
			||||||
				locked > binding_locked) {
 | 
									locked > binding_locked ||
 | 
				
			||||||
 | 
									(strcmp(binding->input, input) != 0 &&
 | 
				
			||||||
 | 
									 strcmp(binding->input, "*") != 0)) {
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -112,13 +114,19 @@ static void get_active_binding(const struct sway_shortcut_state *state,
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (*current_binding && *current_binding != binding) {
 | 
							if (*current_binding && *current_binding != binding &&
 | 
				
			||||||
 | 
									strcmp((*current_binding)->input, binding->input) == 0) {
 | 
				
			||||||
			wlr_log(WLR_DEBUG, "encountered duplicate bindings %d and %d",
 | 
								wlr_log(WLR_DEBUG, "encountered duplicate bindings %d and %d",
 | 
				
			||||||
					(*current_binding)->order, binding->order);
 | 
										(*current_binding)->order, binding->order);
 | 
				
			||||||
		} else {
 | 
							} else if (!*current_binding ||
 | 
				
			||||||
 | 
									strcmp((*current_binding)->input, "*") == 0) {
 | 
				
			||||||
			*current_binding = binding;
 | 
								*current_binding = binding;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (strcmp((*current_binding)->input, input) == 0) {
 | 
				
			||||||
 | 
									// If a binding is found for the exact input, quit searching
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -202,6 +210,7 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct wlr_seat *wlr_seat = seat->wlr_seat;
 | 
						struct wlr_seat *wlr_seat = seat->wlr_seat;
 | 
				
			||||||
	struct wlr_input_device *wlr_device =
 | 
						struct wlr_input_device *wlr_device =
 | 
				
			||||||
		keyboard->seat_device->input_device->wlr_device;
 | 
							keyboard->seat_device->input_device->wlr_device;
 | 
				
			||||||
 | 
						char *device_identifier = input_device_get_identifier(wlr_device);
 | 
				
			||||||
	wlr_idle_notify_activity(seat->input->server->idle, wlr_seat);
 | 
						wlr_idle_notify_activity(seat->input->server->idle, wlr_seat);
 | 
				
			||||||
	struct wlr_event_keyboard_key *event = data;
 | 
						struct wlr_event_keyboard_key *event = data;
 | 
				
			||||||
	bool input_inhibited = seat->exclusive_client != NULL;
 | 
						bool input_inhibited = seat->exclusive_client != NULL;
 | 
				
			||||||
| 
						 | 
					@ -242,13 +251,13 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct sway_binding *binding_released = NULL;
 | 
						struct sway_binding *binding_released = NULL;
 | 
				
			||||||
	get_active_binding(&keyboard->state_keycodes,
 | 
						get_active_binding(&keyboard->state_keycodes,
 | 
				
			||||||
			config->current_mode->keycode_bindings, &binding_released,
 | 
								config->current_mode->keycode_bindings, &binding_released,
 | 
				
			||||||
			code_modifiers, true, input_inhibited);
 | 
								code_modifiers, true, input_inhibited, device_identifier);
 | 
				
			||||||
	get_active_binding(&keyboard->state_keysyms_translated,
 | 
						get_active_binding(&keyboard->state_keysyms_translated,
 | 
				
			||||||
			config->current_mode->keysym_bindings, &binding_released,
 | 
								config->current_mode->keysym_bindings, &binding_released,
 | 
				
			||||||
			translated_modifiers, true, input_inhibited);
 | 
								translated_modifiers, true, input_inhibited, device_identifier);
 | 
				
			||||||
	get_active_binding(&keyboard->state_keysyms_raw,
 | 
						get_active_binding(&keyboard->state_keysyms_raw,
 | 
				
			||||||
			config->current_mode->keysym_bindings, &binding_released,
 | 
								config->current_mode->keysym_bindings, &binding_released,
 | 
				
			||||||
			raw_modifiers, true, input_inhibited);
 | 
								raw_modifiers, true, input_inhibited, device_identifier);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Execute stored release binding once no longer active
 | 
						// Execute stored release binding once no longer active
 | 
				
			||||||
	if (keyboard->held_binding && binding_released != keyboard->held_binding &&
 | 
						if (keyboard->held_binding && binding_released != keyboard->held_binding &&
 | 
				
			||||||
| 
						 | 
					@ -268,13 +277,14 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	if (event->state == WLR_KEY_PRESSED) {
 | 
						if (event->state == WLR_KEY_PRESSED) {
 | 
				
			||||||
		get_active_binding(&keyboard->state_keycodes,
 | 
							get_active_binding(&keyboard->state_keycodes,
 | 
				
			||||||
				config->current_mode->keycode_bindings, &binding,
 | 
									config->current_mode->keycode_bindings, &binding,
 | 
				
			||||||
				code_modifiers, false, input_inhibited);
 | 
									code_modifiers, false, input_inhibited, device_identifier);
 | 
				
			||||||
		get_active_binding(&keyboard->state_keysyms_translated,
 | 
							get_active_binding(&keyboard->state_keysyms_translated,
 | 
				
			||||||
				config->current_mode->keysym_bindings, &binding,
 | 
									config->current_mode->keysym_bindings, &binding,
 | 
				
			||||||
				translated_modifiers, false, input_inhibited);
 | 
									translated_modifiers, false, input_inhibited,
 | 
				
			||||||
 | 
									device_identifier);
 | 
				
			||||||
		get_active_binding(&keyboard->state_keysyms_raw,
 | 
							get_active_binding(&keyboard->state_keysyms_raw,
 | 
				
			||||||
				config->current_mode->keysym_bindings, &binding,
 | 
									config->current_mode->keysym_bindings, &binding,
 | 
				
			||||||
				raw_modifiers, false, input_inhibited);
 | 
									raw_modifiers, false, input_inhibited, device_identifier);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (binding) {
 | 
							if (binding) {
 | 
				
			||||||
			seat_execute_command(seat, binding);
 | 
								seat_execute_command(seat, binding);
 | 
				
			||||||
| 
						 | 
					@ -315,6 +325,8 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	transaction_commit_dirty();
 | 
						transaction_commit_dirty();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						free(device_identifier);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int handle_keyboard_repeat(void *data) {
 | 
					static int handle_keyboard_repeat(void *data) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -257,20 +257,22 @@ runtime.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for\_window <criteria> move container to output <output>
 | 
							for\_window <criteria> move container to output <output>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
*bindsym* [--release|--locked] <key combo> <command>
 | 
					*bindsym* [--release|--locked] [--input-device=<device>] <key combo> <command>
 | 
				
			||||||
	Binds _key combo_ to execute the sway command _command_ when pressed. You
 | 
						Binds _key combo_ to execute the sway command _command_ when pressed. You
 | 
				
			||||||
	may use XKB key names here (*xev*(1) is a good tool for discovering these).
 | 
						may use XKB key names here (*xev*(1) is a good tool for discovering these).
 | 
				
			||||||
	With the flag _--release_, the command is executed when the key combo is
 | 
						With the flag _--release_, the command is executed when the key combo is
 | 
				
			||||||
	released. Unless the flag _--locked_ is set, the command will not be run
 | 
						released. Unless the flag _--locked_ is set, the command will not be run
 | 
				
			||||||
	when a screen locking program is active.
 | 
						when a screen locking program is active. If _input-device_ is given, the
 | 
				
			||||||
 | 
						binding will only be executed for that input device and will be executed
 | 
				
			||||||
 | 
						instead of any binding that is generic to all devices.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Example:
 | 
						Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		# Execute firefox when alt, shift, and f are pressed together
 | 
							# Execute firefox when alt, shift, and f are pressed together
 | 
				
			||||||
		bindsym Mod1+Shift+f exec firefox
 | 
							bindsym Mod1+Shift+f exec firefox
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	*bindcode* [--release|--locked] <code> <command> is also available for
 | 
						*bindcode* [--release|--locked] [--input-device=<device>] <code> <command>
 | 
				
			||||||
	binding with key codes instead of key names.
 | 
						is also available for binding with key codes instead of key names.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
*client.<class>* <border> <background> <text> <indicator> <child\_border>
 | 
					*client.<class>* <border> <background> <text> <indicator> <child\_border>
 | 
				
			||||||
	Configures the color of window borders and title bars. All 5 colors are
 | 
						Configures the color of window borders and title bars. All 5 colors are
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue