diff options
-rw-r--r-- | include/sway/commands.h | 3 | ||||
-rw-r--r-- | include/sway/criteria.h | 3 | ||||
-rw-r--r-- | sway/commands.c | 79 | ||||
-rw-r--r-- | sway/commands/border.c | 2 | ||||
-rw-r--r-- | sway/commands/floating.c | 2 | ||||
-rw-r--r-- | sway/commands/focus.c | 3 | ||||
-rw-r--r-- | sway/commands/fullscreen.c | 2 | ||||
-rw-r--r-- | sway/commands/kill.c | 2 | ||||
-rw-r--r-- | sway/commands/layout.c | 2 | ||||
-rw-r--r-- | sway/commands/mark.c | 4 | ||||
-rw-r--r-- | sway/commands/move.c | 4 | ||||
-rw-r--r-- | sway/commands/resize.c | 12 | ||||
-rw-r--r-- | sway/commands/split.c | 6 | ||||
-rw-r--r-- | sway/commands/unmark.c | 2 | ||||
-rw-r--r-- | sway/criteria.c | 27 | ||||
-rw-r--r-- | sway/sway.5.txt | 16 |
16 files changed, 116 insertions, 53 deletions
diff --git a/include/sway/commands.h b/include/sway/commands.h index 35a2f92a..91f2ae01 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h | |||
@@ -5,6 +5,9 @@ | |||
5 | #include <wlc/wlc.h> | 5 | #include <wlc/wlc.h> |
6 | #include "config.h" | 6 | #include "config.h" |
7 | 7 | ||
8 | // Container that a called command should act upon. Only valid in command functions. | ||
9 | extern swayc_t *current_container; | ||
10 | |||
8 | /** | 11 | /** |
9 | * Indicates the result of a command's execution. | 12 | * Indicates the result of a command's execution. |
10 | */ | 13 | */ |
diff --git a/include/sway/criteria.h b/include/sway/criteria.h index 5c71d172..022c48a8 100644 --- a/include/sway/criteria.h +++ b/include/sway/criteria.h | |||
@@ -33,4 +33,7 @@ char *extract_crit_tokens(list_t *tokens, const char *criteria); | |||
33 | // been set with `for_window` commands and have an associated cmdlist. | 33 | // been set with `for_window` commands and have an associated cmdlist. |
34 | list_t *criteria_for(swayc_t *cont); | 34 | list_t *criteria_for(swayc_t *cont); |
35 | 35 | ||
36 | // Returns a list of all containers that match the given list of tokens. | ||
37 | list_t *container_for(list_t *tokens); | ||
38 | |||
36 | #endif | 39 | #endif |
diff --git a/sway/commands.c b/sway/commands.c index 971ff505..17c7d717 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -43,6 +43,8 @@ struct cmd_handler { | |||
43 | 43 | ||
44 | int sp_index = 0; | 44 | int sp_index = 0; |
45 | 45 | ||
46 | swayc_t *current_container = NULL; | ||
47 | |||
46 | // Returns error object, or NULL if check succeeds. | 48 | // Returns error object, or NULL if check succeeds. |
47 | struct cmd_results *checkarg(int argc, const char *name, enum expected_args type, int val) { | 49 | struct cmd_results *checkarg(int argc, const char *name, enum expected_args type, int val) { |
48 | struct cmd_results *error = NULL; | 50 | struct cmd_results *error = NULL; |
@@ -371,42 +373,37 @@ struct cmd_results *handle_command(char *_exec, enum command_context context) { | |||
371 | char *head = exec; | 373 | char *head = exec; |
372 | char *cmdlist; | 374 | char *cmdlist; |
373 | char *cmd; | 375 | char *cmd; |
374 | char *criteria __attribute__((unused)); | 376 | list_t *containers = NULL; |
375 | 377 | ||
376 | head = exec; | 378 | head = exec; |
377 | do { | 379 | do { |
378 | // Extract criteria (valid for this command list only). | 380 | // Extract criteria (valid for this command list only). |
379 | criteria = NULL; | ||
380 | if (*head == '[') { | 381 | if (*head == '[') { |
381 | ++head; | 382 | ++head; |
382 | criteria = argsep(&head, "]"); | 383 | char *criteria_string = argsep(&head, "]"); |
383 | if (head) { | 384 | if (head) { |
384 | ++head; | 385 | ++head; |
385 | // TODO handle criteria | 386 | list_t *tokens = create_list(); |
387 | char *error; | ||
388 | |||
389 | if ((error = extract_crit_tokens(tokens, criteria_string))) { | ||
390 | results = cmd_results_new(CMD_INVALID, criteria_string, | ||
391 | "Can't parse criteria string: %s", error); | ||
392 | free(error); | ||
393 | free(tokens); | ||
394 | goto cleanup; | ||
395 | } | ||
396 | containers = container_for(tokens); | ||
397 | |||
398 | free(tokens); | ||
386 | } else { | 399 | } else { |
387 | if (!results) { | 400 | if (!results) { |
388 | results = cmd_results_new(CMD_INVALID, criteria, "Unmatched ["); | 401 | results = cmd_results_new(CMD_INVALID, criteria_string, "Unmatched ["); |
389 | } | 402 | } |
390 | goto cleanup; | 403 | goto cleanup; |
391 | } | 404 | } |
392 | // Skip leading whitespace | 405 | // Skip leading whitespace |
393 | head += strspn(head, whitespace); | 406 | head += strspn(head, whitespace); |
394 | |||
395 | // TODO: it will yield unexpected results to execute commands | ||
396 | // (on any view) that where meant for certain views only. | ||
397 | if (!results) { | ||
398 | int len = strlen(criteria) + strlen(head) + 4; | ||
399 | char *tmp = malloc(len); | ||
400 | if (tmp) { | ||
401 | snprintf(tmp, len, "[%s] %s", criteria, head); | ||
402 | } else { | ||
403 | sway_log(L_DEBUG, "Unable to allocate criteria string for cmd result"); | ||
404 | } | ||
405 | results = cmd_results_new(CMD_INVALID, tmp, | ||
406 | "Can't handle criteria string: Refusing to execute command"); | ||
407 | free(tmp); | ||
408 | } | ||
409 | goto cleanup; | ||
410 | } | 407 | } |
411 | // Split command list | 408 | // Split command list |
412 | cmdlist = argsep(&head, ";"); | 409 | cmdlist = argsep(&head, ";"); |
@@ -450,21 +447,43 @@ struct cmd_results *handle_command(char *_exec, enum command_context context) { | |||
450 | free_argv(argc, argv); | 447 | free_argv(argc, argv); |
451 | goto cleanup; | 448 | goto cleanup; |
452 | } | 449 | } |
453 | struct cmd_results *res = handler->handle(argc-1, argv+1); | 450 | int i = 0; |
454 | if (res->status != CMD_SUCCESS) { | 451 | do { |
455 | free_argv(argc, argv); | 452 | if (!containers) { |
456 | if (results) { | 453 | current_container = get_focused_container(&root_container); |
457 | free_cmd_results(results); | 454 | } else if (containers->length == 0) { |
455 | break; | ||
456 | } else { | ||
457 | current_container = (swayc_t *)containers->items[i]; | ||
458 | } | 458 | } |
459 | results = res; | 459 | sway_log(L_INFO, "Running on container '%s'", current_container->name); |
460 | goto cleanup; | 460 | |
461 | } | 461 | struct cmd_results *res = handler->handle(argc-1, argv+1); |
462 | if (res->status != CMD_SUCCESS) { | ||
463 | free_argv(argc, argv); | ||
464 | if (results) { | ||
465 | free_cmd_results(results); | ||
466 | } | ||
467 | results = res; | ||
468 | goto cleanup; | ||
469 | } | ||
470 | free_cmd_results(res); | ||
471 | ++i; | ||
472 | } while(containers && i < containers->length); | ||
473 | |||
462 | free_argv(argc, argv); | 474 | free_argv(argc, argv); |
463 | free_cmd_results(res); | ||
464 | } while(cmdlist); | 475 | } while(cmdlist); |
476 | |||
477 | if (containers) { | ||
478 | list_free(containers); | ||
479 | containers = NULL; | ||
480 | } | ||
465 | } while(head); | 481 | } while(head); |
466 | cleanup: | 482 | cleanup: |
467 | free(exec); | 483 | free(exec); |
484 | if (containers) { | ||
485 | free(containers); | ||
486 | } | ||
468 | if (!results) { | 487 | if (!results) { |
469 | results = cmd_results_new(CMD_SUCCESS, NULL, NULL); | 488 | results = cmd_results_new(CMD_SUCCESS, NULL, NULL); |
470 | } | 489 | } |
diff --git a/sway/commands/border.c b/sway/commands/border.c index 0211e40c..c888622e 100644 --- a/sway/commands/border.c +++ b/sway/commands/border.c | |||
@@ -20,7 +20,7 @@ struct cmd_results *cmd_border(int argc, char **argv) { | |||
20 | "Expected 'border <normal|pixel|none|toggle> [<n>]"); | 20 | "Expected 'border <normal|pixel|none|toggle> [<n>]"); |
21 | } | 21 | } |
22 | 22 | ||
23 | swayc_t *view = get_focused_view(&root_container); | 23 | swayc_t *view = current_container; |
24 | enum swayc_border_types border = view->border_type; | 24 | enum swayc_border_types border = view->border_type; |
25 | int thickness = view->border_thickness; | 25 | int thickness = view->border_thickness; |
26 | 26 | ||
diff --git a/sway/commands/floating.c b/sway/commands/floating.c index 113c8b71..ccfde532 100644 --- a/sway/commands/floating.c +++ b/sway/commands/floating.c | |||
@@ -13,7 +13,7 @@ struct cmd_results *cmd_floating(int argc, char **argv) { | |||
13 | if ((error = checkarg(argc, "floating", EXPECTED_EQUAL_TO, 1))) { | 13 | if ((error = checkarg(argc, "floating", EXPECTED_EQUAL_TO, 1))) { |
14 | return error; | 14 | return error; |
15 | } | 15 | } |
16 | swayc_t *view = get_focused_container(&root_container); | 16 | swayc_t *view = current_container; |
17 | bool wants_floating; | 17 | bool wants_floating; |
18 | if (strcasecmp(argv[0], "enable") == 0) { | 18 | if (strcasecmp(argv[0], "enable") == 0) { |
19 | wants_floating = true; | 19 | wants_floating = true; |
diff --git a/sway/commands/focus.c b/sway/commands/focus.c index 12c5d02c..defaba29 100644 --- a/sway/commands/focus.c +++ b/sway/commands/focus.c | |||
@@ -30,6 +30,9 @@ struct cmd_results *cmd_focus(int argc, char **argv) { | |||
30 | } | 30 | } |
31 | } | 31 | } |
32 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 32 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
33 | } else if (argc == 0) { | ||
34 | set_focused_container(current_container); | ||
35 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
33 | } else if ((error = checkarg(argc, "focus", EXPECTED_EQUAL_TO, 1))) { | 36 | } else if ((error = checkarg(argc, "focus", EXPECTED_EQUAL_TO, 1))) { |
34 | return error; | 37 | return error; |
35 | } | 38 | } |
diff --git a/sway/commands/fullscreen.c b/sway/commands/fullscreen.c index 321d6f59..bfff82f9 100644 --- a/sway/commands/fullscreen.c +++ b/sway/commands/fullscreen.c | |||
@@ -14,7 +14,7 @@ struct cmd_results *cmd_fullscreen(int argc, char **argv) { | |||
14 | if ((error = checkarg(argc, "fullscreen", EXPECTED_AT_LEAST, 0))) { | 14 | if ((error = checkarg(argc, "fullscreen", EXPECTED_AT_LEAST, 0))) { |
15 | return error; | 15 | return error; |
16 | } | 16 | } |
17 | swayc_t *container = get_focused_view(&root_container); | 17 | swayc_t *container = current_container; |
18 | if(container->type != C_VIEW){ | 18 | if(container->type != C_VIEW){ |
19 | return cmd_results_new(CMD_INVALID, "fullscreen", "Only views can fullscreen"); | 19 | return cmd_results_new(CMD_INVALID, "fullscreen", "Only views can fullscreen"); |
20 | } | 20 | } |
diff --git a/sway/commands/kill.c b/sway/commands/kill.c index 2e94fb10..742e2b86 100644 --- a/sway/commands/kill.c +++ b/sway/commands/kill.c | |||
@@ -6,7 +6,7 @@ struct cmd_results *cmd_kill(int argc, char **argv) { | |||
6 | if (config->reading) return cmd_results_new(CMD_FAILURE, "kill", "Can't be used in config file."); | 6 | if (config->reading) return cmd_results_new(CMD_FAILURE, "kill", "Can't be used in config file."); |
7 | if (!config->active) return cmd_results_new(CMD_FAILURE, "kill", "Can only be used when sway is running."); | 7 | if (!config->active) return cmd_results_new(CMD_FAILURE, "kill", "Can only be used when sway is running."); |
8 | 8 | ||
9 | swayc_t *container = get_focused_container(&root_container); | 9 | swayc_t *container = current_container; |
10 | close_views(container); | 10 | close_views(container); |
11 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 11 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
12 | } | 12 | } |
diff --git a/sway/commands/layout.c b/sway/commands/layout.c index 570cd207..40ebd590 100644 --- a/sway/commands/layout.c +++ b/sway/commands/layout.c | |||
@@ -16,7 +16,7 @@ struct cmd_results *cmd_layout(int argc, char **argv) { | |||
16 | if ((error = checkarg(argc, "layout", EXPECTED_MORE_THAN, 0))) { | 16 | if ((error = checkarg(argc, "layout", EXPECTED_MORE_THAN, 0))) { |
17 | return error; | 17 | return error; |
18 | } | 18 | } |
19 | swayc_t *parent = get_focused_container(&root_container); | 19 | swayc_t *parent = current_container; |
20 | if (parent->is_floating) { | 20 | if (parent->is_floating) { |
21 | return cmd_results_new(CMD_FAILURE, "layout", "Unable to change layout of floating windows"); | 21 | return cmd_results_new(CMD_FAILURE, "layout", "Unable to change layout of floating windows"); |
22 | } | 22 | } |
diff --git a/sway/commands/mark.c b/sway/commands/mark.c index 68a84af7..919883b0 100644 --- a/sway/commands/mark.c +++ b/sway/commands/mark.c | |||
@@ -8,11 +8,11 @@ | |||
8 | struct cmd_results *cmd_mark(int argc, char **argv) { | 8 | struct cmd_results *cmd_mark(int argc, char **argv) { |
9 | struct cmd_results *error = NULL; | 9 | struct cmd_results *error = NULL; |
10 | if (config->reading) return cmd_results_new(CMD_FAILURE, "mark", "Can't be used in config file."); | 10 | if (config->reading) return cmd_results_new(CMD_FAILURE, "mark", "Can't be used in config file."); |
11 | if ((error = checkarg(argc, "floating", EXPECTED_AT_LEAST, 1))) { | 11 | if ((error = checkarg(argc, "mark", EXPECTED_AT_LEAST, 1))) { |
12 | return error; | 12 | return error; |
13 | } | 13 | } |
14 | 14 | ||
15 | swayc_t *view = get_focused_container(&root_container); | 15 | swayc_t *view = current_container; |
16 | bool add = false; | 16 | bool add = false; |
17 | bool toggle = false; | 17 | bool toggle = false; |
18 | 18 | ||
diff --git a/sway/commands/move.c b/sway/commands/move.c index 97e10f10..3c47cfe7 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c | |||
@@ -20,7 +20,7 @@ struct cmd_results *cmd_move(int argc, char **argv) { | |||
20 | "'move <container|window> to workspace <name>' or " | 20 | "'move <container|window> to workspace <name>' or " |
21 | "'move <container|window|workspace> to output <name|direction>' or " | 21 | "'move <container|window|workspace> to output <name|direction>' or " |
22 | "'move position mouse'"; | 22 | "'move position mouse'"; |
23 | swayc_t *view = get_focused_container(&root_container); | 23 | swayc_t *view = current_container; |
24 | 24 | ||
25 | if (argc == 2 || (argc == 3 && strcasecmp(argv[2], "px") == 0 )) { | 25 | if (argc == 2 || (argc == 3 && strcasecmp(argv[2], "px") == 0 )) { |
26 | char *inv; | 26 | char *inv; |
@@ -125,7 +125,7 @@ struct cmd_results *cmd_move(int argc, char **argv) { | |||
125 | if (view->type != C_CONTAINER && view->type != C_VIEW) { | 125 | if (view->type != C_CONTAINER && view->type != C_VIEW) { |
126 | return cmd_results_new(CMD_FAILURE, "move scratchpad", "Can only move containers and views."); | 126 | return cmd_results_new(CMD_FAILURE, "move scratchpad", "Can only move containers and views."); |
127 | } | 127 | } |
128 | swayc_t *view = get_focused_container(&root_container); | 128 | swayc_t *view = current_container; |
129 | int i; | 129 | int i; |
130 | for (i = 0; i < scratchpad->length; i++) { | 130 | for (i = 0; i < scratchpad->length; i++) { |
131 | if (scratchpad->items[i] == view) { | 131 | if (scratchpad->items[i] == view) { |
diff --git a/sway/commands/resize.c b/sway/commands/resize.c index 61af080c..ef52bb07 100644 --- a/sway/commands/resize.c +++ b/sway/commands/resize.c | |||
@@ -19,7 +19,7 @@ enum resize_dim_types { | |||
19 | }; | 19 | }; |
20 | 20 | ||
21 | static bool set_size_floating(int new_dimension, bool use_width) { | 21 | static bool set_size_floating(int new_dimension, bool use_width) { |
22 | swayc_t *view = get_focused_float(swayc_active_workspace()); | 22 | swayc_t *view = current_container; |
23 | if (view) { | 23 | if (view) { |
24 | if (use_width) { | 24 | if (use_width) { |
25 | int current_width = view->width; | 25 | int current_width = view->width; |
@@ -50,7 +50,7 @@ static bool set_size_floating(int new_dimension, bool use_width) { | |||
50 | } | 50 | } |
51 | 51 | ||
52 | static bool resize_floating(int amount, bool use_width) { | 52 | static bool resize_floating(int amount, bool use_width) { |
53 | swayc_t *view = get_focused_float(swayc_active_workspace()); | 53 | swayc_t *view = current_container; |
54 | 54 | ||
55 | if (view) { | 55 | if (view) { |
56 | if (use_width) { | 56 | if (use_width) { |
@@ -64,7 +64,7 @@ static bool resize_floating(int amount, bool use_width) { | |||
64 | } | 64 | } |
65 | 65 | ||
66 | static bool resize_tiled(int amount, bool use_width) { | 66 | static bool resize_tiled(int amount, bool use_width) { |
67 | swayc_t *container = get_focused_view(swayc_active_workspace()); | 67 | swayc_t *container = current_container; |
68 | swayc_t *parent = container->parent; | 68 | swayc_t *parent = container->parent; |
69 | int idx_focused = 0; | 69 | int idx_focused = 0; |
70 | bool use_major = false; | 70 | bool use_major = false; |
@@ -199,7 +199,7 @@ static bool resize_tiled(int amount, bool use_width) { | |||
199 | 199 | ||
200 | static bool set_size_tiled(int amount, bool use_width) { | 200 | static bool set_size_tiled(int amount, bool use_width) { |
201 | int desired; | 201 | int desired; |
202 | swayc_t *focused = get_focused_view(swayc_active_workspace()); | 202 | swayc_t *focused = current_container; |
203 | 203 | ||
204 | if (use_width) { | 204 | if (use_width) { |
205 | desired = amount - focused->width; | 205 | desired = amount - focused->width; |
@@ -211,7 +211,7 @@ static bool set_size_tiled(int amount, bool use_width) { | |||
211 | } | 211 | } |
212 | 212 | ||
213 | static bool set_size(int dimension, bool use_width) { | 213 | static bool set_size(int dimension, bool use_width) { |
214 | swayc_t *focused = get_focused_view_include_floating(swayc_active_workspace()); | 214 | swayc_t *focused = current_container; |
215 | 215 | ||
216 | if (focused) { | 216 | if (focused) { |
217 | if (focused->is_floating) { | 217 | if (focused->is_floating) { |
@@ -225,7 +225,7 @@ static bool set_size(int dimension, bool use_width) { | |||
225 | } | 225 | } |
226 | 226 | ||
227 | static bool resize(int dimension, bool use_width, enum resize_dim_types dim_type) { | 227 | static bool resize(int dimension, bool use_width, enum resize_dim_types dim_type) { |
228 | swayc_t *focused = get_focused_view_include_floating(swayc_active_workspace()); | 228 | swayc_t *focused = current_container; |
229 | 229 | ||
230 | // translate "10 ppt" (10%) to appropriate # of pixels in case we need it | 230 | // translate "10 ppt" (10%) to appropriate # of pixels in case we need it |
231 | float ppt_dim = (float)dimension / 100; | 231 | float ppt_dim = (float)dimension / 100; |
diff --git a/sway/commands/split.c b/sway/commands/split.c index e7da93d7..e3045a4f 100644 --- a/sway/commands/split.c +++ b/sway/commands/split.c | |||
@@ -17,7 +17,7 @@ static struct cmd_results *_do_split(int argc, char **argv, int layout) { | |||
17 | if ((error = checkarg(argc, name, EXPECTED_EQUAL_TO, 0))) { | 17 | if ((error = checkarg(argc, name, EXPECTED_EQUAL_TO, 0))) { |
18 | return error; | 18 | return error; |
19 | } | 19 | } |
20 | swayc_t *focused = get_focused_container(&root_container); | 20 | swayc_t *focused = current_container; |
21 | 21 | ||
22 | // Case of floating window, don't split | 22 | // Case of floating window, don't split |
23 | if (focused->is_floating) { | 23 | if (focused->is_floating) { |
@@ -66,7 +66,7 @@ struct cmd_results *cmd_split(int argc, char **argv) { | |||
66 | } else if (strcasecmp(argv[0], "h") == 0 || strcasecmp(argv[0], "horizontal") == 0) { | 66 | } else if (strcasecmp(argv[0], "h") == 0 || strcasecmp(argv[0], "horizontal") == 0) { |
67 | _do_split(argc - 1, argv + 1, L_HORIZ); | 67 | _do_split(argc - 1, argv + 1, L_HORIZ); |
68 | } else if (strcasecmp(argv[0], "t") == 0 || strcasecmp(argv[0], "toggle") == 0) { | 68 | } else if (strcasecmp(argv[0], "t") == 0 || strcasecmp(argv[0], "toggle") == 0) { |
69 | swayc_t *focused = get_focused_container(&root_container); | 69 | swayc_t *focused = current_container; |
70 | if (focused->parent->layout == L_VERT) { | 70 | if (focused->parent->layout == L_VERT) { |
71 | _do_split(argc - 1, argv + 1, L_HORIZ); | 71 | _do_split(argc - 1, argv + 1, L_HORIZ); |
72 | } else { | 72 | } else { |
@@ -89,7 +89,7 @@ struct cmd_results *cmd_splith(int argc, char **argv) { | |||
89 | } | 89 | } |
90 | 90 | ||
91 | struct cmd_results *cmd_splitt(int argc, char **argv) { | 91 | struct cmd_results *cmd_splitt(int argc, char **argv) { |
92 | swayc_t *focused = get_focused_container(&root_container); | 92 | swayc_t *focused = current_container; |
93 | if (focused->parent->layout == L_VERT) { | 93 | if (focused->parent->layout == L_VERT) { |
94 | return _do_split(argc, argv, L_HORIZ); | 94 | return _do_split(argc, argv, L_HORIZ); |
95 | } else { | 95 | } else { |
diff --git a/sway/commands/unmark.c b/sway/commands/unmark.c index 34a2ae44..ac213261 100644 --- a/sway/commands/unmark.c +++ b/sway/commands/unmark.c | |||
@@ -5,7 +5,7 @@ | |||
5 | #include "stringop.h" | 5 | #include "stringop.h" |
6 | 6 | ||
7 | struct cmd_results *cmd_unmark(int argc, char **argv) { | 7 | struct cmd_results *cmd_unmark(int argc, char **argv) { |
8 | swayc_t *view = get_focused_container(&root_container); | 8 | swayc_t *view = current_container; |
9 | 9 | ||
10 | if (view->marks) { | 10 | if (view->marks) { |
11 | if (argc) { | 11 | if (argc) { |
diff --git a/sway/criteria.c b/sway/criteria.c index 3ffc48f0..bd99461d 100644 --- a/sway/criteria.c +++ b/sway/criteria.c | |||
@@ -245,7 +245,7 @@ ect_cleanup: | |||
245 | return error; | 245 | return error; |
246 | } | 246 | } |
247 | 247 | ||
248 | int regex_cmp(const char *item, const regex_t *regex) { | 248 | static int regex_cmp(const char *item, const regex_t *regex) { |
249 | return regexec(regex, item, 0, NULL, 0); | 249 | return regexec(regex, item, 0, NULL, 0); |
250 | } | 250 | } |
251 | 251 | ||
@@ -272,7 +272,10 @@ static bool criteria_test(swayc_t *cont, list_t *tokens) { | |||
272 | break; | 272 | break; |
273 | case CRIT_CON_MARK: | 273 | case CRIT_CON_MARK: |
274 | if (crit->regex && cont->marks && (list_seq_find(cont->marks, (int (*)(const void *, const void *))regex_cmp, crit->regex) != -1)) { | 274 | if (crit->regex && cont->marks && (list_seq_find(cont->marks, (int (*)(const void *, const void *))regex_cmp, crit->regex) != -1)) { |
275 | ++matches; | 275 | // Make sure it isn't matching the NUL string |
276 | if ((strcmp(crit->raw, "") == 0) == (list_seq_find(cont->marks, (int (*)(const void *, const void *))strcmp, "") != -1)) { | ||
277 | ++matches; | ||
278 | } | ||
276 | } | 279 | } |
277 | break; | 280 | break; |
278 | case CRIT_ID: | 281 | case CRIT_ID: |
@@ -285,7 +288,7 @@ static bool criteria_test(swayc_t *cont, list_t *tokens) { | |||
285 | case CRIT_INSTANCE: | 288 | case CRIT_INSTANCE: |
286 | if (!cont->instance) { | 289 | if (!cont->instance) { |
287 | // ignore | 290 | // ignore |
288 | } else if (strcmp(crit->raw, "focused") == 0) { | 291 | } else if (crit_is_focused(crit->raw)) { |
289 | swayc_t *focused = get_focused_view(&root_container); | 292 | swayc_t *focused = get_focused_view(&root_container); |
290 | if (focused->instance && strcmp(cont->instance, focused->instance) == 0) { | 293 | if (focused->instance && strcmp(cont->instance, focused->instance) == 0) { |
291 | matches++; | 294 | matches++; |
@@ -373,3 +376,21 @@ list_t *criteria_for(swayc_t *cont) { | |||
373 | } | 376 | } |
374 | return matches; | 377 | return matches; |
375 | } | 378 | } |
379 | |||
380 | struct list_tokens { | ||
381 | list_t *list; | ||
382 | list_t *tokens; | ||
383 | }; | ||
384 | |||
385 | static void container_match_add(swayc_t *container, struct list_tokens *list_tokens) { | ||
386 | if (criteria_test(container, list_tokens->tokens)) { | ||
387 | list_add(list_tokens->list, container); | ||
388 | } | ||
389 | } | ||
390 | list_t *container_for(list_t *tokens) { | ||
391 | struct list_tokens list_tokens = (struct list_tokens){create_list(), tokens}; | ||
392 | |||
393 | container_map(&root_container, (void (*)(swayc_t *, void *))container_match_add, &list_tokens); | ||
394 | |||
395 | return list_tokens.list; | ||
396 | } | ||
diff --git a/sway/sway.5.txt b/sway/sway.5.txt index 3cccdfd5..d76951b5 100644 --- a/sway/sway.5.txt +++ b/sway/sway.5.txt | |||
@@ -316,7 +316,7 @@ The default colors are: | |||
316 | If smart_gaps are _on_ then gaps will only be enabled if a workspace has more | 316 | If smart_gaps are _on_ then gaps will only be enabled if a workspace has more |
317 | than one child container. | 317 | than one child container. |
318 | 318 | ||
319 | **mark** <--add|--replace> <--toggle> <identifier>:: | 319 | **mark** \<--add|--replace> \<--toggle> <identifier>:: |
320 | Marks are arbitrary labels that can be used to identify certain windows and | 320 | Marks are arbitrary labels that can be used to identify certain windows and |
321 | then jump to them at a later time. By default, the **mark** command sets | 321 | then jump to them at a later time. By default, the **mark** command sets |
322 | _identifier_ as the only mark on a window. By specifying _--add_, mark will | 322 | _identifier_ as the only mark on a window. By specifying _--add_, mark will |
@@ -426,6 +426,20 @@ The string contains one or more (space separated) attribute/value pairs and they | |||
426 | are used by some commands filter which views to execute actions on. All attributes | 426 | are used by some commands filter which views to execute actions on. All attributes |
427 | must match for the criteria string to match. | 427 | must match for the criteria string to match. |
428 | 428 | ||
429 | Criteria may be used with either the **for_window** or **assign** commands to | ||
430 | specify operations to perform on new views. A criteria may also be used to | ||
431 | perform specific commands (ones that normally act upon one window) on all views | ||
432 | that match that criteria. For example: | ||
433 | |||
434 | Focus on a window with the mark "IRC": | ||
435 | [con_mark="IRC"] focus | ||
436 | |||
437 | Kill all windows with the title "Emacs": | ||
438 | [class="Emacs"] kill | ||
439 | |||
440 | Mark all Firefox windows with "Browser": | ||
441 | [class="Firefox"] mark Browser | ||
442 | |||
429 | Currently supported attributes: | 443 | Currently supported attributes: |
430 | 444 | ||
431 | **class**:: | 445 | **class**:: |