diff options
-rw-r--r-- | include/stringop.h | 7 | ||||
-rw-r--r-- | include/sway/config.h | 2 | ||||
-rw-r--r-- | meson.build | 16 | ||||
-rw-r--r-- | sway/commands.c | 61 | ||||
-rw-r--r-- | sway/commands/create_output.c | 4 | ||||
-rw-r--r-- | sway/commands/workspace.c | 13 | ||||
-rw-r--r-- | sway/commands/ws_auto_back_and_forth.c | 2 | ||||
-rw-r--r-- | sway/desktop/output.c | 9 | ||||
-rw-r--r-- | sway/ipc-json.c | 22 | ||||
-rw-r--r-- | sway/sway.5.scd | 8 | ||||
-rw-r--r-- | sway/tree/output.c | 7 | ||||
-rw-r--r-- | sway/tree/workspace.c | 61 | ||||
-rw-r--r-- | swaymsg/main.c | 11 |
13 files changed, 158 insertions, 65 deletions
diff --git a/include/stringop.h b/include/stringop.h index 01bbdaa9..919e605c 100644 --- a/include/stringop.h +++ b/include/stringop.h | |||
@@ -1,12 +1,7 @@ | |||
1 | #ifndef _SWAY_STRINGOP_H | 1 | #ifndef _SWAY_STRINGOP_H |
2 | #define _SWAY_STRINGOP_H | 2 | #define _SWAY_STRINGOP_H |
3 | #include <stdlib.h> | ||
4 | #include "list.h" | ||
5 | 3 | ||
6 | #if !HAVE_DECL_SETENV | 4 | #include "list.h" |
7 | // Not sure why we need to provide this | ||
8 | extern int setenv(const char *, const char *, int); | ||
9 | #endif | ||
10 | 5 | ||
11 | // array of whitespace characters to use for delims | 6 | // array of whitespace characters to use for delims |
12 | extern const char whitespace[]; | 7 | extern const char whitespace[]; |
diff --git a/include/sway/config.h b/include/sway/config.h index cd56c3dc..79c4359b 100644 --- a/include/sway/config.h +++ b/include/sway/config.h | |||
@@ -183,7 +183,7 @@ struct side_gaps { | |||
183 | */ | 183 | */ |
184 | struct workspace_config { | 184 | struct workspace_config { |
185 | char *workspace; | 185 | char *workspace; |
186 | char *output; | 186 | list_t *outputs; |
187 | int gaps_inner; | 187 | int gaps_inner; |
188 | struct side_gaps gaps_outer; | 188 | struct side_gaps gaps_outer; |
189 | }; | 189 | }; |
diff --git a/meson.build b/meson.build index 6b23b4e3..8327b763 100644 --- a/meson.build +++ b/meson.build | |||
@@ -9,11 +9,17 @@ project( | |||
9 | ], | 9 | ], |
10 | ) | 10 | ) |
11 | 11 | ||
12 | add_project_arguments('-Wno-unused-parameter', language: 'c') | 12 | add_project_arguments( |
13 | add_project_arguments('-Wno-unused-function', language: 'c') | 13 | [ |
14 | add_project_arguments('-Wno-unused-result', language: 'c') | 14 | '-DWL_HIDE_DEPRECATED', |
15 | add_project_arguments('-DWL_HIDE_DEPRECATED', language: 'c') | 15 | '-DWLR_USE_UNSTABLE', |
16 | add_project_arguments('-DWLR_USE_UNSTABLE', language: 'c') | 16 | |
17 | '-Wno-unused-parameter', | ||
18 | '-Wno-unused-result', | ||
19 | '-Wundef', | ||
20 | ], | ||
21 | language: 'c', | ||
22 | ) | ||
17 | 23 | ||
18 | cc = meson.get_compiler('c') | 24 | cc = meson.get_compiler('c') |
19 | 25 | ||
diff --git a/sway/commands.c b/sway/commands.c index 37c7169a..4b86c2fa 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -353,12 +353,14 @@ struct cmd_results *config_command(char *exec) { | |||
353 | struct cmd_results *results = NULL; | 353 | struct cmd_results *results = NULL; |
354 | int argc; | 354 | int argc; |
355 | char **argv = split_args(exec, &argc); | 355 | char **argv = split_args(exec, &argc); |
356 | |||
357 | // Check for empty lines | ||
356 | if (!argc) { | 358 | if (!argc) { |
357 | results = cmd_results_new(CMD_SUCCESS, NULL, NULL); | 359 | results = cmd_results_new(CMD_SUCCESS, NULL, NULL); |
358 | goto cleanup; | 360 | goto cleanup; |
359 | } | 361 | } |
360 | 362 | ||
361 | // Start block | 363 | // Check for the start of a block |
362 | if (argc > 1 && strcmp(argv[argc - 1], "{") == 0) { | 364 | if (argc > 1 && strcmp(argv[argc - 1], "{") == 0) { |
363 | char *block = join_args(argv, argc - 1); | 365 | char *block = join_args(argv, argc - 1); |
364 | results = cmd_results_new(CMD_BLOCK, block, NULL); | 366 | results = cmd_results_new(CMD_BLOCK, block, NULL); |
@@ -366,22 +368,54 @@ struct cmd_results *config_command(char *exec) { | |||
366 | goto cleanup; | 368 | goto cleanup; |
367 | } | 369 | } |
368 | 370 | ||
369 | // Endblock | 371 | // Check for the end of a block |
370 | if (strcmp(argv[argc - 1], "}") == 0) { | 372 | if (strcmp(argv[argc - 1], "}") == 0) { |
371 | results = cmd_results_new(CMD_BLOCK_END, NULL, NULL); | 373 | results = cmd_results_new(CMD_BLOCK_END, NULL, NULL); |
372 | goto cleanup; | 374 | goto cleanup; |
373 | } | 375 | } |
374 | wlr_log(WLR_INFO, "handling config command '%s'", exec); | 376 | |
377 | // Make sure the command is not stored in a variable | ||
378 | if (*argv[0] == '$') { | ||
379 | argv[0] = do_var_replacement(argv[0]); | ||
380 | char *temp = join_args(argv, argc); | ||
381 | free_argv(argc, argv); | ||
382 | argv = split_args(temp, &argc); | ||
383 | free(temp); | ||
384 | if (!argc) { | ||
385 | results = cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
386 | goto cleanup; | ||
387 | } | ||
388 | } | ||
389 | |||
390 | // Determine the command handler | ||
391 | wlr_log(WLR_INFO, "Config command: %s", exec); | ||
375 | struct cmd_handler *handler = find_handler(argv[0], NULL, 0); | 392 | struct cmd_handler *handler = find_handler(argv[0], NULL, 0); |
376 | if (!handler) { | 393 | if (!handler || !handler->handle) { |
377 | char *input = argv[0] ? argv[0] : "(empty)"; | 394 | char *input = argv[0] ? argv[0] : "(empty)"; |
378 | results = cmd_results_new(CMD_INVALID, input, "Unknown/invalid command"); | 395 | char *error = handler |
396 | ? "This command is shimmed, but unimplemented" | ||
397 | : "Unknown/invalid command"; | ||
398 | results = cmd_results_new(CMD_INVALID, input, error); | ||
379 | goto cleanup; | 399 | goto cleanup; |
380 | } | 400 | } |
381 | int i; | 401 | |
382 | // Var replacement, for all but first argument of set | 402 | // Do variable replacement |
383 | // TODO commands | 403 | if (handler->handle == cmd_set && argc > 1 && *argv[1] == '$') { |
384 | for (i = handler->handle == cmd_set ? 2 : 1; i < argc; ++i) { | 404 | // Escape the variable name so it does not get replaced by one shorter |
405 | char *temp = calloc(1, strlen(argv[1]) + 2); | ||
406 | temp[0] = '$'; | ||
407 | strcpy(&temp[1], argv[1]); | ||
408 | free(argv[1]); | ||
409 | argv[1] = temp; | ||
410 | } | ||
411 | char *command = do_var_replacement(join_args(argv, argc)); | ||
412 | wlr_log(WLR_INFO, "After replacement: %s", command); | ||
413 | free_argv(argc, argv); | ||
414 | argv = split_args(command, &argc); | ||
415 | free(command); | ||
416 | |||
417 | // Strip quotes and unescape the string | ||
418 | for (int i = handler->handle == cmd_set ? 2 : 1; i < argc; ++i) { | ||
385 | if (handler->handle != cmd_exec && handler->handle != cmd_exec_always | 419 | if (handler->handle != cmd_exec && handler->handle != cmd_exec_always |
386 | && handler->handle != cmd_bindsym | 420 | && handler->handle != cmd_bindsym |
387 | && handler->handle != cmd_bindcode | 421 | && handler->handle != cmd_bindcode |
@@ -389,14 +423,11 @@ struct cmd_results *config_command(char *exec) { | |||
389 | && (*argv[i] == '\"' || *argv[i] == '\'')) { | 423 | && (*argv[i] == '\"' || *argv[i] == '\'')) { |
390 | strip_quotes(argv[i]); | 424 | strip_quotes(argv[i]); |
391 | } | 425 | } |
392 | argv[i] = do_var_replacement(argv[i]); | ||
393 | unescape_string(argv[i]); | 426 | unescape_string(argv[i]); |
394 | } | 427 | } |
395 | if (handler->handle) { | 428 | |
396 | results = handler->handle(argc-1, argv+1); | 429 | // Run command |
397 | } else { | 430 | results = handler->handle(argc - 1, argv + 1); |
398 | results = cmd_results_new(CMD_INVALID, argv[0], "This command is shimmed, but unimplemented"); | ||
399 | } | ||
400 | 431 | ||
401 | cleanup: | 432 | cleanup: |
402 | free_argv(argc, argv); | 433 | free_argv(argc, argv); |
diff --git a/sway/commands/create_output.c b/sway/commands/create_output.c index 1c2464ea..3f870acb 100644 --- a/sway/commands/create_output.c +++ b/sway/commands/create_output.c | |||
@@ -1,7 +1,7 @@ | |||
1 | #include <wlr/config.h> | 1 | #include <wlr/config.h> |
2 | #include <wlr/backend/multi.h> | 2 | #include <wlr/backend/multi.h> |
3 | #include <wlr/backend/wayland.h> | 3 | #include <wlr/backend/wayland.h> |
4 | #ifdef WLR_HAS_X11_BACKEND | 4 | #if WLR_HAS_X11_BACKEND |
5 | #include <wlr/backend/x11.h> | 5 | #include <wlr/backend/x11.h> |
6 | #endif | 6 | #endif |
7 | #include "sway/commands.h" | 7 | #include "sway/commands.h" |
@@ -18,7 +18,7 @@ static void create_output(struct wlr_backend *backend, void *data) { | |||
18 | wlr_wl_output_create(backend); | 18 | wlr_wl_output_create(backend); |
19 | *done = true; | 19 | *done = true; |
20 | } | 20 | } |
21 | #ifdef WLR_HAS_X11_BACKEND | 21 | #if WLR_HAS_X11_BACKEND |
22 | else if (wlr_backend_is_x11(backend)) { | 22 | else if (wlr_backend_is_x11(backend)) { |
23 | wlr_x11_output_create(backend); | 23 | wlr_x11_output_create(backend); |
24 | *done = true; | 24 | *done = true; |
diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c index 168494d2..92118ecf 100644 --- a/sway/commands/workspace.c +++ b/sway/commands/workspace.c | |||
@@ -21,6 +21,7 @@ static struct workspace_config *workspace_config_find_or_create(char *ws_name) { | |||
21 | return NULL; | 21 | return NULL; |
22 | } | 22 | } |
23 | wsc->workspace = strdup(ws_name); | 23 | wsc->workspace = strdup(ws_name); |
24 | wsc->outputs = create_list(); | ||
24 | wsc->gaps_inner = INT_MIN; | 25 | wsc->gaps_inner = INT_MIN; |
25 | wsc->gaps_outer.top = INT_MIN; | 26 | wsc->gaps_outer.top = INT_MIN; |
26 | wsc->gaps_outer.right = INT_MIN; | 27 | wsc->gaps_outer.right = INT_MIN; |
@@ -32,7 +33,7 @@ static struct workspace_config *workspace_config_find_or_create(char *ws_name) { | |||
32 | 33 | ||
33 | void free_workspace_config(struct workspace_config *wsc) { | 34 | void free_workspace_config(struct workspace_config *wsc) { |
34 | free(wsc->workspace); | 35 | free(wsc->workspace); |
35 | free(wsc->output); | 36 | free_flat_list(wsc->outputs); |
36 | free(wsc); | 37 | free(wsc); |
37 | } | 38 | } |
38 | 39 | ||
@@ -141,18 +142,20 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { | |||
141 | } | 142 | } |
142 | } | 143 | } |
143 | if (output_location >= 0) { | 144 | if (output_location >= 0) { |
144 | if ((error = checkarg(argc, "workspace", EXPECTED_EQUAL_TO, output_location + 2))) { | 145 | if ((error = checkarg(argc, "workspace", EXPECTED_AT_LEAST, |
146 | output_location + 2))) { | ||
145 | return error; | 147 | return error; |
146 | } | 148 | } |
147 | char *ws_name = join_args(argv, argc - 2); | 149 | char *ws_name = join_args(argv, output_location); |
148 | struct workspace_config *wsc = workspace_config_find_or_create(ws_name); | 150 | struct workspace_config *wsc = workspace_config_find_or_create(ws_name); |
149 | free(ws_name); | 151 | free(ws_name); |
150 | if (!wsc) { | 152 | if (!wsc) { |
151 | return cmd_results_new(CMD_FAILURE, "workspace output", | 153 | return cmd_results_new(CMD_FAILURE, "workspace output", |
152 | "Unable to allocate workspace output"); | 154 | "Unable to allocate workspace output"); |
153 | } | 155 | } |
154 | free(wsc->output); | 156 | for (int i = output_location + 1; i < argc; ++i) { |
155 | wsc->output = strdup(argv[output_location + 1]); | 157 | list_add(wsc->outputs, strdup(argv[i])); |
158 | } | ||
156 | } else if (gaps_location >= 0) { | 159 | } else if (gaps_location >= 0) { |
157 | if ((error = cmd_workspace_gaps(argc, argv, gaps_location))) { | 160 | if ((error = cmd_workspace_gaps(argc, argv, gaps_location))) { |
158 | return error; | 161 | return error; |
diff --git a/sway/commands/ws_auto_back_and_forth.c b/sway/commands/ws_auto_back_and_forth.c index 3449d4cc..adb851c2 100644 --- a/sway/commands/ws_auto_back_and_forth.c +++ b/sway/commands/ws_auto_back_and_forth.c | |||
@@ -9,6 +9,6 @@ struct cmd_results *cmd_ws_auto_back_and_forth(int argc, char **argv) { | |||
9 | return error; | 9 | return error; |
10 | } | 10 | } |
11 | config->auto_back_and_forth = | 11 | config->auto_back_and_forth = |
12 | !parse_boolean(argv[0], config->auto_back_and_forth); | 12 | parse_boolean(argv[0], config->auto_back_and_forth); |
13 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 13 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
14 | } | 14 | } |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index d48ddef3..c53a9c73 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -469,15 +469,6 @@ void output_damage_box(struct sway_output *output, struct wlr_box *_box) { | |||
469 | wlr_output_damage_add_box(output->damage, &box); | 469 | wlr_output_damage_add_box(output->damage, &box); |
470 | } | 470 | } |
471 | 471 | ||
472 | static void output_damage_whole_container_iterator(struct sway_container *con, | ||
473 | void *data) { | ||
474 | if (!sway_assert(con->view, "expected a view")) { | ||
475 | return; | ||
476 | } | ||
477 | struct sway_output *output = data; | ||
478 | output_damage_view(output, con->view, true); | ||
479 | } | ||
480 | |||
481 | void output_damage_whole_container(struct sway_output *output, | 472 | void output_damage_whole_container(struct sway_output *output, |
482 | struct sway_container *con) { | 473 | struct sway_container *con) { |
483 | // Pad the box by 1px, because the width is a double and might be a fraction | 474 | // Pad the box by 1px, because the width is a double and might be a fraction |
diff --git a/sway/ipc-json.c b/sway/ipc-json.c index 4583558c..4d9a87d8 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include "sway/input/seat.h" | 12 | #include "sway/input/seat.h" |
13 | #include <wlr/types/wlr_box.h> | 13 | #include <wlr/types/wlr_box.h> |
14 | #include <wlr/types/wlr_output.h> | 14 | #include <wlr/types/wlr_output.h> |
15 | #include <xkbcommon/xkbcommon.h> | ||
15 | #include "wlr-layer-shell-unstable-v1-protocol.h" | 16 | #include "wlr-layer-shell-unstable-v1-protocol.h" |
16 | 17 | ||
17 | static const char *ipc_json_layout_description(enum sway_container_layout l) { | 18 | static const char *ipc_json_layout_description(enum sway_container_layout l) { |
@@ -503,6 +504,27 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) { | |||
503 | json_object_object_add(object, "type", | 504 | json_object_object_add(object, "type", |
504 | json_object_new_string(describe_device_type(device))); | 505 | json_object_new_string(describe_device_type(device))); |
505 | 506 | ||
507 | if (device->wlr_device->type == WLR_INPUT_DEVICE_KEYBOARD) { | ||
508 | struct wlr_keyboard *keyboard = device->wlr_device->keyboard; | ||
509 | struct xkb_keymap *keymap = keyboard->keymap; | ||
510 | struct xkb_state *state = keyboard->xkb_state; | ||
511 | xkb_layout_index_t num_layouts = xkb_keymap_num_layouts(keymap); | ||
512 | xkb_layout_index_t layout_idx; | ||
513 | for (layout_idx = 0; layout_idx < num_layouts; layout_idx++) { | ||
514 | bool is_active = | ||
515 | xkb_state_layout_index_is_active(state, | ||
516 | layout_idx, | ||
517 | XKB_STATE_LAYOUT_EFFECTIVE); | ||
518 | if (is_active) { | ||
519 | const char *layout = | ||
520 | xkb_keymap_layout_get_name(keymap, layout_idx); | ||
521 | json_object_object_add(object, "xkb_active_layout_name", | ||
522 | json_object_new_string(layout)); | ||
523 | break; | ||
524 | } | ||
525 | } | ||
526 | } | ||
527 | |||
506 | return object; | 528 | return object; |
507 | } | 529 | } |
508 | 530 | ||
diff --git a/sway/sway.5.scd b/sway/sway.5.scd index 8f6b35f1..1a11015f 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd | |||
@@ -573,8 +573,12 @@ The default colors are: | |||
573 | Specifies that workspace _name_ should have the given gaps settings when it | 573 | Specifies that workspace _name_ should have the given gaps settings when it |
574 | is created. | 574 | is created. |
575 | 575 | ||
576 | *workspace* <name> output <output> | 576 | *workspace* <name> output <outputs...> |
577 | Specifies that workspace _name_ should be shown on the specified _output_. | 577 | Specifies that workspace _name_ should be shown on the specified _outputs_. |
578 | Multiple outputs can be listed and the first available will be used. If the | ||
579 | workspace gets placed on an output further down the list and an output that | ||
580 | is higher on the list becomes available, the workspace will be move to the | ||
581 | higher priority output. | ||
578 | 582 | ||
579 | *workspace\_auto\_back\_and\_forth* yes|no | 583 | *workspace\_auto\_back\_and\_forth* yes|no |
580 | When _yes_, repeating a workspace switch command will switch back to the | 584 | When _yes_, repeating a workspace switch command will switch back to the |
diff --git a/sway/tree/output.c b/sway/tree/output.c index 2704920d..3c4614a8 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c | |||
@@ -31,6 +31,13 @@ static void restore_workspaces(struct sway_output *output) { | |||
31 | j--; | 31 | j--; |
32 | } | 32 | } |
33 | } | 33 | } |
34 | |||
35 | if (other->workspaces->length == 0) { | ||
36 | char *next = workspace_next_name(other->wlr_output->name); | ||
37 | struct sway_workspace *ws = workspace_create(other, next); | ||
38 | free(next); | ||
39 | ipc_event_workspace(NULL, ws, "init"); | ||
40 | } | ||
34 | } | 41 | } |
35 | 42 | ||
36 | // Saved workspaces | 43 | // Saved workspaces |
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 93ce50de..4be63311 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c | |||
@@ -33,14 +33,15 @@ struct workspace_config *workspace_find_config(const char *ws_name) { | |||
33 | struct sway_output *workspace_get_initial_output(const char *name) { | 33 | struct sway_output *workspace_get_initial_output(const char *name) { |
34 | // Check workspace configs for a workspace<->output pair | 34 | // Check workspace configs for a workspace<->output pair |
35 | struct workspace_config *wsc = workspace_find_config(name); | 35 | struct workspace_config *wsc = workspace_find_config(name); |
36 | if (wsc && wsc->output) { | 36 | if (wsc) { |
37 | struct sway_output *output = output_by_name(wsc->output); | 37 | for (int i = 0; i < wsc->outputs->length; i++) { |
38 | if (!output) { | 38 | struct sway_output *output = output_by_name(wsc->outputs->items[i]); |
39 | output = output_by_identifier(wsc->output); | 39 | if (!output) { |
40 | } | 40 | output = output_by_identifier(wsc->outputs->items[i]); |
41 | 41 | } | |
42 | if (output) { | 42 | if (output) { |
43 | return output; | 43 | return output; |
44 | } | ||
44 | } | 45 | } |
45 | } | 46 | } |
46 | // Otherwise put it on the focused output | 47 | // Otherwise put it on the focused output |
@@ -85,7 +86,6 @@ struct sway_workspace *workspace_create(struct sway_output *output, | |||
85 | ws->floating = create_list(); | 86 | ws->floating = create_list(); |
86 | ws->tiling = create_list(); | 87 | ws->tiling = create_list(); |
87 | ws->output_priority = create_list(); | 88 | ws->output_priority = create_list(); |
88 | workspace_output_add_priority(ws, output); | ||
89 | 89 | ||
90 | ws->gaps_outer = config->gaps_outer; | 90 | ws->gaps_outer = config->gaps_outer; |
91 | ws->gaps_inner = config->gaps_inner; | 91 | ws->gaps_inner = config->gaps_inner; |
@@ -110,9 +110,17 @@ struct sway_workspace *workspace_create(struct sway_output *output, | |||
110 | // Since default outer gaps can be smaller than the negation of | 110 | // Since default outer gaps can be smaller than the negation of |
111 | // workspace specific inner gaps, check outer gaps again | 111 | // workspace specific inner gaps, check outer gaps again |
112 | prevent_invalid_outer_gaps(ws); | 112 | prevent_invalid_outer_gaps(ws); |
113 | |||
114 | // Add output priorities | ||
115 | for (int i = 0; i < wsc->outputs->length; ++i) { | ||
116 | list_add(ws->output_priority, strdup(wsc->outputs->items[i])); | ||
117 | } | ||
113 | } | 118 | } |
114 | } | 119 | } |
115 | 120 | ||
121 | // If not already added, add the output to the lowest priority | ||
122 | workspace_output_add_priority(ws, output); | ||
123 | |||
116 | output_add_workspace(output, ws); | 124 | output_add_workspace(output, ws); |
117 | output_sort_workspaces(output); | 125 | output_sort_workspaces(output); |
118 | 126 | ||
@@ -134,8 +142,7 @@ void workspace_destroy(struct sway_workspace *workspace) { | |||
134 | 142 | ||
135 | free(workspace->name); | 143 | free(workspace->name); |
136 | free(workspace->representation); | 144 | free(workspace->representation); |
137 | list_foreach(workspace->output_priority, free); | 145 | free_flat_list(workspace->output_priority); |
138 | list_free(workspace->output_priority); | ||
139 | list_free(workspace->floating); | 146 | list_free(workspace->floating); |
140 | list_free(workspace->tiling); | 147 | list_free(workspace->tiling); |
141 | list_free(workspace->current.floating); | 148 | list_free(workspace->current.floating); |
@@ -177,8 +184,19 @@ static bool workspace_valid_on_output(const char *output_name, | |||
177 | char identifier[128]; | 184 | char identifier[128]; |
178 | struct sway_output *output = output_by_name(output_name); | 185 | struct sway_output *output = output_by_name(output_name); |
179 | output_get_identifier(identifier, sizeof(identifier), output); | 186 | output_get_identifier(identifier, sizeof(identifier), output); |
180 | 187 | ||
181 | return !wsc || !wsc->output || strcmp(wsc->output, output_name) == 0 || strcasecmp(identifier, output_name) == 0; | 188 | if (!wsc) { |
189 | return true; | ||
190 | } | ||
191 | |||
192 | for (int i = 0; i < wsc->outputs->length; i++) { | ||
193 | if (strcmp(wsc->outputs->items[i], output_name) == 0 || | ||
194 | strcmp(wsc->outputs->items[i], identifier) == 0) { | ||
195 | return true; | ||
196 | } | ||
197 | } | ||
198 | |||
199 | return false; | ||
182 | } | 200 | } |
183 | 201 | ||
184 | static void workspace_name_from_binding(const struct sway_binding * binding, | 202 | static void workspace_name_from_binding(const struct sway_binding * binding, |
@@ -281,10 +299,19 @@ char *workspace_next_name(const char *output_name) { | |||
281 | for (int i = 0; i < config->workspace_configs->length; ++i) { | 299 | for (int i = 0; i < config->workspace_configs->length; ++i) { |
282 | // Unlike with bindings, this does not guarantee order | 300 | // Unlike with bindings, this does not guarantee order |
283 | const struct workspace_config *wsc = config->workspace_configs->items[i]; | 301 | const struct workspace_config *wsc = config->workspace_configs->items[i]; |
284 | if (wsc->output && strcmp(wsc->output, output_name) == 0 | 302 | if (workspace_by_name(wsc->workspace)) { |
285 | && workspace_by_name(wsc->workspace) == NULL) { | 303 | continue; |
286 | free(target); | 304 | } |
287 | target = strdup(wsc->workspace); | 305 | bool found = false; |
306 | for (int j = 0; j < wsc->outputs->length; ++j) { | ||
307 | if (strcmp(wsc->outputs->items[j], output_name) == 0) { | ||
308 | found = true; | ||
309 | free(target); | ||
310 | target = strdup(wsc->workspace); | ||
311 | break; | ||
312 | } | ||
313 | } | ||
314 | if (found) { | ||
288 | break; | 315 | break; |
289 | } | 316 | } |
290 | } | 317 | } |
diff --git a/swaymsg/main.c b/swaymsg/main.c index 663518f6..243b5fdc 100644 --- a/swaymsg/main.c +++ b/swaymsg/main.c | |||
@@ -111,7 +111,7 @@ static const char *pretty_type_name(const char *name) { | |||
111 | } | 111 | } |
112 | 112 | ||
113 | static void pretty_print_input(json_object *i) { | 113 | static void pretty_print_input(json_object *i) { |
114 | json_object *id, *name, *type, *product, *vendor; | 114 | json_object *id, *name, *type, *product, *vendor, *kbdlayout; |
115 | json_object_object_get_ex(i, "identifier", &id); | 115 | json_object_object_get_ex(i, "identifier", &id); |
116 | json_object_object_get_ex(i, "name", &name); | 116 | json_object_object_get_ex(i, "name", &name); |
117 | json_object_object_get_ex(i, "type", &type); | 117 | json_object_object_get_ex(i, "type", &type); |
@@ -123,7 +123,7 @@ static void pretty_print_input(json_object *i) { | |||
123 | " Type: %s\n" | 123 | " Type: %s\n" |
124 | " Identifier: %s\n" | 124 | " Identifier: %s\n" |
125 | " Product ID: %d\n" | 125 | " Product ID: %d\n" |
126 | " Vendor ID: %d\n\n"; | 126 | " Vendor ID: %d\n"; |
127 | 127 | ||
128 | 128 | ||
129 | printf(fmt, json_object_get_string(name), | 129 | printf(fmt, json_object_get_string(name), |
@@ -131,6 +131,13 @@ static void pretty_print_input(json_object *i) { | |||
131 | json_object_get_string(id), | 131 | json_object_get_string(id), |
132 | json_object_get_int(product), | 132 | json_object_get_int(product), |
133 | json_object_get_int(vendor)); | 133 | json_object_get_int(vendor)); |
134 | |||
135 | if (json_object_object_get_ex(i, "xkb_active_layout_name", &kbdlayout)) { | ||
136 | printf(" Active Keyboard Layout: %s\n", | ||
137 | json_object_get_string(kbdlayout)); | ||
138 | } | ||
139 | |||
140 | printf("\n"); | ||
134 | } | 141 | } |
135 | 142 | ||
136 | static void pretty_print_seat(json_object *i) { | 143 | static void pretty_print_seat(json_object *i) { |