aboutsummaryrefslogtreecommitdiffstats
path: root/sway/commands.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/commands.c')
-rw-r--r--sway/commands.c106
1 files changed, 39 insertions, 67 deletions
diff --git a/sway/commands.c b/sway/commands.c
index a68c724a..1d190e0b 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -42,22 +42,6 @@ struct cmd_results *checkarg(int argc, const char *name, enum expected_args type
42 : NULL; 42 : NULL;
43} 43}
44 44
45void apply_seat_config(struct seat_config *seat_config) {
46 int i;
47 i = list_seq_find(config->seat_configs, seat_name_cmp, seat_config->name);
48 if (i >= 0) {
49 // merge existing config
50 struct seat_config *sc = config->seat_configs->items[i];
51 merge_seat_config(sc, seat_config);
52 free_seat_config(seat_config);
53 seat_config = sc;
54 } else {
55 list_add(config->seat_configs, seat_config);
56 }
57
58 input_manager_apply_seat_config(seat_config);
59}
60
61/* Keep alphabetized */ 45/* Keep alphabetized */
62static struct cmd_handler handlers[] = { 46static struct cmd_handler handlers[] = {
63 { "assign", cmd_assign }, 47 { "assign", cmd_assign },
@@ -103,6 +87,10 @@ static struct cmd_handler handlers[] = {
103 { "smart_borders", cmd_smart_borders }, 87 { "smart_borders", cmd_smart_borders },
104 { "smart_gaps", cmd_smart_gaps }, 88 { "smart_gaps", cmd_smart_gaps },
105 { "tiling_drag", cmd_tiling_drag }, 89 { "tiling_drag", cmd_tiling_drag },
90 { "tiling_drag_threshold", cmd_tiling_drag_threshold },
91 { "title_align", cmd_title_align },
92 { "titlebar_border_thickness", cmd_titlebar_border_thickness },
93 { "titlebar_padding", cmd_titlebar_padding },
106 { "workspace", cmd_workspace }, 94 { "workspace", cmd_workspace },
107 { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth }, 95 { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth },
108}; 96};
@@ -213,12 +201,9 @@ static void set_config_node(struct sway_node *node) {
213 } 201 }
214} 202}
215 203
216struct cmd_results *execute_command(char *_exec, struct sway_seat *seat, 204list_t *execute_command(char *_exec, struct sway_seat *seat,
217 struct sway_container *con) { 205 struct sway_container *con) {
218 // Even though this function will process multiple commands we will only 206 list_t *res_list = create_list();
219 // return the last error, if any (for now). (Since we have access to an
220 // error string we could e.g. concatenate all errors there.)
221 struct cmd_results *results = NULL;
222 char *exec = strdup(_exec); 207 char *exec = strdup(_exec);
223 char *head = exec; 208 char *head = exec;
224 char *cmdlist; 209 char *cmdlist;
@@ -233,15 +218,6 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat,
233 } 218 }
234 } 219 }
235 220
236 // This is the container or workspace which this command will run on.
237 // Ignored if the command string contains criteria.
238 struct sway_node *node;
239 if (con) {
240 node = &con->node;
241 } else {
242 node = seat_get_focus_inactive(seat, &root->node);
243 }
244
245 config->handler_context.seat = seat; 221 config->handler_context.seat = seat;
246 222
247 head = exec; 223 head = exec;
@@ -252,8 +228,8 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat,
252 char *error = NULL; 228 char *error = NULL;
253 struct criteria *criteria = criteria_parse(head, &error); 229 struct criteria *criteria = criteria_parse(head, &error);
254 if (!criteria) { 230 if (!criteria) {
255 results = cmd_results_new(CMD_INVALID, head, 231 list_add(res_list, cmd_results_new(CMD_INVALID, head,
256 "%s", error); 232 "%s", error));
257 free(error); 233 free(error);
258 goto cleanup; 234 goto cleanup;
259 } 235 }
@@ -262,15 +238,15 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat,
262 criteria_destroy(criteria); 238 criteria_destroy(criteria);
263 config->handler_context.using_criteria = true; 239 config->handler_context.using_criteria = true;
264 // Skip leading whitespace 240 // Skip leading whitespace
265 head += strspn(head, whitespace); 241 for (; isspace(*head); ++head) {}
266 } 242 }
267 // Split command list 243 // Split command list
268 cmdlist = argsep(&head, ";"); 244 cmdlist = argsep(&head, ";");
269 cmdlist += strspn(cmdlist, whitespace); 245 for (; isspace(*cmdlist); ++cmdlist) {}
270 do { 246 do {
271 // Split commands 247 // Split commands
272 cmd = argsep(&cmdlist, ","); 248 cmd = argsep(&cmdlist, ",");
273 cmd += strspn(cmd, whitespace); 249 for (; isspace(*cmd); ++cmd) {}
274 if (strcmp(cmd, "") == 0) { 250 if (strcmp(cmd, "") == 0) {
275 wlr_log(WLR_INFO, "Ignoring empty command."); 251 wlr_log(WLR_INFO, "Ignoring empty command.");
276 continue; 252 continue;
@@ -289,10 +265,8 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat,
289 } 265 }
290 struct cmd_handler *handler = find_handler(argv[0], NULL, 0); 266 struct cmd_handler *handler = find_handler(argv[0], NULL, 0);
291 if (!handler) { 267 if (!handler) {
292 if (results) { 268 list_add(res_list, cmd_results_new(CMD_INVALID, cmd,
293 free_cmd_results(results); 269 "Unknown/invalid command"));
294 }
295 results = cmd_results_new(CMD_INVALID, cmd, "Unknown/invalid command");
296 free_argv(argc, argv); 270 free_argv(argc, argv);
297 goto cleanup; 271 goto cleanup;
298 } 272 }
@@ -304,31 +278,26 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat,
304 } 278 }
305 279
306 if (!config->handler_context.using_criteria) { 280 if (!config->handler_context.using_criteria) {
281 // The container or workspace which this command will run on.
282 struct sway_node *node = con ? &con->node :
283 seat_get_focus_inactive(seat, &root->node);
307 set_config_node(node); 284 set_config_node(node);
308 struct cmd_results *res = handler->handle(argc-1, argv+1); 285 struct cmd_results *res = handler->handle(argc-1, argv+1);
309 if (res->status != CMD_SUCCESS) { 286 list_add(res_list, res);
287 if (res->status == CMD_INVALID) {
310 free_argv(argc, argv); 288 free_argv(argc, argv);
311 if (results) {
312 free_cmd_results(results);
313 }
314 results = res;
315 goto cleanup; 289 goto cleanup;
316 } 290 }
317 free_cmd_results(res);
318 } else { 291 } else {
319 for (int i = 0; i < views->length; ++i) { 292 for (int i = 0; i < views->length; ++i) {
320 struct sway_view *view = views->items[i]; 293 struct sway_view *view = views->items[i];
321 set_config_node(&view->container->node); 294 set_config_node(&view->container->node);
322 struct cmd_results *res = handler->handle(argc-1, argv+1); 295 struct cmd_results *res = handler->handle(argc-1, argv+1);
323 if (res->status != CMD_SUCCESS) { 296 list_add(res_list, res);
297 if (res->status == CMD_INVALID) {
324 free_argv(argc, argv); 298 free_argv(argc, argv);
325 if (results) {
326 free_cmd_results(results);
327 }
328 results = res;
329 goto cleanup; 299 goto cleanup;
330 } 300 }
331 free_cmd_results(res);
332 } 301 }
333 } 302 }
334 free_argv(argc, argv); 303 free_argv(argc, argv);
@@ -337,10 +306,7 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat,
337cleanup: 306cleanup:
338 free(exec); 307 free(exec);
339 list_free(views); 308 list_free(views);
340 if (!results) { 309 return res_list;
341 results = cmd_results_new(CMD_SUCCESS, NULL, NULL);
342 }
343 return results;
344} 310}
345 311
346// this is like execute_command above, except: 312// this is like execute_command above, except:
@@ -418,6 +384,7 @@ struct cmd_results *config_command(char *exec) {
418 // Strip quotes and unescape the string 384 // Strip quotes and unescape the string
419 for (int i = handler->handle == cmd_set ? 2 : 1; i < argc; ++i) { 385 for (int i = handler->handle == cmd_set ? 2 : 1; i < argc; ++i) {
420 if (handler->handle != cmd_exec && handler->handle != cmd_exec_always 386 if (handler->handle != cmd_exec && handler->handle != cmd_exec_always
387 && handler->handle != cmd_mode
421 && handler->handle != cmd_bindsym 388 && handler->handle != cmd_bindsym
422 && handler->handle != cmd_bindcode 389 && handler->handle != cmd_bindcode
423 && handler->handle != cmd_set 390 && handler->handle != cmd_set
@@ -572,20 +539,25 @@ void free_cmd_results(struct cmd_results *results) {
572 free(results); 539 free(results);
573} 540}
574 541
575char *cmd_results_to_json(struct cmd_results *results) { 542char *cmd_results_to_json(list_t *res_list) {
576 json_object *result_array = json_object_new_array(); 543 json_object *result_array = json_object_new_array();
577 json_object *root = json_object_new_object(); 544 for (int i = 0; i < res_list->length; ++i) {
578 json_object_object_add(root, "success", 545 struct cmd_results *results = res_list->items[i];
579 json_object_new_boolean(results->status == CMD_SUCCESS)); 546 json_object *root = json_object_new_object();
580 if (results->input) { 547 json_object_object_add(root, "success",
581 json_object_object_add( 548 json_object_new_boolean(results->status == CMD_SUCCESS));
582 root, "input", json_object_new_string(results->input)); 549 if (results->error) {
583 } 550 json_object_object_add(root, "parse_error",
584 if (results->error) { 551 json_object_new_boolean(results->status == CMD_INVALID));
585 json_object_object_add( 552 json_object_object_add(
586 root, "error", json_object_new_string(results->error)); 553 root, "error", json_object_new_string(results->error));
554 }
555 if (results->input) {
556 json_object_object_add(
557 root, "input", json_object_new_string(results->input));
558 }
559 json_object_array_add(result_array, root);
587 } 560 }
588 json_object_array_add(result_array, root);
589 const char *json = json_object_to_json_string(result_array); 561 const char *json = json_object_to_json_string(result_array);
590 char *res = strdup(json); 562 char *res = strdup(json);
591 json_object_put(result_array); 563 json_object_put(result_array);