diff options
Diffstat (limited to 'sway/commands.c')
-rw-r--r-- | sway/commands.c | 82 |
1 files changed, 52 insertions, 30 deletions
diff --git a/sway/commands.c b/sway/commands.c index c330ebee..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; |
@@ -190,6 +192,7 @@ static struct cmd_handler handlers[] = { | |||
190 | { "kill", cmd_kill }, | 192 | { "kill", cmd_kill }, |
191 | { "layout", cmd_layout }, | 193 | { "layout", cmd_layout }, |
192 | { "log_colors", cmd_log_colors }, | 194 | { "log_colors", cmd_log_colors }, |
195 | { "mark", cmd_mark }, | ||
193 | { "mode", cmd_mode }, | 196 | { "mode", cmd_mode }, |
194 | { "mouse_warping", cmd_mouse_warping }, | 197 | { "mouse_warping", cmd_mouse_warping }, |
195 | { "move", cmd_move }, | 198 | { "move", cmd_move }, |
@@ -203,12 +206,14 @@ static struct cmd_handler handlers[] = { | |||
203 | { "scratchpad", cmd_scratchpad }, | 206 | { "scratchpad", cmd_scratchpad }, |
204 | { "seamless_mouse", cmd_seamless_mouse }, | 207 | { "seamless_mouse", cmd_seamless_mouse }, |
205 | { "set", cmd_set }, | 208 | { "set", cmd_set }, |
209 | { "show_marks", cmd_show_marks }, | ||
206 | { "smart_gaps", cmd_smart_gaps }, | 210 | { "smart_gaps", cmd_smart_gaps }, |
207 | { "split", cmd_split }, | 211 | { "split", cmd_split }, |
208 | { "splith", cmd_splith }, | 212 | { "splith", cmd_splith }, |
209 | { "splitt", cmd_splitt }, | 213 | { "splitt", cmd_splitt }, |
210 | { "splitv", cmd_splitv }, | 214 | { "splitv", cmd_splitv }, |
211 | { "sticky", cmd_sticky }, | 215 | { "sticky", cmd_sticky }, |
216 | { "unmark", cmd_unmark }, | ||
212 | { "workspace", cmd_workspace }, | 217 | { "workspace", cmd_workspace }, |
213 | { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth }, | 218 | { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth }, |
214 | { "workspace_layout", cmd_workspace_layout }, | 219 | { "workspace_layout", cmd_workspace_layout }, |
@@ -368,42 +373,37 @@ struct cmd_results *handle_command(char *_exec, enum command_context context) { | |||
368 | char *head = exec; | 373 | char *head = exec; |
369 | char *cmdlist; | 374 | char *cmdlist; |
370 | char *cmd; | 375 | char *cmd; |
371 | char *criteria __attribute__((unused)); | 376 | list_t *containers = NULL; |
372 | 377 | ||
373 | head = exec; | 378 | head = exec; |
374 | do { | 379 | do { |
375 | // Extract criteria (valid for this command list only). | 380 | // Extract criteria (valid for this command list only). |
376 | criteria = NULL; | ||
377 | if (*head == '[') { | 381 | if (*head == '[') { |
378 | ++head; | 382 | ++head; |
379 | criteria = argsep(&head, "]"); | 383 | char *criteria_string = argsep(&head, "]"); |
380 | if (head) { | 384 | if (head) { |
381 | ++head; | 385 | ++head; |
382 | // 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); | ||
383 | } else { | 399 | } else { |
384 | if (!results) { | 400 | if (!results) { |
385 | results = cmd_results_new(CMD_INVALID, criteria, "Unmatched ["); | 401 | results = cmd_results_new(CMD_INVALID, criteria_string, "Unmatched ["); |
386 | } | 402 | } |
387 | goto cleanup; | 403 | goto cleanup; |
388 | } | 404 | } |
389 | // Skip leading whitespace | 405 | // Skip leading whitespace |
390 | head += strspn(head, whitespace); | 406 | head += strspn(head, whitespace); |
391 | |||
392 | // TODO: it will yield unexpected results to execute commands | ||
393 | // (on any view) that where meant for certain views only. | ||
394 | if (!results) { | ||
395 | int len = strlen(criteria) + strlen(head) + 4; | ||
396 | char *tmp = malloc(len); | ||
397 | if (tmp) { | ||
398 | snprintf(tmp, len, "[%s] %s", criteria, head); | ||
399 | } else { | ||
400 | sway_log(L_DEBUG, "Unable to allocate criteria string for cmd result"); | ||
401 | } | ||
402 | results = cmd_results_new(CMD_INVALID, tmp, | ||
403 | "Can't handle criteria string: Refusing to execute command"); | ||
404 | free(tmp); | ||
405 | } | ||
406 | goto cleanup; | ||
407 | } | 407 | } |
408 | // Split command list | 408 | // Split command list |
409 | cmdlist = argsep(&head, ";"); | 409 | cmdlist = argsep(&head, ";"); |
@@ -447,21 +447,43 @@ struct cmd_results *handle_command(char *_exec, enum command_context context) { | |||
447 | free_argv(argc, argv); | 447 | free_argv(argc, argv); |
448 | goto cleanup; | 448 | goto cleanup; |
449 | } | 449 | } |
450 | struct cmd_results *res = handler->handle(argc-1, argv+1); | 450 | int i = 0; |
451 | if (res->status != CMD_SUCCESS) { | 451 | do { |
452 | free_argv(argc, argv); | 452 | if (!containers) { |
453 | if (results) { | 453 | current_container = get_focused_container(&root_container); |
454 | free_cmd_results(results); | 454 | } else if (containers->length == 0) { |
455 | break; | ||
456 | } else { | ||
457 | current_container = (swayc_t *)containers->items[i]; | ||
455 | } | 458 | } |
456 | results = res; | 459 | sway_log(L_INFO, "Running on container '%s'", current_container->name); |
457 | goto cleanup; | 460 | |
458 | } | 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 | |||
459 | free_argv(argc, argv); | 474 | free_argv(argc, argv); |
460 | free_cmd_results(res); | ||
461 | } while(cmdlist); | 475 | } while(cmdlist); |
476 | |||
477 | if (containers) { | ||
478 | list_free(containers); | ||
479 | containers = NULL; | ||
480 | } | ||
462 | } while(head); | 481 | } while(head); |
463 | cleanup: | 482 | cleanup: |
464 | free(exec); | 483 | free(exec); |
484 | if (containers) { | ||
485 | free(containers); | ||
486 | } | ||
465 | if (!results) { | 487 | if (!results) { |
466 | results = cmd_results_new(CMD_SUCCESS, NULL, NULL); | 488 | results = cmd_results_new(CMD_SUCCESS, NULL, NULL); |
467 | } | 489 | } |