diff options
-rw-r--r-- | include/sway/commands.h | 1 | ||||
-rw-r--r-- | include/sway/config.h | 1 | ||||
-rw-r--r-- | sway/commands.c | 1 | ||||
-rw-r--r-- | sway/commands/seat.c | 2 | ||||
-rw-r--r-- | sway/commands/seat/fallback.c | 29 | ||||
-rw-r--r-- | sway/config/seat.c | 5 | ||||
-rw-r--r-- | sway/input/input-manager.c | 83 | ||||
-rw-r--r-- | sway/input/seat.c | 3 | ||||
-rw-r--r-- | sway/meson.build | 1 |
9 files changed, 100 insertions, 26 deletions
diff --git a/include/sway/commands.h b/include/sway/commands.h index 5008831d..4ee7af2a 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h | |||
@@ -198,6 +198,7 @@ sway_cmd input_cmd_xkb_options; | |||
198 | sway_cmd input_cmd_xkb_rules; | 198 | sway_cmd input_cmd_xkb_rules; |
199 | sway_cmd input_cmd_xkb_variant; | 199 | sway_cmd input_cmd_xkb_variant; |
200 | 200 | ||
201 | sway_cmd seat_cmd_fallback; | ||
201 | sway_cmd seat_cmd_attach; | 202 | sway_cmd seat_cmd_attach; |
202 | 203 | ||
203 | sway_cmd cmd_ipc_cmd; | 204 | sway_cmd cmd_ipc_cmd; |
diff --git a/include/sway/config.h b/include/sway/config.h index eb642dc2..fdfbbedb 100644 --- a/include/sway/config.h +++ b/include/sway/config.h | |||
@@ -90,6 +90,7 @@ struct seat_attachment_config { | |||
90 | */ | 90 | */ |
91 | struct seat_config { | 91 | struct seat_config { |
92 | char *name; | 92 | char *name; |
93 | int fallback; // -1 means not set | ||
93 | list_t *attachments; // list of seat_attachment configs | 94 | list_t *attachments; // list of seat_attachment configs |
94 | }; | 95 | }; |
95 | 96 | ||
diff --git a/sway/commands.c b/sway/commands.c index 3fb1842d..34afb6a0 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -165,6 +165,7 @@ static struct cmd_handler input_handlers[] = { | |||
165 | // must be in order for the bsearch | 165 | // must be in order for the bsearch |
166 | static struct cmd_handler seat_handlers[] = { | 166 | static struct cmd_handler seat_handlers[] = { |
167 | { "attach", seat_cmd_attach }, | 167 | { "attach", seat_cmd_attach }, |
168 | { "fallback", seat_cmd_fallback }, | ||
168 | }; | 169 | }; |
169 | 170 | ||
170 | static struct cmd_handler *find_handler(char *line, enum cmd_status block) { | 171 | static struct cmd_handler *find_handler(char *line, enum cmd_status block) { |
diff --git a/sway/commands/seat.c b/sway/commands/seat.c index 4f9e259b..0149762a 100644 --- a/sway/commands/seat.c +++ b/sway/commands/seat.c | |||
@@ -24,6 +24,8 @@ struct cmd_results *cmd_seat(int argc, char **argv) { | |||
24 | current_seat_config = new_seat_config(argv[0]); | 24 | current_seat_config = new_seat_config(argv[0]); |
25 | if (strcasecmp("attach", argv[1]) == 0) { | 25 | if (strcasecmp("attach", argv[1]) == 0) { |
26 | res = seat_cmd_attach(argc_new, argv_new); | 26 | res = seat_cmd_attach(argc_new, argv_new); |
27 | } else if (strcasecmp("fallback", argv[1]) == 0) { | ||
28 | res = seat_cmd_fallback(argc_new, argv_new); | ||
27 | } else { | 29 | } else { |
28 | res = cmd_results_new(CMD_INVALID, "seat <name>", "Unknown command %s", argv[1]); | 30 | res = cmd_results_new(CMD_INVALID, "seat <name>", "Unknown command %s", argv[1]); |
29 | } | 31 | } |
diff --git a/sway/commands/seat/fallback.c b/sway/commands/seat/fallback.c new file mode 100644 index 00000000..7c129aae --- /dev/null +++ b/sway/commands/seat/fallback.c | |||
@@ -0,0 +1,29 @@ | |||
1 | #include <string.h> | ||
2 | #include <strings.h> | ||
3 | #include "sway/config.h" | ||
4 | #include "sway/commands.h" | ||
5 | #include "sway/input/input-manager.h" | ||
6 | |||
7 | struct cmd_results *seat_cmd_fallback(int argc, char **argv) { | ||
8 | struct cmd_results *error = NULL; | ||
9 | if ((error = checkarg(argc, "fallback", EXPECTED_AT_LEAST, 1))) { | ||
10 | return error; | ||
11 | } | ||
12 | if (!current_seat_config) { | ||
13 | return cmd_results_new(CMD_FAILURE, "fallback", "No seat defined"); | ||
14 | } | ||
15 | struct seat_config *new_config = | ||
16 | new_seat_config(current_seat_config->name); | ||
17 | |||
18 | if (strcasecmp(argv[0], "true") == 0) { | ||
19 | new_config->fallback = 1; | ||
20 | } else if (strcasecmp(argv[0], "false") == 0) { | ||
21 | new_config->fallback = 0; | ||
22 | } else { | ||
23 | return cmd_results_new(CMD_INVALID, "fallback", | ||
24 | "Expected 'fallback <true|false>'"); | ||
25 | } | ||
26 | |||
27 | apply_seat_config(new_config); | ||
28 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
29 | } | ||
diff --git a/sway/config/seat.c b/sway/config/seat.c index 3a2fdaa6..4c9e8d0d 100644 --- a/sway/config/seat.c +++ b/sway/config/seat.c | |||
@@ -17,6 +17,7 @@ struct seat_config *new_seat_config(const char* name) { | |||
17 | return NULL; | 17 | return NULL; |
18 | } | 18 | } |
19 | 19 | ||
20 | seat->fallback = -1; | ||
20 | seat->attachments = create_list(); | 21 | seat->attachments = create_list(); |
21 | if (!sway_assert(seat->attachments, | 22 | if (!sway_assert(seat->attachments, |
22 | "could not allocate seat attachments list")) { | 23 | "could not allocate seat attachments list")) { |
@@ -66,6 +67,10 @@ void merge_seat_config(struct seat_config *dest, struct seat_config *source) { | |||
66 | dest->name = strdup(source->name); | 67 | dest->name = strdup(source->name); |
67 | } | 68 | } |
68 | 69 | ||
70 | if (source->fallback != -1) { | ||
71 | dest->fallback = source->fallback; | ||
72 | } | ||
73 | |||
69 | for (int i = 0; i < source->attachments->length; ++i) { | 74 | for (int i = 0; i < source->attachments->length; ++i) { |
70 | struct seat_attachment_config *source_attachment = | 75 | struct seat_attachment_config *source_attachment = |
71 | source->attachments->items[i]; | 76 | source->attachments->items[i]; |
diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c index fa8e4b49..16301489 100644 --- a/sway/input/input-manager.c +++ b/sway/input/input-manager.c | |||
@@ -56,9 +56,9 @@ static char *get_device_identifier(struct wlr_input_device *device) { | |||
56 | 56 | ||
57 | int len = | 57 | int len = |
58 | (strlen(name) + | 58 | (strlen(name) + |
59 | strlen_num(device->vendor) + | 59 | strlen_num(device->vendor) + |
60 | strlen_num(device->product) + | 60 | strlen_num(device->product) + |
61 | 3) * sizeof(char); | 61 | 3) * sizeof(char); |
62 | 62 | ||
63 | char *identifier = malloc(len); | 63 | char *identifier = malloc(len); |
64 | if (!identifier) { | 64 | if (!identifier) { |
@@ -151,13 +151,30 @@ static void input_add_notify(struct wl_listener *listener, void *data) { | |||
151 | return; | 151 | return; |
152 | } | 152 | } |
153 | 153 | ||
154 | bool added = false; | ||
154 | wl_list_for_each(seat, &input->seats, link) { | 155 | wl_list_for_each(seat, &input->seats, link) { |
155 | if (seat->config && | 156 | if (seat->config && |
156 | (seat_config_get_attachment(seat->config, input_device->identifier) || | 157 | (seat_config_get_attachment(seat->config, input_device->identifier) || |
157 | seat_config_get_attachment(seat->config, "*"))) { | 158 | seat_config_get_attachment(seat->config, "*"))) { |
158 | sway_seat_add_device(seat, input_device); | 159 | sway_seat_add_device(seat, input_device); |
160 | added = true; | ||
159 | } | 161 | } |
160 | } | 162 | } |
163 | |||
164 | if (!added) { | ||
165 | wl_list_for_each(seat, &input->seats, link) { | ||
166 | if (seat->config && seat->config->fallback == 1) { | ||
167 | sway_seat_add_device(seat, input_device); | ||
168 | added = true; | ||
169 | } | ||
170 | } | ||
171 | } | ||
172 | |||
173 | if (!added) { | ||
174 | sway_log(L_DEBUG, | ||
175 | "device '%s' is not configured on any seats", | ||
176 | input_device->identifier); | ||
177 | } | ||
161 | } | 178 | } |
162 | 179 | ||
163 | static void input_remove_notify(struct wl_listener *listener, void *data) { | 180 | static void input_remove_notify(struct wl_listener *listener, void *data) { |
@@ -248,35 +265,53 @@ void sway_input_manager_apply_seat_config(struct sway_input_manager *input, | |||
248 | struct seat_config *seat_config) { | 265 | struct seat_config *seat_config) { |
249 | sway_log(L_DEBUG, "applying new seat config for seat %s", seat_config->name); | 266 | sway_log(L_DEBUG, "applying new seat config for seat %s", seat_config->name); |
250 | struct sway_seat *seat = input_manager_get_seat(input, seat_config->name); | 267 | struct sway_seat *seat = input_manager_get_seat(input, seat_config->name); |
251 | // the old config is invalid so clear it | 268 | if (!seat) { |
252 | sway_seat_set_config(seat, NULL); | 269 | return; |
270 | } | ||
271 | |||
272 | sway_seat_set_config(seat, seat_config); | ||
253 | 273 | ||
254 | // clear devices | 274 | // for every device, try to add it to a seat and if no seat has it |
275 | // attached, add it to the fallback seats. | ||
255 | struct sway_input_device *input_device = NULL; | 276 | struct sway_input_device *input_device = NULL; |
256 | wl_list_for_each(input_device, &input->devices, link) { | 277 | wl_list_for_each(input_device, &input->devices, link) { |
257 | sway_seat_remove_device(seat, input_device); | 278 | list_t *seat_list = create_list(); |
258 | } | 279 | struct sway_seat *seat = NULL; |
259 | 280 | wl_list_for_each(seat, &input->seats, link) { | |
260 | if (seat_config_get_attachment(seat_config, "*")) { | 281 | if (!seat->config) { |
261 | wl_list_for_each(input_device, &input->devices, link) { | 282 | continue; |
262 | sway_seat_add_device(seat, input_device); | 283 | } |
284 | if (seat_config_get_attachment(seat->config, "*") || | ||
285 | seat_config_get_attachment(seat->config, input_device->identifier)) { | ||
286 | list_add(seat_list, seat); | ||
287 | } | ||
263 | } | 288 | } |
264 | } else { | ||
265 | for (int i = 0; i < seat_config->attachments->length; ++i) { | ||
266 | struct seat_attachment_config *attachment = | ||
267 | seat_config->attachments->items[i]; | ||
268 | |||
269 | struct sway_input_device *device = | ||
270 | input_sway_device_from_identifier(input, | ||
271 | attachment->identifier); | ||
272 | 289 | ||
273 | if (device) { | 290 | if (seat_list->length) { |
274 | sway_seat_add_device(seat, device); | 291 | wl_list_for_each(seat, &input->seats, link) { |
292 | bool attached = false; | ||
293 | for (int i = 0; i < seat_list->length; ++i) { | ||
294 | if (seat == seat_list->items[i]) { | ||
295 | attached = true; | ||
296 | break; | ||
297 | } | ||
298 | } | ||
299 | if (attached) { | ||
300 | sway_seat_add_device(seat, input_device); | ||
301 | } else { | ||
302 | sway_seat_remove_device(seat, input_device); | ||
303 | } | ||
304 | } | ||
305 | } else { | ||
306 | wl_list_for_each(seat, &input->seats, link) { | ||
307 | if (seat->config && seat->config->fallback == 1) { | ||
308 | sway_seat_add_device(seat, input_device); | ||
309 | } else { | ||
310 | sway_seat_remove_device(seat, input_device); | ||
311 | } | ||
275 | } | 312 | } |
276 | } | 313 | } |
277 | } | 314 | } |
278 | |||
279 | sway_seat_set_config(seat, seat_config); | ||
280 | } | 315 | } |
281 | 316 | ||
282 | void sway_input_manager_configure_xcursor(struct sway_input_manager *input) { | 317 | void sway_input_manager_configure_xcursor(struct sway_input_manager *input) { |
diff --git a/sway/input/seat.c b/sway/input/seat.c index 8fe82b46..94503687 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -120,6 +120,7 @@ void sway_seat_configure_device(struct sway_seat *seat, | |||
120 | void sway_seat_add_device(struct sway_seat *seat, | 120 | void sway_seat_add_device(struct sway_seat *seat, |
121 | struct sway_input_device *input_device) { | 121 | struct sway_input_device *input_device) { |
122 | if (sway_seat_get_device(seat, input_device)) { | 122 | if (sway_seat_get_device(seat, input_device)) { |
123 | sway_seat_configure_device(seat, input_device); | ||
123 | return; | 124 | return; |
124 | } | 125 | } |
125 | 126 | ||
@@ -246,7 +247,5 @@ void sway_seat_set_config(struct sway_seat *seat, | |||
246 | seat_device->attachment_config = | 247 | seat_device->attachment_config = |
247 | seat_config_get_attachment(seat_config, | 248 | seat_config_get_attachment(seat_config, |
248 | seat_device->input_device->identifier); | 249 | seat_device->input_device->identifier); |
249 | sway_seat_configure_device(seat, seat_device->input_device); | ||
250 | } | 250 | } |
251 | |||
252 | } | 251 | } |
diff --git a/sway/meson.build b/sway/meson.build index 3d38c7c9..fee2ddd2 100644 --- a/sway/meson.build +++ b/sway/meson.build | |||
@@ -13,6 +13,7 @@ sway_sources = files( | |||
13 | 'commands/input.c', | 13 | 'commands/input.c', |
14 | 'commands/seat.c', | 14 | 'commands/seat.c', |
15 | 'commands/seat/attach.c', | 15 | 'commands/seat/attach.c', |
16 | 'commands/seat/fallback.c', | ||
16 | 'commands/input/accel_profile.c', | 17 | 'commands/input/accel_profile.c', |
17 | 'commands/input/click_method.c', | 18 | 'commands/input/click_method.c', |
18 | 'commands/input/drag_lock.c', | 19 | 'commands/input/drag_lock.c', |