diff options
-rw-r--r-- | include/sway/commands.h | 6 | ||||
-rw-r--r-- | sway/commands.c | 67 | ||||
-rw-r--r-- | sway/commands/bind.c | 21 | ||||
-rw-r--r-- | sway/ipc-server.c | 11 | ||||
-rw-r--r-- | sway/main.c | 13 | ||||
-rw-r--r-- | sway/tree/view.c | 9 |
6 files changed, 69 insertions, 58 deletions
diff --git a/include/sway/commands.h b/include/sway/commands.h index eb446eae..c3913c79 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h | |||
@@ -56,7 +56,7 @@ struct cmd_handler *find_handler(char *line, struct cmd_handler *cmd_handlers, | |||
56 | * all matching containers. Otherwise, it'll run on the `con` container. If | 56 | * all matching containers. Otherwise, it'll run on the `con` container. If |
57 | * `con` is NULL then it'll run on the currently focused container. | 57 | * `con` is NULL then it'll run on the currently focused container. |
58 | */ | 58 | */ |
59 | struct cmd_results *execute_command(char *command, struct sway_seat *seat, | 59 | list_t *execute_command(char *command, struct sway_seat *seat, |
60 | struct sway_container *con); | 60 | struct sway_container *con); |
61 | /** | 61 | /** |
62 | * Parse and handles a command during config file loading. | 62 | * Parse and handles a command during config file loading. |
@@ -82,11 +82,11 @@ struct cmd_results *cmd_results_new(enum cmd_status status, const char* input, c | |||
82 | */ | 82 | */ |
83 | void free_cmd_results(struct cmd_results *results); | 83 | void free_cmd_results(struct cmd_results *results); |
84 | /** | 84 | /** |
85 | * Serializes cmd_results to a JSON string. | 85 | * Serializes a list of cmd_results to a JSON string. |
86 | * | 86 | * |
87 | * Free the JSON string later on. | 87 | * Free the JSON string later on. |
88 | */ | 88 | */ |
89 | char *cmd_results_to_json(struct cmd_results *results); | 89 | char *cmd_results_to_json(list_t *res_list); |
90 | 90 | ||
91 | struct cmd_results *add_color(const char *name, | 91 | struct cmd_results *add_color(const char *name, |
92 | char *buffer, const char *color); | 92 | char *buffer, const char *color); |
diff --git a/sway/commands.c b/sway/commands.c index bffc18f6..34e66ce9 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -215,12 +215,9 @@ static void set_config_node(struct sway_node *node) { | |||
215 | } | 215 | } |
216 | } | 216 | } |
217 | 217 | ||
218 | struct cmd_results *execute_command(char *_exec, struct sway_seat *seat, | 218 | list_t *execute_command(char *_exec, struct sway_seat *seat, |
219 | struct sway_container *con) { | 219 | struct sway_container *con) { |
220 | // Even though this function will process multiple commands we will only | 220 | list_t *res_list = create_list(); |
221 | // return the last error, if any (for now). (Since we have access to an | ||
222 | // error string we could e.g. concatenate all errors there.) | ||
223 | struct cmd_results *results = NULL; | ||
224 | char *exec = strdup(_exec); | 221 | char *exec = strdup(_exec); |
225 | char *head = exec; | 222 | char *head = exec; |
226 | char *cmdlist; | 223 | char *cmdlist; |
@@ -254,8 +251,8 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat, | |||
254 | char *error = NULL; | 251 | char *error = NULL; |
255 | struct criteria *criteria = criteria_parse(head, &error); | 252 | struct criteria *criteria = criteria_parse(head, &error); |
256 | if (!criteria) { | 253 | if (!criteria) { |
257 | results = cmd_results_new(CMD_INVALID, head, | 254 | list_add(res_list, cmd_results_new(CMD_INVALID, head, |
258 | "%s", error); | 255 | "%s", error)); |
259 | free(error); | 256 | free(error); |
260 | goto cleanup; | 257 | goto cleanup; |
261 | } | 258 | } |
@@ -291,10 +288,8 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat, | |||
291 | } | 288 | } |
292 | struct cmd_handler *handler = find_handler(argv[0], NULL, 0); | 289 | struct cmd_handler *handler = find_handler(argv[0], NULL, 0); |
293 | if (!handler) { | 290 | if (!handler) { |
294 | if (results) { | 291 | list_add(res_list, cmd_results_new(CMD_INVALID, cmd, |
295 | free_cmd_results(results); | 292 | "Unknown/invalid command")); |
296 | } | ||
297 | results = cmd_results_new(CMD_INVALID, cmd, "Unknown/invalid command"); | ||
298 | free_argv(argc, argv); | 293 | free_argv(argc, argv); |
299 | goto cleanup; | 294 | goto cleanup; |
300 | } | 295 | } |
@@ -308,29 +303,21 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat, | |||
308 | if (!config->handler_context.using_criteria) { | 303 | if (!config->handler_context.using_criteria) { |
309 | set_config_node(node); | 304 | set_config_node(node); |
310 | struct cmd_results *res = handler->handle(argc-1, argv+1); | 305 | struct cmd_results *res = handler->handle(argc-1, argv+1); |
311 | if (res->status != CMD_SUCCESS) { | 306 | list_add(res_list, res); |
307 | if (res->status == CMD_INVALID) { | ||
312 | free_argv(argc, argv); | 308 | free_argv(argc, argv); |
313 | if (results) { | ||
314 | free_cmd_results(results); | ||
315 | } | ||
316 | results = res; | ||
317 | goto cleanup; | 309 | goto cleanup; |
318 | } | 310 | } |
319 | free_cmd_results(res); | ||
320 | } else { | 311 | } else { |
321 | for (int i = 0; i < views->length; ++i) { | 312 | for (int i = 0; i < views->length; ++i) { |
322 | struct sway_view *view = views->items[i]; | 313 | struct sway_view *view = views->items[i]; |
323 | set_config_node(&view->container->node); | 314 | set_config_node(&view->container->node); |
324 | struct cmd_results *res = handler->handle(argc-1, argv+1); | 315 | struct cmd_results *res = handler->handle(argc-1, argv+1); |
325 | if (res->status != CMD_SUCCESS) { | 316 | list_add(res_list, res); |
317 | if (res->status == CMD_INVALID) { | ||
326 | free_argv(argc, argv); | 318 | free_argv(argc, argv); |
327 | if (results) { | ||
328 | free_cmd_results(results); | ||
329 | } | ||
330 | results = res; | ||
331 | goto cleanup; | 319 | goto cleanup; |
332 | } | 320 | } |
333 | free_cmd_results(res); | ||
334 | } | 321 | } |
335 | } | 322 | } |
336 | free_argv(argc, argv); | 323 | free_argv(argc, argv); |
@@ -339,10 +326,7 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat, | |||
339 | cleanup: | 326 | cleanup: |
340 | free(exec); | 327 | free(exec); |
341 | list_free(views); | 328 | list_free(views); |
342 | if (!results) { | 329 | return res_list; |
343 | results = cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
344 | } | ||
345 | return results; | ||
346 | } | 330 | } |
347 | 331 | ||
348 | // this is like execute_command above, except: | 332 | // this is like execute_command above, except: |
@@ -574,20 +558,25 @@ void free_cmd_results(struct cmd_results *results) { | |||
574 | free(results); | 558 | free(results); |
575 | } | 559 | } |
576 | 560 | ||
577 | char *cmd_results_to_json(struct cmd_results *results) { | 561 | char *cmd_results_to_json(list_t *res_list) { |
578 | json_object *result_array = json_object_new_array(); | 562 | json_object *result_array = json_object_new_array(); |
579 | json_object *root = json_object_new_object(); | 563 | for (int i = 0; i < res_list->length; ++i) { |
580 | json_object_object_add(root, "success", | 564 | struct cmd_results *results = res_list->items[i]; |
581 | json_object_new_boolean(results->status == CMD_SUCCESS)); | 565 | json_object *root = json_object_new_object(); |
582 | if (results->input) { | 566 | json_object_object_add(root, "success", |
583 | json_object_object_add( | 567 | json_object_new_boolean(results->status == CMD_SUCCESS)); |
584 | root, "input", json_object_new_string(results->input)); | 568 | if (results->error) { |
585 | } | 569 | json_object_object_add(root, "parse_error", |
586 | if (results->error) { | 570 | json_object_new_boolean(results->status == CMD_INVALID)); |
587 | json_object_object_add( | 571 | json_object_object_add( |
588 | root, "error", json_object_new_string(results->error)); | 572 | root, "error", json_object_new_string(results->error)); |
573 | } | ||
574 | if (results->input) { | ||
575 | json_object_object_add( | ||
576 | root, "input", json_object_new_string(results->input)); | ||
577 | } | ||
578 | json_object_array_add(result_array, root); | ||
589 | } | 579 | } |
590 | json_object_array_add(result_array, root); | ||
591 | const char *json = json_object_to_json_string(result_array); | 580 | const char *json = json_object_to_json_string(result_array); |
592 | char *res = strdup(json); | 581 | char *res = strdup(json); |
593 | json_object_put(result_array); | 582 | json_object_put(result_array); |
diff --git a/sway/commands/bind.c b/sway/commands/bind.c index 08acbe7a..34881b0f 100644 --- a/sway/commands/bind.c +++ b/sway/commands/bind.c | |||
@@ -289,13 +289,20 @@ void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding) | |||
289 | wlr_log(WLR_DEBUG, "running command for binding: %s", binding->command); | 289 | wlr_log(WLR_DEBUG, "running command for binding: %s", binding->command); |
290 | 290 | ||
291 | config->handler_context.seat = seat; | 291 | config->handler_context.seat = seat; |
292 | struct cmd_results *results = execute_command(binding->command, NULL, NULL); | 292 | list_t *res_list = execute_command(binding->command, NULL, NULL); |
293 | if (results->status == CMD_SUCCESS) { | 293 | bool success = true; |
294 | while (res_list->length) { | ||
295 | struct cmd_results *results = res_list->items[0]; | ||
296 | if (results->status != CMD_SUCCESS) { | ||
297 | wlr_log(WLR_DEBUG, "could not run command for binding: %s (%s)", | ||
298 | binding->command, results->error); | ||
299 | success = false; | ||
300 | } | ||
301 | free_cmd_results(results); | ||
302 | list_del(res_list, 0); | ||
303 | } | ||
304 | list_free(res_list); | ||
305 | if (success) { | ||
294 | ipc_event_binding(binding); | 306 | ipc_event_binding(binding); |
295 | } else { | ||
296 | wlr_log(WLR_DEBUG, "could not run command for binding: %s (%s)", | ||
297 | binding->command, results->error); | ||
298 | } | 307 | } |
299 | |||
300 | free_cmd_results(results); | ||
301 | } | 308 | } |
diff --git a/sway/ipc-server.c b/sway/ipc-server.c index aa0f0fad..95433d97 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c | |||
@@ -597,13 +597,18 @@ void ipc_client_handle_command(struct ipc_client *client) { | |||
597 | switch (client->current_command) { | 597 | switch (client->current_command) { |
598 | case IPC_COMMAND: | 598 | case IPC_COMMAND: |
599 | { | 599 | { |
600 | struct cmd_results *results = execute_command(buf, NULL, NULL); | 600 | list_t *res_list = execute_command(buf, NULL, NULL); |
601 | transaction_commit_dirty(); | 601 | transaction_commit_dirty(); |
602 | char *json = cmd_results_to_json(results); | 602 | char *json = cmd_results_to_json(res_list); |
603 | int length = strlen(json); | 603 | int length = strlen(json); |
604 | client_valid = ipc_send_reply(client, json, (uint32_t)length); | 604 | client_valid = ipc_send_reply(client, json, (uint32_t)length); |
605 | free(json); | 605 | free(json); |
606 | free_cmd_results(results); | 606 | while (res_list->length) { |
607 | struct cmd_results *results = res_list->items[0]; | ||
608 | free_cmd_results(results); | ||
609 | list_del(res_list, 0); | ||
610 | } | ||
611 | list_free(res_list); | ||
607 | goto exit_cleanup; | 612 | goto exit_cleanup; |
608 | } | 613 | } |
609 | 614 | ||
diff --git a/sway/main.c b/sway/main.c index a21970e2..a74183fe 100644 --- a/sway/main.c +++ b/sway/main.c | |||
@@ -392,11 +392,16 @@ int main(int argc, char **argv) { | |||
392 | wlr_log(WLR_DEBUG, "Running deferred commands"); | 392 | wlr_log(WLR_DEBUG, "Running deferred commands"); |
393 | while (config->cmd_queue->length) { | 393 | while (config->cmd_queue->length) { |
394 | char *line = config->cmd_queue->items[0]; | 394 | char *line = config->cmd_queue->items[0]; |
395 | struct cmd_results *res = execute_command(line, NULL, NULL); | 395 | list_t *res_list = execute_command(line, NULL, NULL); |
396 | if (res->status != CMD_SUCCESS) { | 396 | while (res_list->length) { |
397 | wlr_log(WLR_ERROR, "Error on line '%s': %s", line, res->error); | 397 | struct cmd_results *res = res_list->items[0]; |
398 | if (res->status != CMD_SUCCESS) { | ||
399 | wlr_log(WLR_ERROR, "Error on line '%s': %s", line, res->error); | ||
400 | } | ||
401 | free_cmd_results(res); | ||
402 | list_del(res_list, 0); | ||
398 | } | 403 | } |
399 | free_cmd_results(res); | 404 | list_free(res_list); |
400 | free(line); | 405 | free(line); |
401 | list_del(config->cmd_queue, 0); | 406 | list_del(config->cmd_queue, 0); |
402 | } | 407 | } |
diff --git a/sway/tree/view.c b/sway/tree/view.c index febba3b9..511c2ecc 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -437,9 +437,14 @@ void view_execute_criteria(struct sway_view *view) { | |||
437 | wlr_log(WLR_DEBUG, "for_window '%s' matches view %p, cmd: '%s'", | 437 | wlr_log(WLR_DEBUG, "for_window '%s' matches view %p, cmd: '%s'", |
438 | criteria->raw, view, criteria->cmdlist); | 438 | criteria->raw, view, criteria->cmdlist); |
439 | list_add(view->executed_criteria, criteria); | 439 | list_add(view->executed_criteria, criteria); |
440 | struct cmd_results *res = execute_command( | 440 | list_t *res_list = execute_command( |
441 | criteria->cmdlist, NULL, view->container); | 441 | criteria->cmdlist, NULL, view->container); |
442 | free_cmd_results(res); | 442 | while (res_list->length) { |
443 | struct cmd_results *res = res_list->items[0]; | ||
444 | free_cmd_results(res); | ||
445 | list_del(res_list, 0); | ||
446 | } | ||
447 | list_free(res_list); | ||
443 | } | 448 | } |
444 | list_free(criterias); | 449 | list_free(criterias); |
445 | } | 450 | } |