summaryrefslogtreecommitdiffstats
path: root/sway/commands.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/commands.c')
-rw-r--r--sway/commands.c82
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
44int sp_index = 0; 44int sp_index = 0;
45 45
46swayc_t *current_container = NULL;
47
46// Returns error object, or NULL if check succeeds. 48// Returns error object, or NULL if check succeeds.
47struct cmd_results *checkarg(int argc, const char *name, enum expected_args type, int val) { 49struct 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 }