diff options
-rw-r--r-- | include/sway/config.h | 1 | ||||
-rw-r--r-- | include/sway/input/cursor.h | 5 | ||||
-rw-r--r-- | include/sway/input/input-manager.h | 1 | ||||
-rw-r--r-- | sway/commands/bind.c | 14 | ||||
-rw-r--r-- | sway/commands/seat/cursor.c | 2 | ||||
-rw-r--r-- | sway/input/cursor.c | 40 | ||||
-rw-r--r-- | sway/input/input-manager.c | 6 | ||||
-rw-r--r-- | sway/input/keyboard.c | 34 | ||||
-rw-r--r-- | sway/sway.5.scd | 10 |
9 files changed, 77 insertions, 36 deletions
diff --git a/include/sway/config.h b/include/sway/config.h index be5a00b5..fef3a60a 100644 --- a/include/sway/config.h +++ b/include/sway/config.h | |||
@@ -43,6 +43,7 @@ enum binding_flags { | |||
43 | struct sway_binding { | 43 | struct sway_binding { |
44 | enum binding_input_type type; | 44 | enum binding_input_type type; |
45 | int order; | 45 | int order; |
46 | char *input; | ||
46 | uint32_t flags; | 47 | uint32_t flags; |
47 | list_t *keys; // sorted in ascending order | 48 | list_t *keys; // sorted in ascending order |
48 | uint32_t modifiers; | 49 | uint32_t modifiers; |
diff --git a/include/sway/input/cursor.h b/include/sway/input/cursor.h index 5556ea11..299721f0 100644 --- a/include/sway/input/cursor.h +++ b/include/sway/input/cursor.h | |||
@@ -42,8 +42,9 @@ void sway_cursor_destroy(struct sway_cursor *cursor); | |||
42 | struct sway_cursor *sway_cursor_create(struct sway_seat *seat); | 42 | struct sway_cursor *sway_cursor_create(struct sway_seat *seat); |
43 | void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, | 43 | void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, |
44 | bool allow_refocusing); | 44 | bool allow_refocusing); |
45 | void dispatch_cursor_button(struct sway_cursor *cursor, uint32_t time_msec, | 45 | void dispatch_cursor_button(struct sway_cursor *cursor, |
46 | uint32_t button, enum wlr_button_state state); | 46 | struct wlr_input_device *device, uint32_t time_msec, uint32_t button, |
47 | enum wlr_button_state state); | ||
47 | 48 | ||
48 | void cursor_set_image(struct sway_cursor *cursor, const char *image, | 49 | void cursor_set_image(struct sway_cursor *cursor, const char *image, |
49 | struct wl_client *client); | 50 | struct wl_client *client); |
diff --git a/include/sway/input/input-manager.h b/include/sway/input/input-manager.h index bde3cf46..b7073006 100644 --- a/include/sway/input/input-manager.h +++ b/include/sway/input/input-manager.h | |||
@@ -63,5 +63,6 @@ struct sway_seat *input_manager_current_seat(struct sway_input_manager *input); | |||
63 | 63 | ||
64 | struct input_config *input_device_get_config(struct sway_input_device *device); | 64 | struct input_config *input_device_get_config(struct sway_input_device *device); |
65 | 65 | ||
66 | char *input_device_get_identifier(struct wlr_input_device *device); | ||
66 | 67 | ||
67 | #endif | 68 | #endif |
diff --git a/sway/commands/bind.c b/sway/commands/bind.c index 701d9746..5832d01e 100644 --- a/sway/commands/bind.c +++ b/sway/commands/bind.c | |||
@@ -26,6 +26,7 @@ void free_sway_binding(struct sway_binding *binding) { | |||
26 | if (binding->keys) { | 26 | if (binding->keys) { |
27 | free_flat_list(binding->keys); | 27 | free_flat_list(binding->keys); |
28 | } | 28 | } |
29 | free(binding->input); | ||
29 | free(binding->command); | 30 | free(binding->command); |
30 | free(binding); | 31 | free(binding); |
31 | } | 32 | } |
@@ -37,6 +38,10 @@ void free_sway_binding(struct sway_binding *binding) { | |||
37 | */ | 38 | */ |
38 | static bool binding_key_compare(struct sway_binding *binding_a, | 39 | static bool binding_key_compare(struct sway_binding *binding_a, |
39 | struct sway_binding *binding_b) { | 40 | struct sway_binding *binding_b) { |
41 | if (strcmp(binding_a->input, binding_b->input) != 0) { | ||
42 | return false; | ||
43 | } | ||
44 | |||
40 | if (binding_a->type != binding_b->type) { | 45 | if (binding_a->type != binding_b->type) { |
41 | return false; | 46 | return false; |
42 | } | 47 | } |
@@ -149,6 +154,7 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv, | |||
149 | return cmd_results_new(CMD_FAILURE, bindtype, | 154 | return cmd_results_new(CMD_FAILURE, bindtype, |
150 | "Unable to allocate binding"); | 155 | "Unable to allocate binding"); |
151 | } | 156 | } |
157 | binding->input = strdup("*"); | ||
152 | binding->keys = create_list(); | 158 | binding->keys = create_list(); |
153 | binding->modifiers = 0; | 159 | binding->modifiers = 0; |
154 | binding->flags = 0; | 160 | binding->flags = 0; |
@@ -168,6 +174,10 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv, | |||
168 | binding->flags |= BINDING_BORDER; | 174 | binding->flags |= BINDING_BORDER; |
169 | } else if (strcmp("--exclude-titlebar", argv[0]) == 0) { | 175 | } else if (strcmp("--exclude-titlebar", argv[0]) == 0) { |
170 | exclude_titlebar = true; | 176 | exclude_titlebar = true; |
177 | } else if (strncmp("--input-device=", argv[0], | ||
178 | strlen("--input-device=")) == 0) { | ||
179 | free(binding->input); | ||
180 | binding->input = strdup(argv[0] + strlen("--input-device=")); | ||
171 | } else { | 181 | } else { |
172 | break; | 182 | break; |
173 | } | 183 | } |
@@ -257,8 +267,8 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv, | |||
257 | list_add(mode_bindings, binding); | 267 | list_add(mode_bindings, binding); |
258 | } | 268 | } |
259 | 269 | ||
260 | wlr_log(WLR_DEBUG, "%s - Bound %s to command %s", | 270 | wlr_log(WLR_DEBUG, "%s - Bound %s to command `%s` for device '%s'", |
261 | bindtype, argv[0], binding->command); | 271 | bindtype, argv[0], binding->command, binding->input); |
262 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 272 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
263 | 273 | ||
264 | } | 274 | } |
diff --git a/sway/commands/seat/cursor.c b/sway/commands/seat/cursor.c index cd6630e0..595e9bc6 100644 --- a/sway/commands/seat/cursor.c +++ b/sway/commands/seat/cursor.c | |||
@@ -80,6 +80,6 @@ static struct cmd_results *press_or_release(struct sway_cursor *cursor, | |||
80 | return cmd_results_new(CMD_INVALID, "cursor", expected_syntax); | 80 | return cmd_results_new(CMD_INVALID, "cursor", expected_syntax); |
81 | } | 81 | } |
82 | } | 82 | } |
83 | dispatch_cursor_button(cursor, 0, button, state); | 83 | dispatch_cursor_button(cursor, NULL, 0, button, state); |
84 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 84 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
85 | } | 85 | } |
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 688fc230..7ac5013d 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -727,19 +727,23 @@ static void state_add_button(struct sway_cursor *cursor, uint32_t button) { | |||
727 | * Return the mouse binding which matches modifier, click location, release, | 727 | * Return the mouse binding which matches modifier, click location, release, |
728 | * and pressed button state, otherwise return null. | 728 | * and pressed button state, otherwise return null. |
729 | */ | 729 | */ |
730 | static struct sway_binding* get_active_mouse_binding(const struct sway_cursor *cursor, | 730 | static struct sway_binding* get_active_mouse_binding( |
731 | list_t *bindings, uint32_t modifiers, bool release, bool on_titlebar, | 731 | const struct sway_cursor *cursor, list_t *bindings, uint32_t modifiers, |
732 | bool on_border, bool on_content) { | 732 | bool release, bool on_titlebar, bool on_border, bool on_content, |
733 | const char *identifier) { | ||
733 | uint32_t click_region = (on_titlebar ? BINDING_TITLEBAR : 0) | | 734 | uint32_t click_region = (on_titlebar ? BINDING_TITLEBAR : 0) | |
734 | (on_border ? BINDING_BORDER : 0) | | 735 | (on_border ? BINDING_BORDER : 0) | |
735 | (on_content ? BINDING_CONTENTS : 0); | 736 | (on_content ? BINDING_CONTENTS : 0); |
736 | 737 | ||
738 | struct sway_binding *current = NULL; | ||
737 | for (int i = 0; i < bindings->length; ++i) { | 739 | for (int i = 0; i < bindings->length; ++i) { |
738 | struct sway_binding *binding = bindings->items[i]; | 740 | struct sway_binding *binding = bindings->items[i]; |
739 | if (modifiers ^ binding->modifiers || | 741 | if (modifiers ^ binding->modifiers || |
740 | cursor->pressed_button_count != (size_t)binding->keys->length || | 742 | cursor->pressed_button_count != (size_t)binding->keys->length || |
741 | release != (binding->flags & BINDING_RELEASE) || | 743 | release != (binding->flags & BINDING_RELEASE) || |
742 | !(click_region & binding->flags)) { | 744 | !(click_region & binding->flags) || |
745 | (strcmp(binding->input, identifier) != 0 && | ||
746 | strcmp(binding->input, "*") != 0)) { | ||
743 | continue; | 747 | continue; |
744 | } | 748 | } |
745 | 749 | ||
@@ -755,13 +759,20 @@ static struct sway_binding* get_active_mouse_binding(const struct sway_cursor *c | |||
755 | continue; | 759 | continue; |
756 | } | 760 | } |
757 | 761 | ||
758 | return binding; | 762 | if (!current || strcmp(current->input, "*") == 0) { |
763 | current = binding; | ||
764 | if (strcmp(current->input, identifier) == 0) { | ||
765 | // If a binding is found for the exact input, quit searching | ||
766 | break; | ||
767 | } | ||
768 | } | ||
759 | } | 769 | } |
760 | return NULL; | 770 | return current; |
761 | } | 771 | } |
762 | 772 | ||
763 | void dispatch_cursor_button(struct sway_cursor *cursor, | 773 | void dispatch_cursor_button(struct sway_cursor *cursor, |
764 | uint32_t time_msec, uint32_t button, enum wlr_button_state state) { | 774 | struct wlr_input_device *device, uint32_t time_msec, uint32_t button, |
775 | enum wlr_button_state state) { | ||
765 | if (time_msec == 0) { | 776 | if (time_msec == 0) { |
766 | time_msec = get_current_time_msec(); | 777 | time_msec = get_current_time_msec(); |
767 | } | 778 | } |
@@ -797,18 +808,21 @@ void dispatch_cursor_button(struct sway_cursor *cursor, | |||
797 | struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat); | 808 | struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat); |
798 | uint32_t modifiers = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; | 809 | uint32_t modifiers = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; |
799 | 810 | ||
811 | char *device_identifier = device ? input_device_get_identifier(device) | ||
812 | : strdup("*"); | ||
800 | struct sway_binding *binding = NULL; | 813 | struct sway_binding *binding = NULL; |
801 | if (state == WLR_BUTTON_PRESSED) { | 814 | if (state == WLR_BUTTON_PRESSED) { |
802 | state_add_button(cursor, button); | 815 | state_add_button(cursor, button); |
803 | binding = get_active_mouse_binding(cursor, | 816 | binding = get_active_mouse_binding(cursor, |
804 | config->current_mode->mouse_bindings, modifiers, false, | 817 | config->current_mode->mouse_bindings, modifiers, false, |
805 | on_titlebar, on_border, on_contents); | 818 | on_titlebar, on_border, on_contents, device_identifier); |
806 | } else { | 819 | } else { |
807 | binding = get_active_mouse_binding(cursor, | 820 | binding = get_active_mouse_binding(cursor, |
808 | config->current_mode->mouse_bindings, modifiers, true, | 821 | config->current_mode->mouse_bindings, modifiers, true, |
809 | on_titlebar, on_border, on_contents); | 822 | on_titlebar, on_border, on_contents, device_identifier); |
810 | state_erase_button(cursor, button); | 823 | state_erase_button(cursor, button); |
811 | } | 824 | } |
825 | free(device_identifier); | ||
812 | if (binding) { | 826 | if (binding) { |
813 | seat_execute_command(seat, binding); | 827 | seat_execute_command(seat, binding); |
814 | return; | 828 | return; |
@@ -942,7 +956,7 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) { | |||
942 | struct sway_cursor *cursor = wl_container_of(listener, cursor, button); | 956 | struct sway_cursor *cursor = wl_container_of(listener, cursor, button); |
943 | wlr_idle_notify_activity(cursor->seat->input->server->idle, cursor->seat->wlr_seat); | 957 | wlr_idle_notify_activity(cursor->seat->input->server->idle, cursor->seat->wlr_seat); |
944 | struct wlr_event_pointer_button *event = data; | 958 | struct wlr_event_pointer_button *event = data; |
945 | dispatch_cursor_button(cursor, | 959 | dispatch_cursor_button(cursor, event->device, |
946 | event->time_msec, event->button, event->state); | 960 | event->time_msec, event->button, event->state); |
947 | transaction_commit_dirty(); | 961 | transaction_commit_dirty(); |
948 | } | 962 | } |
@@ -1128,7 +1142,7 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) { | |||
1128 | struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_tip); | 1142 | struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_tip); |
1129 | wlr_idle_notify_activity(cursor->seat->input->server->idle, cursor->seat->wlr_seat); | 1143 | wlr_idle_notify_activity(cursor->seat->input->server->idle, cursor->seat->wlr_seat); |
1130 | struct wlr_event_tablet_tool_tip *event = data; | 1144 | struct wlr_event_tablet_tool_tip *event = data; |
1131 | dispatch_cursor_button(cursor, event->time_msec, | 1145 | dispatch_cursor_button(cursor, event->device, event->time_msec, |
1132 | BTN_LEFT, event->state == WLR_TABLET_TOOL_TIP_DOWN ? | 1146 | BTN_LEFT, event->state == WLR_TABLET_TOOL_TIP_DOWN ? |
1133 | WLR_BUTTON_PRESSED : WLR_BUTTON_RELEASED); | 1147 | WLR_BUTTON_PRESSED : WLR_BUTTON_RELEASED); |
1134 | transaction_commit_dirty(); | 1148 | transaction_commit_dirty(); |
@@ -1143,14 +1157,14 @@ static void handle_tool_button(struct wl_listener *listener, void *data) { | |||
1143 | switch (event->state) { | 1157 | switch (event->state) { |
1144 | case WLR_BUTTON_PRESSED: | 1158 | case WLR_BUTTON_PRESSED: |
1145 | if (cursor->tool_buttons == 0) { | 1159 | if (cursor->tool_buttons == 0) { |
1146 | dispatch_cursor_button(cursor, | 1160 | dispatch_cursor_button(cursor, event->device, |
1147 | event->time_msec, BTN_RIGHT, event->state); | 1161 | event->time_msec, BTN_RIGHT, event->state); |
1148 | } | 1162 | } |
1149 | cursor->tool_buttons++; | 1163 | cursor->tool_buttons++; |
1150 | break; | 1164 | break; |
1151 | case WLR_BUTTON_RELEASED: | 1165 | case WLR_BUTTON_RELEASED: |
1152 | if (cursor->tool_buttons == 1) { | 1166 | if (cursor->tool_buttons == 1) { |
1153 | dispatch_cursor_button(cursor, | 1167 | dispatch_cursor_button(cursor, event->device, |
1154 | event->time_msec, BTN_RIGHT, event->state); | 1168 | event->time_msec, BTN_RIGHT, event->state); |
1155 | } | 1169 | } |
1156 | cursor->tool_buttons--; | 1170 | cursor->tool_buttons--; |
diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c index 70c2abf7..671f9a47 100644 --- a/sway/input/input-manager.c +++ b/sway/input/input-manager.c | |||
@@ -45,7 +45,7 @@ struct sway_seat *input_manager_get_seat( | |||
45 | return seat_create(input, seat_name); | 45 | return seat_create(input, seat_name); |
46 | } | 46 | } |
47 | 47 | ||
48 | static char *get_device_identifier(struct wlr_input_device *device) { | 48 | char *input_device_get_identifier(struct wlr_input_device *device) { |
49 | int vendor = device->vendor; | 49 | int vendor = device->vendor; |
50 | int product = device->product; | 50 | int product = device->product; |
51 | char *name = strdup(device->name); | 51 | char *name = strdup(device->name); |
@@ -278,7 +278,7 @@ static void handle_new_input(struct wl_listener *listener, void *data) { | |||
278 | device->data = input_device; | 278 | device->data = input_device; |
279 | 279 | ||
280 | input_device->wlr_device = device; | 280 | input_device->wlr_device = device; |
281 | input_device->identifier = get_device_identifier(device); | 281 | input_device->identifier = input_device_get_identifier(device); |
282 | wl_list_insert(&input->devices, &input_device->link); | 282 | wl_list_insert(&input->devices, &input_device->link); |
283 | 283 | ||
284 | wlr_log(WLR_DEBUG, "adding device: '%s'", | 284 | wlr_log(WLR_DEBUG, "adding device: '%s'", |
@@ -375,7 +375,7 @@ void handle_virtual_keyboard(struct wl_listener *listener, void *data) { | |||
375 | device->data = input_device; | 375 | device->data = input_device; |
376 | 376 | ||
377 | input_device->wlr_device = device; | 377 | input_device->wlr_device = device; |
378 | input_device->identifier = get_device_identifier(device); | 378 | input_device->identifier = input_device_get_identifier(device); |
379 | wl_list_insert(&input_manager->devices, &input_device->link); | 379 | wl_list_insert(&input_manager->devices, &input_device->link); |
380 | 380 | ||
381 | wlr_log(WLR_DEBUG, "adding virtual keyboard: '%s'", | 381 | wlr_log(WLR_DEBUG, "adding virtual keyboard: '%s'", |
diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index 2c8b41cd..4427dabe 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c | |||
@@ -87,7 +87,7 @@ static void update_shortcut_state(struct sway_shortcut_state *state, | |||
87 | */ | 87 | */ |
88 | static void get_active_binding(const struct sway_shortcut_state *state, | 88 | static void get_active_binding(const struct sway_shortcut_state *state, |
89 | list_t *bindings, struct sway_binding **current_binding, | 89 | list_t *bindings, struct sway_binding **current_binding, |
90 | uint32_t modifiers, bool release, bool locked) { | 90 | uint32_t modifiers, bool release, bool locked, const char *input) { |
91 | for (int i = 0; i < bindings->length; ++i) { | 91 | for (int i = 0; i < bindings->length; ++i) { |
92 | struct sway_binding *binding = bindings->items[i]; | 92 | struct sway_binding *binding = bindings->items[i]; |
93 | bool binding_locked = binding->flags & BINDING_LOCKED; | 93 | bool binding_locked = binding->flags & BINDING_LOCKED; |
@@ -96,7 +96,9 @@ static void get_active_binding(const struct sway_shortcut_state *state, | |||
96 | if (modifiers ^ binding->modifiers || | 96 | if (modifiers ^ binding->modifiers || |
97 | state->npressed != (size_t)binding->keys->length || | 97 | state->npressed != (size_t)binding->keys->length || |
98 | release != binding_release || | 98 | release != binding_release || |
99 | locked > binding_locked) { | 99 | locked > binding_locked || |
100 | (strcmp(binding->input, input) != 0 && | ||
101 | strcmp(binding->input, "*") != 0)) { | ||
100 | continue; | 102 | continue; |
101 | } | 103 | } |
102 | 104 | ||
@@ -112,13 +114,19 @@ static void get_active_binding(const struct sway_shortcut_state *state, | |||
112 | continue; | 114 | continue; |
113 | } | 115 | } |
114 | 116 | ||
115 | if (*current_binding && *current_binding != binding) { | 117 | if (*current_binding && *current_binding != binding && |
118 | strcmp((*current_binding)->input, binding->input) == 0) { | ||
116 | wlr_log(WLR_DEBUG, "encountered duplicate bindings %d and %d", | 119 | wlr_log(WLR_DEBUG, "encountered duplicate bindings %d and %d", |
117 | (*current_binding)->order, binding->order); | 120 | (*current_binding)->order, binding->order); |
118 | } else { | 121 | } else if (!*current_binding || |
122 | strcmp((*current_binding)->input, "*") == 0) { | ||
119 | *current_binding = binding; | 123 | *current_binding = binding; |
124 | |||
125 | if (strcmp((*current_binding)->input, input) == 0) { | ||
126 | // If a binding is found for the exact input, quit searching | ||
127 | return; | ||
128 | } | ||
120 | } | 129 | } |
121 | return; | ||
122 | } | 130 | } |
123 | } | 131 | } |
124 | 132 | ||
@@ -202,6 +210,7 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) { | |||
202 | struct wlr_seat *wlr_seat = seat->wlr_seat; | 210 | struct wlr_seat *wlr_seat = seat->wlr_seat; |
203 | struct wlr_input_device *wlr_device = | 211 | struct wlr_input_device *wlr_device = |
204 | keyboard->seat_device->input_device->wlr_device; | 212 | keyboard->seat_device->input_device->wlr_device; |
213 | char *device_identifier = input_device_get_identifier(wlr_device); | ||
205 | wlr_idle_notify_activity(seat->input->server->idle, wlr_seat); | 214 | wlr_idle_notify_activity(seat->input->server->idle, wlr_seat); |
206 | struct wlr_event_keyboard_key *event = data; | 215 | struct wlr_event_keyboard_key *event = data; |
207 | bool input_inhibited = seat->exclusive_client != NULL; | 216 | bool input_inhibited = seat->exclusive_client != NULL; |
@@ -242,13 +251,13 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) { | |||
242 | struct sway_binding *binding_released = NULL; | 251 | struct sway_binding *binding_released = NULL; |
243 | get_active_binding(&keyboard->state_keycodes, | 252 | get_active_binding(&keyboard->state_keycodes, |
244 | config->current_mode->keycode_bindings, &binding_released, | 253 | config->current_mode->keycode_bindings, &binding_released, |
245 | code_modifiers, true, input_inhibited); | 254 | code_modifiers, true, input_inhibited, device_identifier); |
246 | get_active_binding(&keyboard->state_keysyms_translated, | 255 | get_active_binding(&keyboard->state_keysyms_translated, |
247 | config->current_mode->keysym_bindings, &binding_released, | 256 | config->current_mode->keysym_bindings, &binding_released, |
248 | translated_modifiers, true, input_inhibited); | 257 | translated_modifiers, true, input_inhibited, device_identifier); |
249 | get_active_binding(&keyboard->state_keysyms_raw, | 258 | get_active_binding(&keyboard->state_keysyms_raw, |
250 | config->current_mode->keysym_bindings, &binding_released, | 259 | config->current_mode->keysym_bindings, &binding_released, |
251 | raw_modifiers, true, input_inhibited); | 260 | raw_modifiers, true, input_inhibited, device_identifier); |
252 | 261 | ||
253 | // Execute stored release binding once no longer active | 262 | // Execute stored release binding once no longer active |
254 | if (keyboard->held_binding && binding_released != keyboard->held_binding && | 263 | if (keyboard->held_binding && binding_released != keyboard->held_binding && |
@@ -268,13 +277,14 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) { | |||
268 | if (event->state == WLR_KEY_PRESSED) { | 277 | if (event->state == WLR_KEY_PRESSED) { |
269 | get_active_binding(&keyboard->state_keycodes, | 278 | get_active_binding(&keyboard->state_keycodes, |
270 | config->current_mode->keycode_bindings, &binding, | 279 | config->current_mode->keycode_bindings, &binding, |
271 | code_modifiers, false, input_inhibited); | 280 | code_modifiers, false, input_inhibited, device_identifier); |
272 | get_active_binding(&keyboard->state_keysyms_translated, | 281 | get_active_binding(&keyboard->state_keysyms_translated, |
273 | config->current_mode->keysym_bindings, &binding, | 282 | config->current_mode->keysym_bindings, &binding, |
274 | translated_modifiers, false, input_inhibited); | 283 | translated_modifiers, false, input_inhibited, |
284 | device_identifier); | ||
275 | get_active_binding(&keyboard->state_keysyms_raw, | 285 | get_active_binding(&keyboard->state_keysyms_raw, |
276 | config->current_mode->keysym_bindings, &binding, | 286 | config->current_mode->keysym_bindings, &binding, |
277 | raw_modifiers, false, input_inhibited); | 287 | raw_modifiers, false, input_inhibited, device_identifier); |
278 | 288 | ||
279 | if (binding) { | 289 | if (binding) { |
280 | seat_execute_command(seat, binding); | 290 | seat_execute_command(seat, binding); |
@@ -315,6 +325,8 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) { | |||
315 | } | 325 | } |
316 | 326 | ||
317 | transaction_commit_dirty(); | 327 | transaction_commit_dirty(); |
328 | |||
329 | free(device_identifier); | ||
318 | } | 330 | } |
319 | 331 | ||
320 | static int handle_keyboard_repeat(void *data) { | 332 | static int handle_keyboard_repeat(void *data) { |
diff --git a/sway/sway.5.scd b/sway/sway.5.scd index f6f0e859..e5e7918f 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd | |||
@@ -257,20 +257,22 @@ runtime. | |||
257 | 257 | ||
258 | for\_window <criteria> move container to output <output> | 258 | for\_window <criteria> move container to output <output> |
259 | 259 | ||
260 | *bindsym* [--release|--locked] <key combo> <command> | 260 | *bindsym* [--release|--locked] [--input-device=<device>] <key combo> <command> |
261 | Binds _key combo_ to execute the sway command _command_ when pressed. You | 261 | Binds _key combo_ to execute the sway command _command_ when pressed. You |
262 | may use XKB key names here (*xev*(1) is a good tool for discovering these). | 262 | may use XKB key names here (*xev*(1) is a good tool for discovering these). |
263 | With the flag _--release_, the command is executed when the key combo is | 263 | With the flag _--release_, the command is executed when the key combo is |
264 | released. Unless the flag _--locked_ is set, the command will not be run | 264 | released. Unless the flag _--locked_ is set, the command will not be run |
265 | when a screen locking program is active. | 265 | when a screen locking program is active. If _input-device_ is given, the |
266 | binding will only be executed for that input device and will be executed | ||
267 | instead of any binding that is generic to all devices. | ||
266 | 268 | ||
267 | Example: | 269 | Example: |
268 | 270 | ||
269 | # Execute firefox when alt, shift, and f are pressed together | 271 | # Execute firefox when alt, shift, and f are pressed together |
270 | bindsym Mod1+Shift+f exec firefox | 272 | bindsym Mod1+Shift+f exec firefox |
271 | 273 | ||
272 | *bindcode* [--release|--locked] <code> <command> is also available for | 274 | *bindcode* [--release|--locked] [--input-device=<device>] <code> <command> |
273 | binding with key codes instead of key names. | 275 | is also available for binding with key codes instead of key names. |
274 | 276 | ||
275 | *client.<class>* <border> <background> <text> <indicator> <child\_border> | 277 | *client.<class>* <border> <background> <text> <indicator> <child\_border> |
276 | Configures the color of window borders and title bars. All 5 colors are | 278 | Configures the color of window borders and title bars. All 5 colors are |