diff options
Diffstat (limited to 'sway')
-rw-r--r-- | sway/commands.c | 501 | ||||
-rw-r--r-- | sway/config.c | 6 | ||||
-rw-r--r-- | sway/handlers.c | 2 | ||||
-rw-r--r-- | sway/stringop.c | 2 | ||||
-rw-r--r-- | sway/workspace.c | 21 |
5 files changed, 289 insertions, 243 deletions
diff --git a/sway/commands.c b/sway/commands.c index 09ee91e8..e79746ae 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -18,15 +18,13 @@ | |||
18 | #include "sway.h" | 18 | #include "sway.h" |
19 | #include "resize.h" | 19 | #include "resize.h" |
20 | 20 | ||
21 | struct modifier_key { | ||
22 | char *name; | ||
23 | uint32_t mod; | ||
24 | }; | ||
25 | |||
26 | swayc_t *sp_view; | 21 | swayc_t *sp_view; |
27 | int sp_index = 0; | 22 | int sp_index = 0; |
28 | 23 | ||
29 | static struct modifier_key modifiers[] = { | 24 | static struct modifier_key { |
25 | char *name; | ||
26 | uint32_t mod; | ||
27 | } modifiers[] = { | ||
30 | { XKB_MOD_NAME_SHIFT, WLC_BIT_MOD_SHIFT }, | 28 | { XKB_MOD_NAME_SHIFT, WLC_BIT_MOD_SHIFT }, |
31 | { XKB_MOD_NAME_CAPS, WLC_BIT_MOD_CAPS }, | 29 | { XKB_MOD_NAME_CAPS, WLC_BIT_MOD_CAPS }, |
32 | { XKB_MOD_NAME_CTRL, WLC_BIT_MOD_CTRL }, | 30 | { XKB_MOD_NAME_CTRL, WLC_BIT_MOD_CTRL }, |
@@ -46,14 +44,14 @@ enum expected_args { | |||
46 | EXPECTED_EQUAL_TO | 44 | EXPECTED_EQUAL_TO |
47 | }; | 45 | }; |
48 | 46 | ||
49 | static bool checkarg(int argc, char *name, enum expected_args type, int val) { | 47 | static bool checkarg(int argc, const char *name, enum expected_args type, int val) { |
50 | switch (type) { | 48 | switch (type) { |
51 | case EXPECTED_MORE_THAN: | 49 | case EXPECTED_MORE_THAN: |
52 | if (argc > val) { | 50 | if (argc > val) { |
53 | return true; | 51 | return true; |
54 | } | 52 | } |
55 | sway_log(L_ERROR, "Invalid %s command." | 53 | sway_log(L_ERROR, "Invalid %s command." |
56 | "(expected more than %d argument%s, got %d", | 54 | "(expected more than %d argument%s, got %d)", |
57 | name, val, (char*[2]){"s", ""}[argc==1], argc); | 55 | name, val, (char*[2]){"s", ""}[argc==1], argc); |
58 | break; | 56 | break; |
59 | case EXPECTED_AT_LEAST: | 57 | case EXPECTED_AT_LEAST: |
@@ -61,7 +59,7 @@ static bool checkarg(int argc, char *name, enum expected_args type, int val) { | |||
61 | return true; | 59 | return true; |
62 | } | 60 | } |
63 | sway_log(L_ERROR, "Invalid %s command." | 61 | sway_log(L_ERROR, "Invalid %s command." |
64 | "(expected at least %d argument%s, got %d", | 62 | "(expected at least %d argument%s, got %d)", |
65 | name, val, (char*[2]){"s", ""}[argc==1], argc); | 63 | name, val, (char*[2]){"s", ""}[argc==1], argc); |
66 | break; | 64 | break; |
67 | case EXPECTED_LESS_THAN: | 65 | case EXPECTED_LESS_THAN: |
@@ -69,7 +67,7 @@ static bool checkarg(int argc, char *name, enum expected_args type, int val) { | |||
69 | return true; | 67 | return true; |
70 | }; | 68 | }; |
71 | sway_log(L_ERROR, "Invalid %s command." | 69 | sway_log(L_ERROR, "Invalid %s command." |
72 | "(expected less than %d argument%s, got %d", | 70 | "(expected less than %d argument%s, got %d)", |
73 | name, val, (char*[2]){"s", ""}[argc==1], argc); | 71 | name, val, (char*[2]){"s", ""}[argc==1], argc); |
74 | break; | 72 | break; |
75 | case EXPECTED_EQUAL_TO: | 73 | case EXPECTED_EQUAL_TO: |
@@ -77,7 +75,7 @@ static bool checkarg(int argc, char *name, enum expected_args type, int val) { | |||
77 | return true; | 75 | return true; |
78 | }; | 76 | }; |
79 | sway_log(L_ERROR, "Invalid %s command." | 77 | sway_log(L_ERROR, "Invalid %s command." |
80 | "(expected %d arguments, got %d", name, val, argc); | 78 | "(expected %d arguments, got %d)", name, val, argc); |
81 | break; | 79 | break; |
82 | } | 80 | } |
83 | return false; | 81 | return false; |
@@ -96,9 +94,10 @@ static int bindsym_sort(const void *_lbind, const void *_rbind) { | |||
96 | return (rbind->keys->length + rmod) - (lbind->keys->length + lmod); | 94 | return (rbind->keys->length + rmod) - (lbind->keys->length + lmod); |
97 | } | 95 | } |
98 | 96 | ||
99 | static bool cmd_bindsym(int argc, char **argv) { | 97 | static enum cmd_status cmd_bindsym(int argc, char **argv) { |
100 | if (!checkarg(argc, "bindsym", EXPECTED_MORE_THAN, 1)) { | 98 | if (!checkarg(argc, "bindsym", EXPECTED_MORE_THAN, 1) |
101 | return false; | 99 | || !config->reading) { |
100 | return CMD_FAILURE; | ||
102 | }; | 101 | }; |
103 | 102 | ||
104 | struct sway_binding *binding = malloc(sizeof(struct sway_binding)); | 103 | struct sway_binding *binding = malloc(sizeof(struct sway_binding)); |
@@ -128,7 +127,7 @@ static bool cmd_bindsym(int argc, char **argv) { | |||
128 | free(binding->command); | 127 | free(binding->command); |
129 | free(binding); | 128 | free(binding); |
130 | list_free(split); | 129 | list_free(split); |
131 | return false; | 130 | return CMD_FAILURE; |
132 | } | 131 | } |
133 | xkb_keysym_t *key = malloc(sizeof(xkb_keysym_t)); | 132 | xkb_keysym_t *key = malloc(sizeof(xkb_keysym_t)); |
134 | *key = sym; | 133 | *key = sym; |
@@ -142,19 +141,22 @@ static bool cmd_bindsym(int argc, char **argv) { | |||
142 | list_sort(mode->bindings, bindsym_sort); | 141 | list_sort(mode->bindings, bindsym_sort); |
143 | 142 | ||
144 | sway_log(L_DEBUG, "bindsym - Bound %s to command %s", argv[0], binding->command); | 143 | sway_log(L_DEBUG, "bindsym - Bound %s to command %s", argv[0], binding->command); |
145 | return true; | 144 | return CMD_SUCCESS; |
146 | } | 145 | } |
147 | 146 | ||
148 | static bool cmd_exec_always(int argc, char **argv) { | 147 | static enum cmd_status cmd_exec_always(int argc, char **argv) { |
149 | if (!checkarg(argc, "exec_always", EXPECTED_MORE_THAN, 0)) { | 148 | if (!checkarg(argc, "exec_always", EXPECTED_MORE_THAN, 0)) { |
150 | return false; | 149 | return CMD_FAILURE; |
150 | } | ||
151 | if (!config->active) { | ||
152 | return CMD_DEFER; | ||
151 | } | 153 | } |
152 | 154 | ||
153 | pid_t pid = fork(); | 155 | pid_t pid = fork(); |
154 | /* Failed to fork */ | 156 | /* Failed to fork */ |
155 | if (pid < 0) { | 157 | if (pid < 0) { |
156 | sway_log(L_ERROR, "exec command failed, sway did not fork"); | 158 | sway_log(L_ERROR, "exec command failed, sway did not fork"); |
157 | return false; | 159 | return CMD_FAILURE; |
158 | } | 160 | } |
159 | /* Child process */ | 161 | /* Child process */ |
160 | if (pid == 0) { | 162 | if (pid == 0) { |
@@ -167,15 +169,18 @@ static bool cmd_exec_always(int argc, char **argv) { | |||
167 | exit(-1); | 169 | exit(-1); |
168 | } | 170 | } |
169 | /* Parent */ | 171 | /* Parent */ |
170 | return true; | 172 | return CMD_SUCCESS; |
171 | } | 173 | } |
172 | 174 | ||
173 | static bool cmd_exec(int argc, char **argv) { | 175 | static enum cmd_status cmd_exec(int argc, char **argv) { |
176 | if (!config->active) { | ||
177 | return CMD_DEFER; | ||
178 | } | ||
174 | if (config->reloading) { | 179 | if (config->reloading) { |
175 | char *args = join_args(argv, argc); | 180 | char *args = join_args(argv, argc); |
176 | sway_log(L_DEBUG, "Ignoring exec %s due to reload", args); | 181 | sway_log(L_DEBUG, "Ignoring 'exec %s' due to reload", args); |
177 | free(args); | 182 | free(args); |
178 | return true; | 183 | return CMD_SUCCESS; |
179 | } | 184 | } |
180 | return cmd_exec_always(argc, argv); | 185 | return cmd_exec_always(argc, argv); |
181 | } | 186 | } |
@@ -186,26 +191,28 @@ static void kill_views(swayc_t *container, void *data) { | |||
186 | } | 191 | } |
187 | } | 192 | } |
188 | 193 | ||
189 | static bool cmd_exit(int argc, char **argv) { | 194 | static enum cmd_status cmd_exit(int argc, char **argv) { |
190 | if (!checkarg(argc, "exit", EXPECTED_EQUAL_TO, 0)) { | 195 | if (!checkarg(argc, "exit", EXPECTED_EQUAL_TO, 0) |
191 | return false; | 196 | || config->reading || !config->active) { |
197 | return CMD_FAILURE; | ||
192 | } | 198 | } |
193 | // Close all views | 199 | // Close all views |
194 | container_map(&root_container, kill_views, NULL); | 200 | container_map(&root_container, kill_views, NULL); |
195 | sway_terminate(); | 201 | sway_terminate(); |
196 | return true; | 202 | return CMD_SUCCESS; |
197 | } | 203 | } |
198 | 204 | ||
199 | static bool cmd_floating(int argc, char **argv) { | 205 | static enum cmd_status cmd_floating(int argc, char **argv) { |
200 | if (!checkarg(argc, "floating", EXPECTED_EQUAL_TO, 1)) { | 206 | if (!checkarg(argc, "floating", EXPECTED_EQUAL_TO, 1) |
201 | return false; | 207 | || config->reading || !config->active) { |
208 | return CMD_FAILURE; | ||
202 | } | 209 | } |
203 | 210 | ||
204 | if (strcasecmp(argv[0], "toggle") == 0) { | 211 | if (strcasecmp(argv[0], "toggle") == 0) { |
205 | swayc_t *view = get_focused_container(&root_container); | 212 | swayc_t *view = get_focused_container(&root_container); |
206 | // Prevent running floating commands on things like workspaces | 213 | // Prevent running floating commands on things like workspaces |
207 | if (view->type != C_VIEW) { | 214 | if (view->type != C_VIEW) { |
208 | return true; | 215 | return CMD_SUCCESS; |
209 | } | 216 | } |
210 | // Change from nonfloating to floating | 217 | // Change from nonfloating to floating |
211 | if (!view->is_floating) { | 218 | if (!view->is_floating) { |
@@ -254,12 +261,13 @@ static bool cmd_floating(int argc, char **argv) { | |||
254 | } | 261 | } |
255 | set_focused_container(view); | 262 | set_focused_container(view); |
256 | } | 263 | } |
257 | return true; | 264 | return CMD_SUCCESS; |
258 | } | 265 | } |
259 | 266 | ||
260 | static bool cmd_floating_mod(int argc, char **argv) { | 267 | static enum cmd_status cmd_floating_mod(int argc, char **argv) { |
261 | if (!checkarg(argc, "floating_modifier", EXPECTED_EQUAL_TO, 1)) { | 268 | if (!checkarg(argc, "floating_modifier", EXPECTED_EQUAL_TO, 1) |
262 | return false; | 269 | || !config->reading) { |
270 | return CMD_FAILURE; | ||
263 | } | 271 | } |
264 | int i, j; | 272 | int i, j; |
265 | list_t *split = split_string(argv[0], "+"); | 273 | list_t *split = split_string(argv[0], "+"); |
@@ -276,27 +284,28 @@ static bool cmd_floating_mod(int argc, char **argv) { | |||
276 | free_flat_list(split); | 284 | free_flat_list(split); |
277 | if (!config->floating_mod) { | 285 | if (!config->floating_mod) { |
278 | sway_log(L_ERROR, "bindsym - unknown keys %s", argv[0]); | 286 | sway_log(L_ERROR, "bindsym - unknown keys %s", argv[0]); |
279 | return false; | 287 | return CMD_FAILURE; |
280 | } | 288 | } |
281 | return true; | 289 | return CMD_SUCCESS; |
282 | } | 290 | } |
283 | 291 | ||
284 | static bool cmd_focus(int argc, char **argv) { | 292 | static enum cmd_status cmd_focus(int argc, char **argv) { |
285 | static int floating_toggled_index = 0; | 293 | static int floating_toggled_index = 0; |
286 | static int tiled_toggled_index = 0; | 294 | static int tiled_toggled_index = 0; |
287 | if (!checkarg(argc, "focus", EXPECTED_EQUAL_TO, 1)) { | 295 | if (!checkarg(argc, "focus", EXPECTED_EQUAL_TO, 1) |
288 | return false; | 296 | || config->reading || !config->active) { |
297 | return CMD_FAILURE; | ||
289 | } | 298 | } |
290 | if (strcasecmp(argv[0], "left") == 0) { | 299 | if (strcasecmp(argv[0], "left") == 0) { |
291 | return move_focus(MOVE_LEFT); | 300 | move_focus(MOVE_LEFT); |
292 | } else if (strcasecmp(argv[0], "right") == 0) { | 301 | } else if (strcasecmp(argv[0], "right") == 0) { |
293 | return move_focus(MOVE_RIGHT); | 302 | move_focus(MOVE_RIGHT); |
294 | } else if (strcasecmp(argv[0], "up") == 0) { | 303 | } else if (strcasecmp(argv[0], "up") == 0) { |
295 | return move_focus(MOVE_UP); | 304 | move_focus(MOVE_UP); |
296 | } else if (strcasecmp(argv[0], "down") == 0) { | 305 | } else if (strcasecmp(argv[0], "down") == 0) { |
297 | return move_focus(MOVE_DOWN); | 306 | move_focus(MOVE_DOWN); |
298 | } else if (strcasecmp(argv[0], "parent") == 0) { | 307 | } else if (strcasecmp(argv[0], "parent") == 0) { |
299 | return move_focus(MOVE_PARENT); | 308 | move_focus(MOVE_PARENT); |
300 | } else if (strcasecmp(argv[0], "mode_toggle") == 0) { | 309 | } else if (strcasecmp(argv[0], "mode_toggle") == 0) { |
301 | int i; | 310 | int i; |
302 | swayc_t *workspace = swayc_active_workspace(); | 311 | swayc_t *workspace = swayc_active_workspace(); |
@@ -335,17 +344,16 @@ static bool cmd_focus(int argc, char **argv) { | |||
335 | } | 344 | } |
336 | } | 345 | } |
337 | } | 346 | } |
338 | 347 | return CMD_SUCCESS; | |
339 | return true; | ||
340 | } | 348 | } |
341 | 349 | ||
342 | static bool cmd_focus_follows_mouse(int argc, char **argv) { | 350 | static enum cmd_status cmd_focus_follows_mouse(int argc, char **argv) { |
343 | if (!checkarg(argc, "focus_follows_mouse", EXPECTED_EQUAL_TO, 1)) { | 351 | if (!checkarg(argc, "focus_follows_mouse", EXPECTED_EQUAL_TO, 1)) { |
344 | return false; | 352 | return CMD_FAILURE; |
345 | } | 353 | } |
346 | 354 | ||
347 | config->focus_follows_mouse = !strcasecmp(argv[0], "yes"); | 355 | config->focus_follows_mouse = !strcasecmp(argv[0], "yes"); |
348 | return true; | 356 | return CMD_SUCCESS; |
349 | } | 357 | } |
350 | 358 | ||
351 | static void hide_view_in_scratchpad(swayc_t *sp_view) { | 359 | static void hide_view_in_scratchpad(swayc_t *sp_view) { |
@@ -364,12 +372,16 @@ static void hide_view_in_scratchpad(swayc_t *sp_view) { | |||
364 | set_focused_container(container_under_pointer()); | 372 | set_focused_container(container_under_pointer()); |
365 | } | 373 | } |
366 | 374 | ||
367 | static bool cmd_mode(int argc, char **argv) { | 375 | static enum cmd_status cmd_mode(int argc, char **argv) { |
368 | if (!checkarg(argc, "move", EXPECTED_AT_LEAST, 1)) { | 376 | if (!checkarg(argc, "move", EXPECTED_AT_LEAST, 1)) { |
369 | return false; | 377 | return CMD_FAILURE; |
370 | } | 378 | } |
371 | bool mode_make = strcmp(argv[argc-1], "{") == 0; | 379 | bool mode_make = !strcmp(argv[argc-1], "{"); |
372 | const char *mode_name = join_args(argv, argc - mode_make); | 380 | if (mode_make && !config->reading) { |
381 | return CMD_FAILURE; | ||
382 | } | ||
383 | |||
384 | char *mode_name = join_args(argv, argc - mode_make); | ||
373 | struct sway_mode *mode = NULL; | 385 | struct sway_mode *mode = NULL; |
374 | // Find mode | 386 | // Find mode |
375 | int i, len = config->modes->length; | 387 | int i, len = config->modes->length; |
@@ -389,17 +401,20 @@ static bool cmd_mode(int argc, char **argv) { | |||
389 | } | 401 | } |
390 | if (!mode) { | 402 | if (!mode) { |
391 | sway_log(L_ERROR, "Unknown mode `%s'", mode_name); | 403 | sway_log(L_ERROR, "Unknown mode `%s'", mode_name); |
392 | return false; | 404 | free(mode_name); |
405 | return CMD_FAILURE; | ||
393 | } | 406 | } |
394 | sway_log(L_DEBUG, "Switching to mode `%s'",mode->name); | 407 | sway_log(L_DEBUG, "Switching to mode `%s'",mode->name); |
408 | free(mode_name); | ||
395 | // Set current mode | 409 | // Set current mode |
396 | config->current_mode = mode; | 410 | config->current_mode = mode; |
397 | return true; | 411 | return CMD_SUCCESS; |
398 | } | 412 | } |
399 | 413 | ||
400 | static bool cmd_move(int argc, char **argv) { | 414 | static enum cmd_status cmd_move(int argc, char **argv) { |
401 | if (!checkarg(argc, "move", EXPECTED_AT_LEAST, 1)) { | 415 | if (!checkarg(argc, "move", EXPECTED_AT_LEAST, 1) |
402 | return false; | 416 | || config->reading || !config->active) { |
417 | return CMD_FAILURE; | ||
403 | } | 418 | } |
404 | 419 | ||
405 | swayc_t *view = get_focused_container(&root_container); | 420 | swayc_t *view = get_focused_container(&root_container); |
@@ -414,14 +429,14 @@ static bool cmd_move(int argc, char **argv) { | |||
414 | move_container(view, MOVE_DOWN); | 429 | move_container(view, MOVE_DOWN); |
415 | } else if (strcasecmp(argv[0], "container") == 0 || strcasecmp(argv[0], "window") == 0) { | 430 | } else if (strcasecmp(argv[0], "container") == 0 || strcasecmp(argv[0], "window") == 0) { |
416 | // "move container to workspace x" | 431 | // "move container to workspace x" |
417 | if (!checkarg(argc, "move container/window", EXPECTED_EQUAL_TO, 4) || | 432 | if (!checkarg(argc, "move container/window", EXPECTED_EQUAL_TO, 4) |
418 | strcasecmp(argv[1], "to") != 0 || | 433 | || strcasecmp(argv[1], "to") != 0 |
419 | strcasecmp(argv[2], "workspace") != 0) { | 434 | || strcasecmp(argv[2], "workspace") != 0) { |
420 | return false; | 435 | return CMD_FAILURE; |
421 | } | 436 | } |
422 | 437 | ||
423 | if (view->type != C_CONTAINER && view->type != C_VIEW) { | 438 | if (view->type != C_CONTAINER && view->type != C_VIEW) { |
424 | return false; | 439 | return CMD_FAILURE; |
425 | } | 440 | } |
426 | 441 | ||
427 | const char *ws_name = argv[3]; | 442 | const char *ws_name = argv[3]; |
@@ -437,7 +452,7 @@ static bool cmd_move(int argc, char **argv) { | |||
437 | move_container_to(view, get_focused_container(ws)); | 452 | move_container_to(view, get_focused_container(ws)); |
438 | } else if (strcasecmp(argv[0], "scratchpad") == 0) { | 453 | } else if (strcasecmp(argv[0], "scratchpad") == 0) { |
439 | if (view->type != C_CONTAINER && view->type != C_VIEW) { | 454 | if (view->type != C_CONTAINER && view->type != C_VIEW) { |
440 | return false; | 455 | return CMD_FAILURE; |
441 | } | 456 | } |
442 | swayc_t *view = get_focused_container(&root_container); | 457 | swayc_t *view = get_focused_container(&root_container); |
443 | int i; | 458 | int i; |
@@ -445,7 +460,7 @@ static bool cmd_move(int argc, char **argv) { | |||
445 | if (scratchpad->items[i] == view) { | 460 | if (scratchpad->items[i] == view) { |
446 | hide_view_in_scratchpad(view); | 461 | hide_view_in_scratchpad(view); |
447 | sp_view = NULL; | 462 | sp_view = NULL; |
448 | return true; | 463 | return CMD_SUCCESS; |
449 | } | 464 | } |
450 | } | 465 | } |
451 | list_add(scratchpad, view); | 466 | list_add(scratchpad, view); |
@@ -462,12 +477,16 @@ static bool cmd_move(int argc, char **argv) { | |||
462 | } | 477 | } |
463 | set_focused_container(focused); | 478 | set_focused_container(focused); |
464 | } else { | 479 | } else { |
465 | return false; | 480 | return CMD_FAILURE; |
466 | } | 481 | } |
467 | return true; | 482 | return CMD_SUCCESS; |
468 | } | 483 | } |
469 | 484 | ||
470 | static bool cmd_orientation(int argc, char **argv) { | 485 | static enum cmd_status cmd_orientation(int argc, char **argv) { |
486 | if (!checkarg(argc, "orientation", EXPECTED_EQUAL_TO, 1) | ||
487 | || !config->reading) { | ||
488 | return CMD_FAILURE; | ||
489 | } | ||
471 | if (strcasecmp(argv[0], "horizontal") == 0) { | 490 | if (strcasecmp(argv[0], "horizontal") == 0) { |
472 | config->default_orientation = L_HORIZ; | 491 | config->default_orientation = L_HORIZ; |
473 | } else if (strcasecmp(argv[0], "vertical") == 0) { | 492 | } else if (strcasecmp(argv[0], "vertical") == 0) { |
@@ -475,14 +494,14 @@ static bool cmd_orientation(int argc, char **argv) { | |||
475 | } else if (strcasecmp(argv[0], "auto") == 0) { | 494 | } else if (strcasecmp(argv[0], "auto") == 0) { |
476 | // Do nothing | 495 | // Do nothing |
477 | } else { | 496 | } else { |
478 | return false; | 497 | return CMD_FAILURE; |
479 | } | 498 | } |
480 | return true; | 499 | return CMD_SUCCESS; |
481 | } | 500 | } |
482 | 501 | ||
483 | static bool cmd_output(int argc, char **argv) { | 502 | static enum cmd_status cmd_output(int argc, char **argv) { |
484 | if (!checkarg(argc, "output", EXPECTED_AT_LEAST, 1)) { | 503 | if (!checkarg(argc, "output", EXPECTED_AT_LEAST, 1)) { |
485 | return false; | 504 | return CMD_FAILURE; |
486 | } | 505 | } |
487 | 506 | ||
488 | struct output_config *output = calloc(1, sizeof(struct output_config)); | 507 | struct output_config *output = calloc(1, sizeof(struct output_config)); |
@@ -542,12 +561,12 @@ static bool cmd_output(int argc, char **argv) { | |||
542 | sway_log(L_DEBUG, "Configured output %s to %d x %d @ %d, %d", | 561 | sway_log(L_DEBUG, "Configured output %s to %d x %d @ %d, %d", |
543 | output->name, output->width, output->height, output->x, output->y); | 562 | output->name, output->width, output->height, output->x, output->y); |
544 | 563 | ||
545 | return true; | 564 | return CMD_SUCCESS; |
546 | } | 565 | } |
547 | 566 | ||
548 | static bool cmd_gaps(int argc, char **argv) { | 567 | static enum cmd_status cmd_gaps(int argc, char **argv) { |
549 | if (!checkarg(argc, "gaps", EXPECTED_AT_LEAST, 1)) { | 568 | if (!checkarg(argc, "gaps", EXPECTED_AT_LEAST, 1)) { |
550 | return false; | 569 | return CMD_FAILURE; |
551 | } | 570 | } |
552 | const char *amount_str = argv[0]; | 571 | const char *amount_str = argv[0]; |
553 | // gaps amount | 572 | // gaps amount |
@@ -555,7 +574,7 @@ static bool cmd_gaps(int argc, char **argv) { | |||
555 | int amount = (int)strtol(amount_str, NULL, 10); | 574 | int amount = (int)strtol(amount_str, NULL, 10); |
556 | if (errno == ERANGE || amount == 0) { | 575 | if (errno == ERANGE || amount == 0) { |
557 | errno = 0; | 576 | errno = 0; |
558 | return false; | 577 | return CMD_FAILURE; |
559 | } | 578 | } |
560 | if (config->gaps_inner == 0) { | 579 | if (config->gaps_inner == 0) { |
561 | config->gaps_inner = amount; | 580 | config->gaps_inner = amount; |
@@ -563,14 +582,14 @@ static bool cmd_gaps(int argc, char **argv) { | |||
563 | if (config->gaps_outer == 0) { | 582 | if (config->gaps_outer == 0) { |
564 | config->gaps_outer = amount; | 583 | config->gaps_outer = amount; |
565 | } | 584 | } |
566 | return true; | 585 | return CMD_SUCCESS; |
567 | } | 586 | } |
568 | // gaps inner|outer n | 587 | // gaps inner|outer n |
569 | else if (argc >= 2 && isdigit((amount_str = argv[1])[0])) { | 588 | else if (argc >= 2 && isdigit((amount_str = argv[1])[0])) { |
570 | int amount = (int)strtol(amount_str, NULL, 10); | 589 | int amount = (int)strtol(amount_str, NULL, 10); |
571 | if (errno == ERANGE || amount == 0) { | 590 | if (errno == ERANGE || amount == 0) { |
572 | errno = 0; | 591 | errno = 0; |
573 | return false; | 592 | return CMD_FAILURE; |
574 | } | 593 | } |
575 | const char *target_str = argv[0]; | 594 | const char *target_str = argv[0]; |
576 | if (strcasecmp(target_str, "inner") == 0) { | 595 | if (strcasecmp(target_str, "inner") == 0) { |
@@ -578,11 +597,11 @@ static bool cmd_gaps(int argc, char **argv) { | |||
578 | } else if (strcasecmp(target_str, "outer") == 0) { | 597 | } else if (strcasecmp(target_str, "outer") == 0) { |
579 | config->gaps_outer = amount; | 598 | config->gaps_outer = amount; |
580 | } | 599 | } |
581 | return true; | 600 | return CMD_SUCCESS; |
582 | } | 601 | } |
583 | // gaps inner|outer current|all set|plus|minus n | 602 | // gaps inner|outer current|all set|plus|minus n |
584 | if (argc < 4) { | 603 | if (argc < 4 || config->reading) { |
585 | return false; | 604 | return CMD_FAILURE; |
586 | } | 605 | } |
587 | // gaps inner|outer ... | 606 | // gaps inner|outer ... |
588 | const char *inout_str = argv[0]; | 607 | const char *inout_str = argv[0]; |
@@ -592,7 +611,7 @@ static bool cmd_gaps(int argc, char **argv) { | |||
592 | } else if (strcasecmp(inout_str, "outer") == 0) { | 611 | } else if (strcasecmp(inout_str, "outer") == 0) { |
593 | inout = OUTER; | 612 | inout = OUTER; |
594 | } else { | 613 | } else { |
595 | return false; | 614 | return CMD_FAILURE; |
596 | } | 615 | } |
597 | 616 | ||
598 | // gaps ... current|all ... | 617 | // gaps ... current|all ... |
@@ -610,7 +629,7 @@ static bool cmd_gaps(int argc, char **argv) { | |||
610 | target = WORKSPACE; | 629 | target = WORKSPACE; |
611 | } | 630 | } |
612 | } else { | 631 | } else { |
613 | return false; | 632 | return CMD_FAILURE; |
614 | } | 633 | } |
615 | 634 | ||
616 | // gaps ... n | 635 | // gaps ... n |
@@ -618,7 +637,7 @@ static bool cmd_gaps(int argc, char **argv) { | |||
618 | int amount = (int)strtol(amount_str, NULL, 10); | 637 | int amount = (int)strtol(amount_str, NULL, 10); |
619 | if (errno == ERANGE || amount == 0) { | 638 | if (errno == ERANGE || amount == 0) { |
620 | errno = 0; | 639 | errno = 0; |
621 | return false; | 640 | return CMD_FAILURE; |
622 | } | 641 | } |
623 | 642 | ||
624 | // gaps ... set|plus|minus ... | 643 | // gaps ... set|plus|minus ... |
@@ -632,18 +651,18 @@ static bool cmd_gaps(int argc, char **argv) { | |||
632 | method = ADD; | 651 | method = ADD; |
633 | amount *= -1; | 652 | amount *= -1; |
634 | } else { | 653 | } else { |
635 | return false; | 654 | return CMD_FAILURE; |
636 | } | 655 | } |
637 | 656 | ||
638 | if (target == CURRENT) { | 657 | if (target == CURRENT) { |
639 | swayc_t *cont; | 658 | swayc_t *cont; |
640 | if (inout == OUTER) { | 659 | if (inout == OUTER) { |
641 | if ((cont = swayc_active_workspace()) == NULL) { | 660 | if ((cont = swayc_active_workspace()) == NULL) { |
642 | return false; | 661 | return CMD_FAILURE; |
643 | } | 662 | } |
644 | } else { | 663 | } else { |
645 | if ((cont = get_focused_view(&root_container))->type != C_VIEW) { | 664 | if ((cont = get_focused_view(&root_container))->type != C_VIEW) { |
646 | return false; | 665 | return CMD_FAILURE; |
647 | } | 666 | } |
648 | } | 667 | } |
649 | cont->gaps = swayc_gap(cont); | 668 | cont->gaps = swayc_gap(cont); |
@@ -673,7 +692,7 @@ static bool cmd_gaps(int argc, char **argv) { | |||
673 | swayc_t *top; | 692 | swayc_t *top; |
674 | if (target == WORKSPACE) { | 693 | if (target == WORKSPACE) { |
675 | if ((top = swayc_active_workspace()) == NULL) { | 694 | if ((top = swayc_active_workspace()) == NULL) { |
676 | return false; | 695 | return CMD_FAILURE; |
677 | } | 696 | } |
678 | } else { | 697 | } else { |
679 | top = &root_container; | 698 | top = &root_container; |
@@ -684,18 +703,22 @@ static bool cmd_gaps(int argc, char **argv) { | |||
684 | arrange_windows(top, -1, -1); | 703 | arrange_windows(top, -1, -1); |
685 | } | 704 | } |
686 | 705 | ||
687 | return true; | 706 | return CMD_SUCCESS; |
688 | } | 707 | } |
689 | 708 | ||
690 | static bool cmd_kill(int argc, char **argv) { | 709 | static enum cmd_status cmd_kill(int argc, char **argv) { |
710 | if (config->reading || !config->active) { | ||
711 | return CMD_FAILURE; | ||
712 | } | ||
691 | swayc_t *view = get_focused_container(&root_container); | 713 | swayc_t *view = get_focused_container(&root_container); |
692 | wlc_view_close(view->handle); | 714 | wlc_view_close(view->handle); |
693 | return true; | 715 | return CMD_SUCCESS; |
694 | } | 716 | } |
695 | 717 | ||
696 | static bool cmd_layout(int argc, char **argv) { | 718 | static enum cmd_status cmd_layout(int argc, char **argv) { |
697 | if (!checkarg(argc, "layout", EXPECTED_MORE_THAN, 0)) { | 719 | if (!checkarg(argc, "layout", EXPECTED_MORE_THAN, 0) |
698 | return false; | 720 | || config->reading || !config->active) { |
721 | return CMD_FAILURE; | ||
699 | } | 722 | } |
700 | swayc_t *parent = get_focused_container(&root_container); | 723 | swayc_t *parent = get_focused_container(&root_container); |
701 | while (parent->type == C_VIEW) { | 724 | while (parent->type == C_VIEW) { |
@@ -715,33 +738,33 @@ static bool cmd_layout(int argc, char **argv) { | |||
715 | } | 738 | } |
716 | arrange_windows(parent, parent->width, parent->height); | 739 | arrange_windows(parent, parent->width, parent->height); |
717 | 740 | ||
718 | return true; | 741 | return CMD_SUCCESS; |
719 | } | 742 | } |
720 | 743 | ||
721 | static bool cmd_reload(int argc, char **argv) { | 744 | static enum cmd_status cmd_reload(int argc, char **argv) { |
722 | if (!checkarg(argc, "reload", EXPECTED_EQUAL_TO, 0)) { | 745 | if (!checkarg(argc, "reload", EXPECTED_EQUAL_TO, 0) |
723 | return false; | 746 | || config->reading |
724 | } | 747 | || !load_config(NULL)) { |
725 | if (!load_config(NULL)) { // TODO: Use config given from -c | 748 | return CMD_FAILURE; |
726 | return false; | ||
727 | } | 749 | } |
728 | arrange_windows(&root_container, -1, -1); | 750 | arrange_windows(&root_container, -1, -1); |
729 | return true; | 751 | return CMD_SUCCESS; |
730 | } | 752 | } |
731 | 753 | ||
732 | static bool cmd_resize(int argc, char **argv) { | 754 | static enum cmd_status cmd_resize(int argc, char **argv) { |
733 | if (!checkarg(argc, "resize", EXPECTED_AT_LEAST, 3)) { | 755 | if (!checkarg(argc, "resize", EXPECTED_AT_LEAST, 3) |
734 | return false; | 756 | || config->reading || !config->active) { |
757 | return CMD_FAILURE; | ||
735 | } | 758 | } |
736 | char *end; | 759 | char *end; |
737 | int amount = (int)strtol(argv[2], &end, 10); | 760 | int amount = (int)strtol(argv[2], &end, 10); |
738 | if (errno == ERANGE || amount == 0) { | 761 | if (errno == ERANGE || amount == 0) { |
739 | errno = 0; | 762 | errno = 0; |
740 | return false; | 763 | return CMD_FAILURE; |
741 | } | 764 | } |
742 | 765 | ||
743 | if (strcmp(argv[0], "shrink") != 0 && strcmp(argv[0], "grow") != 0) { | 766 | if (strcmp(argv[0], "shrink") != 0 && strcmp(argv[0], "grow") != 0) { |
744 | return false; | 767 | return CMD_FAILURE; |
745 | } | 768 | } |
746 | 769 | ||
747 | if (strcmp(argv[0], "shrink") == 0) { | 770 | if (strcmp(argv[0], "shrink") == 0) { |
@@ -749,11 +772,13 @@ static bool cmd_resize(int argc, char **argv) { | |||
749 | } | 772 | } |
750 | 773 | ||
751 | if (strcmp(argv[1], "width") == 0) { | 774 | if (strcmp(argv[1], "width") == 0) { |
752 | return resize_tiled(amount, true); | 775 | resize_tiled(amount, true); |
753 | } else if (strcmp(argv[1], "height") == 0) { | 776 | } else if (strcmp(argv[1], "height") == 0) { |
754 | return resize_tiled(amount, false); | 777 | resize_tiled(amount, false); |
778 | } else { | ||
779 | return CMD_FAILURE; | ||
755 | } | 780 | } |
756 | return false; | 781 | return CMD_SUCCESS; |
757 | } | 782 | } |
758 | 783 | ||
759 | static swayc_t *fetch_view_from_scratchpad() { | 784 | static swayc_t *fetch_view_from_scratchpad() { |
@@ -801,9 +826,10 @@ void remove_view_from_scratchpad(swayc_t *view) { | |||
801 | } | 826 | } |
802 | } | 827 | } |
803 | 828 | ||
804 | static bool cmd_scratchpad(int argc, char **argv) { | 829 | static enum cmd_status cmd_scratchpad(int argc, char **argv) { |
805 | if (!checkarg(argc, "scratchpad", EXPECTED_EQUAL_TO, 1)) { | 830 | if (!checkarg(argc, "scratchpad", EXPECTED_EQUAL_TO, 1) |
806 | return false; | 831 | || config->reading || !config->active) { |
832 | return CMD_FAILURE; | ||
807 | } | 833 | } |
808 | 834 | ||
809 | if (strcasecmp(argv[0], "show") == 0 && scratchpad->length > 0) { | 835 | if (strcasecmp(argv[0], "show") == 0 && scratchpad->length > 0) { |
@@ -822,10 +848,9 @@ static bool cmd_scratchpad(int argc, char **argv) { | |||
822 | sp_view = NULL; | 848 | sp_view = NULL; |
823 | } | 849 | } |
824 | } | 850 | } |
825 | return true; | 851 | return CMD_SUCCESS; |
826 | } else { | ||
827 | return false; | ||
828 | } | 852 | } |
853 | return CMD_FAILURE; | ||
829 | } | 854 | } |
830 | 855 | ||
831 | // sort in order of longest->shortest | 856 | // sort in order of longest->shortest |
@@ -835,9 +860,10 @@ static int compare_set(const void *_l, const void *_r) { | |||
835 | return strlen((*r)->name) - strlen((*l)->name); | 860 | return strlen((*r)->name) - strlen((*l)->name); |
836 | } | 861 | } |
837 | 862 | ||
838 | static bool cmd_set(int argc, char **argv) { | 863 | static enum cmd_status cmd_set(int argc, char **argv) { |
839 | if (!checkarg(argc, "set", EXPECTED_AT_LEAST, 2)) { | 864 | if (!checkarg(argc, "set", EXPECTED_AT_LEAST, 2) |
840 | return false; | 865 | || !config->reading) { |
866 | return CMD_FAILURE; | ||
841 | } | 867 | } |
842 | struct sway_variable *var = NULL; | 868 | struct sway_variable *var = NULL; |
843 | // Find old variable if it exists | 869 | // Find old variable if it exists |
@@ -858,20 +884,21 @@ static bool cmd_set(int argc, char **argv) { | |||
858 | list_sort(config->symbols, compare_set); | 884 | list_sort(config->symbols, compare_set); |
859 | } | 885 | } |
860 | var->value = join_args(argv + 1, argc - 1); | 886 | var->value = join_args(argv + 1, argc - 1); |
861 | return true; | 887 | return CMD_SUCCESS; |
862 | } | 888 | } |
863 | 889 | ||
864 | static bool _do_split(int argc, char **argv, int layout) { | 890 | static enum cmd_status _do_split(int argc, char **argv, int layout) { |
865 | char *name = layout == L_VERT ? "splitv" : | 891 | char *name = layout == L_VERT ? "splitv" : |
866 | layout == L_HORIZ ? "splith" : "split"; | 892 | layout == L_HORIZ ? "splith" : "split"; |
867 | if (!checkarg(argc, name, EXPECTED_EQUAL_TO, 0)) { | 893 | if (!checkarg(argc, name, EXPECTED_EQUAL_TO, 0) |
868 | return false; | 894 | || config->reading || !config->active) { |
895 | return CMD_FAILURE; | ||
869 | } | 896 | } |
870 | swayc_t *focused = get_focused_container(&root_container); | 897 | swayc_t *focused = get_focused_container(&root_container); |
871 | 898 | ||
872 | // Case of floating window, dont split | 899 | // Case of floating window, dont split |
873 | if (focused->is_floating) { | 900 | if (focused->is_floating) { |
874 | return true; | 901 | return CMD_SUCCESS; |
875 | } | 902 | } |
876 | /* Case that focus is on an workspace with 0/1 children.change its layout */ | 903 | /* Case that focus is on an workspace with 0/1 children.change its layout */ |
877 | if (focused->type == C_WORKSPACE && focused->children->length <= 1) { | 904 | if (focused->type == C_WORKSPACE && focused->children->length <= 1) { |
@@ -889,12 +916,13 @@ static bool _do_split(int argc, char **argv, int layout) { | |||
889 | set_focused_container(focused); | 916 | set_focused_container(focused); |
890 | arrange_windows(parent, -1, -1); | 917 | arrange_windows(parent, -1, -1); |
891 | } | 918 | } |
892 | return true; | 919 | return CMD_SUCCESS; |
893 | } | 920 | } |
894 | 921 | ||
895 | static bool cmd_split(int argc, char **argv) { | 922 | static enum cmd_status cmd_split(int argc, char **argv) { |
896 | if (!checkarg(argc, "split", EXPECTED_EQUAL_TO, 1)) { | 923 | if (!checkarg(argc, "split", EXPECTED_EQUAL_TO, 1) |
897 | return false; | 924 | || config->reading || !config->active) { |
925 | return CMD_FAILURE; | ||
898 | } | 926 | } |
899 | 927 | ||
900 | if (strcasecmp(argv[0], "v") == 0 || strcasecmp(argv[0], "vertical") == 0) { | 928 | if (strcasecmp(argv[0], "v") == 0 || strcasecmp(argv[0], "vertical") == 0) { |
@@ -903,36 +931,39 @@ static bool cmd_split(int argc, char **argv) { | |||
903 | _do_split(argc - 1, argv + 1, L_HORIZ); | 931 | _do_split(argc - 1, argv + 1, L_HORIZ); |
904 | } else { | 932 | } else { |
905 | sway_log(L_ERROR, "Invalid split command (expected either horiziontal or vertical)."); | 933 | sway_log(L_ERROR, "Invalid split command (expected either horiziontal or vertical)."); |
906 | return false; | 934 | return CMD_FAILURE; |
907 | } | 935 | } |
908 | 936 | return CMD_SUCCESS; | |
909 | return true; | ||
910 | } | 937 | } |
911 | 938 | ||
912 | static bool cmd_splitv(int argc, char **argv) { | 939 | static enum cmd_status cmd_splitv(int argc, char **argv) { |
913 | return _do_split(argc, argv, L_VERT); | 940 | return _do_split(argc, argv, L_VERT); |
914 | } | 941 | } |
915 | 942 | ||
916 | static bool cmd_splith(int argc, char **argv) { | 943 | static enum cmd_status cmd_splith(int argc, char **argv) { |
917 | return _do_split(argc, argv, L_HORIZ); | 944 | return _do_split(argc, argv, L_HORIZ); |
918 | } | 945 | } |
919 | 946 | ||
920 | static bool cmd_log_colors(int argc, char **argv) { | 947 | static enum cmd_status cmd_log_colors(int argc, char **argv) { |
921 | if (!checkarg(argc, "log_colors", EXPECTED_EQUAL_TO, 1)) { | 948 | if (!checkarg(argc, "log_colors", EXPECTED_EQUAL_TO, 1) |
922 | return false; | 949 | || !config->reading) { |
950 | return CMD_FAILURE; | ||
923 | } | 951 | } |
924 | if (strcasecmp(argv[0], "no") != 0 && strcasecmp(argv[0], "yes") != 0) { | 952 | if (strcasecmp(argv[0], "no") == 0) { |
953 | sway_log_colors(0); | ||
954 | } else if(strcasecmp(argv[0], "yes") == 0) { | ||
955 | sway_log_colors(1); | ||
956 | } else { | ||
925 | sway_log(L_ERROR, "Invalid log_colors command (expected `yes` or `no`, got '%s')", argv[0]); | 957 | sway_log(L_ERROR, "Invalid log_colors command (expected `yes` or `no`, got '%s')", argv[0]); |
926 | return false; | 958 | return CMD_FAILURE; |
927 | } | 959 | } |
928 | 960 | return CMD_SUCCESS; | |
929 | sway_log_colors(!strcasecmp(argv[0], "yes")); | ||
930 | return true; | ||
931 | } | 961 | } |
932 | 962 | ||
933 | static bool cmd_fullscreen(int argc, char **argv) { | 963 | static enum cmd_status cmd_fullscreen(int argc, char **argv) { |
934 | if (!checkarg(argc, "fullscreen", EXPECTED_AT_LEAST, 0)) { | 964 | if (!checkarg(argc, "fullscreen", EXPECTED_AT_LEAST, 0) |
935 | return false; | 965 | || config->reading || !config->active) { |
966 | return CMD_FAILURE; | ||
936 | } | 967 | } |
937 | 968 | ||
938 | swayc_t *container = get_focused_view(&root_container); | 969 | swayc_t *container = get_focused_view(&root_container); |
@@ -946,103 +977,100 @@ static bool cmd_fullscreen(int argc, char **argv) { | |||
946 | // Only resize container when going into fullscreen | 977 | // Only resize container when going into fullscreen |
947 | arrange_windows(container, -1, -1); | 978 | arrange_windows(container, -1, -1); |
948 | 979 | ||
949 | return true; | 980 | return CMD_SUCCESS; |
950 | } | 981 | } |
951 | 982 | ||
952 | static bool cmd_workspace(int argc, char **argv) { | 983 | static enum cmd_status cmd_workspace(int argc, char **argv) { |
953 | if (!checkarg(argc, "workspace", EXPECTED_AT_LEAST, 1)) { | 984 | if (!checkarg(argc, "workspace", EXPECTED_AT_LEAST, 1)) { |
954 | return false; | 985 | return CMD_FAILURE; |
955 | } | 986 | } |
956 | 987 | ||
957 | if (argc == 1) { | 988 | if (argc == 1) { |
989 | if (config->reading || !config->active) { | ||
990 | return CMD_DEFER; | ||
991 | } | ||
958 | // Handle workspace next/prev | 992 | // Handle workspace next/prev |
993 | swayc_t *ws = NULL; | ||
959 | if (strcasecmp(argv[0], "next") == 0) { | 994 | if (strcasecmp(argv[0], "next") == 0) { |
960 | workspace_switch(workspace_next()); | 995 | ws = workspace_next(); |
961 | return true; | 996 | } else if (strcasecmp(argv[0], "prev") == 0) { |
962 | } | 997 | ws = workspace_prev(); |
963 | 998 | } else if (strcasecmp(argv[0], "next_on_output") == 0) { | |
964 | if (strcasecmp(argv[0], "prev") == 0) { | 999 | ws = workspace_output_next(); |
965 | workspace_switch(workspace_prev()); | 1000 | } else if (strcasecmp(argv[0], "prev_on_output") == 0) { |
966 | return true; | 1001 | ws = workspace_output_prev(); |
967 | } | 1002 | } else if (strcasecmp(argv[0], "back_and_forth") == 0) { |
968 | |||
969 | // Handle workspace output_next/prev | ||
970 | if (strcasecmp(argv[0], "next_on_output") == 0) { | ||
971 | workspace_switch(workspace_output_next()); | ||
972 | return true; | ||
973 | } | ||
974 | |||
975 | if (strcasecmp(argv[0], "prev_on_output") == 0) { | ||
976 | workspace_switch(workspace_output_prev()); | ||
977 | return true; | ||
978 | } | ||
979 | if (strcasecmp(argv[0], "back_and_forth") == 0) { | ||
980 | if (prev_workspace_name) { | 1003 | if (prev_workspace_name) { |
981 | swayc_t *ws = workspace_by_name(prev_workspace_name); | 1004 | if (!(ws = workspace_by_name(prev_workspace_name))) { |
982 | workspace_switch(ws ? ws : workspace_create(prev_workspace_name)); | 1005 | ws = workspace_create(prev_workspace_name); |
1006 | } | ||
1007 | } | ||
1008 | } else { | ||
1009 | if (!(ws= workspace_by_name(argv[0]))) { | ||
1010 | ws = workspace_create(argv[0]); | ||
983 | } | 1011 | } |
984 | return true; | ||
985 | } | ||
986 | |||
987 | swayc_t *workspace = workspace_by_name(argv[0]); | ||
988 | if (!workspace) { | ||
989 | workspace = workspace_create(argv[0]); | ||
990 | } | 1012 | } |
991 | workspace_switch(workspace); | 1013 | workspace_switch(ws); |
992 | } else { | 1014 | } else { |
993 | if (strcasecmp(argv[1], "output") == 0) { | 1015 | if (strcasecmp(argv[1], "output") == 0) { |
994 | if (!checkarg(argc, "workspace", EXPECTED_EQUAL_TO, 3)) { | 1016 | if (!checkarg(argc, "workspace", EXPECTED_EQUAL_TO, 3)) { |
995 | return false; | 1017 | return CMD_FAILURE; |
996 | } | 1018 | } |
997 | struct workspace_output *wso = calloc(1, sizeof(struct workspace_output)); | 1019 | struct workspace_output *wso = calloc(1, sizeof(struct workspace_output)); |
998 | sway_log(L_DEBUG, "Assigning workspace %s to output %s", argv[0], argv[2]); | 1020 | sway_log(L_DEBUG, "Assigning workspace %s to output %s", argv[0], argv[2]); |
999 | wso->workspace = strdup(argv[0]); | 1021 | wso->workspace = strdup(argv[0]); |
1000 | wso->output = strdup(argv[2]); | 1022 | wso->output = strdup(argv[2]); |
1001 | list_add(config->workspace_outputs, wso); | 1023 | list_add(config->workspace_outputs, wso); |
1002 | // TODO: Consider moving any existing workspace to that output? This might be executed sometime after config load | 1024 | if (!config->reading) { |
1025 | // TODO: Move workspace to output. (dont do so when reloading) | ||
1026 | } | ||
1003 | } | 1027 | } |
1004 | } | 1028 | } |
1005 | return true; | 1029 | return CMD_SUCCESS; |
1006 | } | 1030 | } |
1007 | 1031 | ||
1008 | static bool cmd_ws_auto_back_and_forth(int argc, char **argv) { | 1032 | static enum cmd_status cmd_ws_auto_back_and_forth(int argc, char **argv) { |
1009 | if (!checkarg(argc, "workspace_auto_back_and_forth", EXPECTED_EQUAL_TO, 1)) { | 1033 | if (!checkarg(argc, "workspace_auto_back_and_forth", EXPECTED_EQUAL_TO, 1)) { |
1010 | return false; | 1034 | return CMD_FAILURE; |
1011 | } | 1035 | } |
1012 | if (strcasecmp(argv[0], "yes") == 0) { | 1036 | if (strcasecmp(argv[0], "yes") == 0) { |
1013 | config->auto_back_and_forth = true; | 1037 | config->auto_back_and_forth = true; |
1038 | } else if (strcasecmp(argv[0], "no") == 0) { | ||
1039 | config->auto_back_and_forth = false; | ||
1040 | } else { | ||
1041 | return CMD_FAILURE; | ||
1014 | } | 1042 | } |
1015 | return true; | 1043 | return CMD_SUCCESS; |
1016 | } | 1044 | } |
1017 | 1045 | ||
1018 | /* Keep alphabetized */ | 1046 | /* Keep alphabetized */ |
1019 | static struct cmd_handler handlers[] = { | 1047 | static struct cmd_handler handlers[] = { |
1020 | { "bindsym", cmd_bindsym, CMD_ANYTIME }, | 1048 | { "bindsym", cmd_bindsym }, |
1021 | { "default_orientation", cmd_orientation, CMD_ANYTIME}, | 1049 | { "default_orientation", cmd_orientation }, |
1022 | { "exec", cmd_exec, CMD_COMPOSITOR_READY }, | 1050 | { "exec", cmd_exec }, |
1023 | { "exec_always", cmd_exec_always, CMD_COMPOSITOR_READY }, | 1051 | { "exec_always", cmd_exec_always }, |
1024 | { "exit", cmd_exit, CMD_KEYBIND }, | 1052 | { "exit", cmd_exit }, |
1025 | { "floating", cmd_floating, CMD_KEYBIND }, | 1053 | { "floating", cmd_floating }, |
1026 | { "floating_modifier", cmd_floating_mod, CMD_ANYTIME }, | 1054 | { "floating_modifier", cmd_floating_mod }, |
1027 | { "focus", cmd_focus, CMD_KEYBIND }, | 1055 | { "focus", cmd_focus }, |
1028 | { "focus_follows_mouse", cmd_focus_follows_mouse, CMD_ANYTIME }, | 1056 | { "focus_follows_mouse", cmd_focus_follows_mouse }, |
1029 | { "fullscreen", cmd_fullscreen, CMD_KEYBIND }, | 1057 | { "fullscreen", cmd_fullscreen }, |
1030 | { "gaps", cmd_gaps, CMD_ANYTIME }, | 1058 | { "gaps", cmd_gaps }, |
1031 | { "kill", cmd_kill, CMD_KEYBIND }, | 1059 | { "kill", cmd_kill }, |
1032 | { "layout", cmd_layout, CMD_KEYBIND }, | 1060 | { "layout", cmd_layout }, |
1033 | { "log_colors", cmd_log_colors, CMD_ANYTIME }, | 1061 | { "log_colors", cmd_log_colors }, |
1034 | { "mode", cmd_mode, CMD_ANYTIME }, | 1062 | { "mode", cmd_mode }, |
1035 | { "move", cmd_move, CMD_KEYBIND }, | 1063 | { "move", cmd_move }, |
1036 | { "output", cmd_output, CMD_ANYTIME }, | 1064 | { "output", cmd_output }, |
1037 | { "reload", cmd_reload, CMD_KEYBIND }, | 1065 | { "reload", cmd_reload }, |
1038 | { "resize", cmd_resize, CMD_KEYBIND }, | 1066 | { "resize", cmd_resize }, |
1039 | { "scratchpad", cmd_scratchpad, CMD_KEYBIND }, | 1067 | { "scratchpad", cmd_scratchpad }, |
1040 | { "set", cmd_set, CMD_ANYTIME }, | 1068 | { "set", cmd_set }, |
1041 | { "split", cmd_split, CMD_KEYBIND }, | 1069 | { "split", cmd_split }, |
1042 | { "splith", cmd_splith, CMD_KEYBIND }, | 1070 | { "splith", cmd_splith }, |
1043 | { "splitv", cmd_splitv, CMD_KEYBIND }, | 1071 | { "splitv", cmd_splitv }, |
1044 | { "workspace", cmd_workspace, CMD_COMPOSITOR_READY }, | 1072 | { "workspace", cmd_workspace }, |
1045 | { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth, CMD_ANYTIME }, | 1073 | { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth }, |
1046 | }; | 1074 | }; |
1047 | 1075 | ||
1048 | static int handler_compare(const void *_a, const void *_b) { | 1076 | static int handler_compare(const void *_a, const void *_b) { |
@@ -1059,63 +1087,58 @@ static struct cmd_handler *find_handler(char *line) { | |||
1059 | return res; | 1087 | return res; |
1060 | } | 1088 | } |
1061 | 1089 | ||
1062 | bool handle_command(char *exec) { | 1090 | enum cmd_status handle_command(char *exec) { |
1063 | sway_log(L_INFO, "Handling command '%s'", exec); | 1091 | sway_log(L_INFO, "Handling command '%s'", exec); |
1064 | int argc; | 1092 | int argc; |
1065 | char **argv = split_args(exec, &argc); | 1093 | char **argv = split_args(exec, &argc); |
1066 | if (argc == 0) { | 1094 | enum cmd_status status = CMD_FAILURE; |
1067 | return false; | 1095 | struct cmd_handler *handler; |
1096 | if (!argc) { | ||
1097 | return status; | ||
1068 | } | 1098 | } |
1069 | struct cmd_handler *handler = find_handler(argv[0]); | 1099 | if ((handler = find_handler(argv[0])) == NULL |
1070 | bool exec_success = false; | 1100 | || (status = handler->handle(argc - 1, argv + 1)) != CMD_SUCCESS) { |
1071 | if (handler && !(handler->handle(argc - 1, argv + 1))) { | ||
1072 | sway_log(L_ERROR, "Command failed: %s", argv[0]); | 1101 | sway_log(L_ERROR, "Command failed: %s", argv[0]); |
1073 | } | 1102 | } |
1074 | free_argv(argc, argv); | 1103 | free_argv(argc, argv); |
1075 | return exec_success; | 1104 | return status; |
1076 | } | 1105 | } |
1077 | 1106 | ||
1078 | bool config_command(char *exec) { | 1107 | enum cmd_status config_command(char *exec) { |
1079 | sway_log(L_INFO, "handling config command '%s'", exec); | 1108 | sway_log(L_INFO, "handling config command '%s'", exec); |
1080 | struct cmd_handler *handler; | ||
1081 | int argc; | 1109 | int argc; |
1082 | char **argv = split_args(exec, &argc); | 1110 | char **argv = split_args(exec, &argc); |
1083 | bool res = false; | 1111 | enum cmd_status status = CMD_FAILURE; |
1112 | struct cmd_handler *handler; | ||
1084 | if (!argc) { | 1113 | if (!argc) { |
1085 | return true; | 1114 | status = CMD_SUCCESS; |
1115 | goto cleanup; | ||
1086 | } | 1116 | } |
1087 | //TODO make this better, it only handles modes right now, and very | 1117 | // TODO better block handling |
1088 | //simply at that | ||
1089 | if (strncmp(argv[0], "}", 1) == 0) { | 1118 | if (strncmp(argv[0], "}", 1) == 0) { |
1090 | config->current_mode = config->modes->items[0]; | 1119 | config->current_mode = config->modes->items[0]; |
1091 | res = true; | 1120 | status = CMD_SUCCESS; |
1092 | goto cleanup; | 1121 | goto cleanup; |
1093 | } | 1122 | } |
1094 | if ((handler = find_handler(argv[0]))) { | 1123 | if ((handler = find_handler(argv[0]))) { |
1095 | int i = 1, e = argc; | 1124 | // Dont replace first argument in cmd_set |
1096 | // dont var replace first argument | 1125 | int i = handler->handle == cmd_set ? 2 : 1; |
1097 | if (handler->handle == cmd_set) { | 1126 | int e = argc; |
1098 | i = 2; | ||
1099 | } | ||
1100 | for (; i < e; ++i) { | 1127 | for (; i < e; ++i) { |
1101 | argv[i] = do_var_replacement(argv[i]); | 1128 | argv[i] = do_var_replacement(argv[i]); |
1102 | } | 1129 | } |
1103 | if (handler->config_type == CMD_KEYBIND) { | 1130 | status = handler->handle(argc - 1, argv + 1); |
1104 | sway_log(L_ERROR, "Invalid command during config `%s'", exec); | 1131 | if (status == CMD_FAILURE) { |
1105 | } else if (handler->config_type == CMD_COMPOSITOR_READY && !config->active) { | 1132 | sway_log(L_ERROR, "Config load failed for line `%s'", exec); |
1133 | } else if (status == CMD_DEFER) { | ||
1106 | sway_log(L_DEBUG, "Defferring command `%s'", exec); | 1134 | sway_log(L_DEBUG, "Defferring command `%s'", exec); |
1107 | char *cmd = join_args(argv, argc); | 1135 | list_add(config->cmd_queue, strdup(exec)); |
1108 | list_add(config->cmd_queue, cmd); | 1136 | status = CMD_SUCCESS; |
1109 | res = true; | ||
1110 | } else if (!handler->handle(argc-1, argv+1)) { | ||
1111 | sway_log(L_DEBUG, "Config load failed for line `%s'", exec); | ||
1112 | } else { | ||
1113 | res = true; | ||
1114 | } | 1137 | } |
1115 | } else { | 1138 | } else { |
1116 | sway_log(L_ERROR, "Unknown command `%s'", exec); | 1139 | sway_log(L_ERROR, "Unknown command `%s'", exec); |
1117 | } | 1140 | } |
1118 | cleanup: | 1141 | cleanup: |
1119 | free_argv(argc, argv); | 1142 | free_argv(argc, argv); |
1120 | return res; | 1143 | return status; |
1121 | } | 1144 | } |
diff --git a/sway/config.c b/sway/config.c index 11394a7c..23d6ac0d 100644 --- a/sway/config.c +++ b/sway/config.c | |||
@@ -102,6 +102,7 @@ static void config_defaults(struct sway_config *config) { | |||
102 | config->active = false; | 102 | config->active = false; |
103 | config->failed = false; | 103 | config->failed = false; |
104 | config->auto_back_and_forth = false; | 104 | config->auto_back_and_forth = false; |
105 | config->reading = false; | ||
105 | 106 | ||
106 | config->gaps_inner = 0; | 107 | config->gaps_inner = 0; |
107 | config->gaps_outer = 0; | 108 | config->gaps_outer = 0; |
@@ -217,6 +218,7 @@ bool read_config(FILE *file, bool is_active) { | |||
217 | config = malloc(sizeof(struct sway_config)); | 218 | config = malloc(sizeof(struct sway_config)); |
218 | 219 | ||
219 | config_defaults(config); | 220 | config_defaults(config); |
221 | config->reading = true; | ||
220 | if (is_active) { | 222 | if (is_active) { |
221 | sway_log(L_DEBUG, "Performing configuration file reload"); | 223 | sway_log(L_DEBUG, "Performing configuration file reload"); |
222 | config->reloading = true; | 224 | config->reloading = true; |
@@ -228,7 +230,8 @@ bool read_config(FILE *file, bool is_active) { | |||
228 | while (!feof(file)) { | 230 | while (!feof(file)) { |
229 | line = read_line(file); | 231 | line = read_line(file); |
230 | line = strip_comments(line); | 232 | line = strip_comments(line); |
231 | if (!config_command(line)) { | 233 | if (config_command(line) == CMD_FAILURE) { |
234 | sway_log(L_ERROR, "Error on line '%s'", line); | ||
232 | success = false; | 235 | success = false; |
233 | } | 236 | } |
234 | free(line); | 237 | free(line); |
@@ -242,6 +245,7 @@ bool read_config(FILE *file, bool is_active) { | |||
242 | free_config(old_config); | 245 | free_config(old_config); |
243 | } | 246 | } |
244 | 247 | ||
248 | config->reading = false; | ||
245 | return success; | 249 | return success; |
246 | } | 250 | } |
247 | 251 | ||
diff --git a/sway/handlers.c b/sway/handlers.c index c0472817..096df53c 100644 --- a/sway/handlers.c +++ b/sway/handlers.c | |||
@@ -478,12 +478,12 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w | |||
478 | static void handle_wlc_ready(void) { | 478 | static void handle_wlc_ready(void) { |
479 | sway_log(L_DEBUG, "Compositor is ready, executing cmds in queue"); | 479 | sway_log(L_DEBUG, "Compositor is ready, executing cmds in queue"); |
480 | // Execute commands until there are none left | 480 | // Execute commands until there are none left |
481 | config->active = true; | ||
481 | while (config->cmd_queue->length) { | 482 | while (config->cmd_queue->length) { |
482 | handle_command(config->cmd_queue->items[0]); | 483 | handle_command(config->cmd_queue->items[0]); |
483 | free(config->cmd_queue->items[0]); | 484 | free(config->cmd_queue->items[0]); |
484 | list_del(config->cmd_queue, 0); | 485 | list_del(config->cmd_queue, 0); |
485 | } | 486 | } |
486 | config->active = true; | ||
487 | } | 487 | } |
488 | 488 | ||
489 | struct wlc_interface interface = { | 489 | struct wlc_interface interface = { |
diff --git a/sway/stringop.c b/sway/stringop.c index 270e673a..191e40c8 100644 --- a/sway/stringop.c +++ b/sway/stringop.c | |||
@@ -145,7 +145,7 @@ char **split_args(const char *start, int *argc) { | |||
145 | } | 145 | } |
146 | 146 | ||
147 | void free_argv(int argc, char **argv) { | 147 | void free_argv(int argc, char **argv) { |
148 | while (--argc) { | 148 | while (--argc > 0) { |
149 | free(argv[argc]); | 149 | free(argv[argc]); |
150 | } | 150 | } |
151 | free(argv); | 151 | free(argv); |
diff --git a/sway/workspace.c b/sway/workspace.c index 7eb422c4..658f79bc 100644 --- a/sway/workspace.c +++ b/sway/workspace.c | |||
@@ -76,7 +76,26 @@ char *workspace_next_name(void) { | |||
76 | } | 76 | } |
77 | 77 | ||
78 | swayc_t *workspace_create(const char* name) { | 78 | swayc_t *workspace_create(const char* name) { |
79 | swayc_t *parent = get_focused_container(&root_container); | 79 | swayc_t *parent; |
80 | // Search for workspace<->output pair | ||
81 | int i, e = config->workspace_outputs->length; | ||
82 | for (i = 0; i < e; ++i) { | ||
83 | struct workspace_output *wso = config->workspace_outputs->items[i]; | ||
84 | if (strcasecmp(wso->workspace, name) == 0) | ||
85 | { | ||
86 | // Find output to use if it exists | ||
87 | e = root_container.children->length; | ||
88 | for (i = 0; i < e; ++i) { | ||
89 | parent = root_container.children->items[i]; | ||
90 | if (strcmp(parent->name, wso->output) == 0) { | ||
91 | return new_workspace(parent, name); | ||
92 | } | ||
93 | } | ||
94 | break; | ||
95 | } | ||
96 | } | ||
97 | // Otherwise create a new one | ||
98 | parent = get_focused_container(&root_container); | ||
80 | parent = swayc_parent_by_type(parent, C_OUTPUT); | 99 | parent = swayc_parent_by_type(parent, C_OUTPUT); |
81 | return new_workspace(parent, name); | 100 | return new_workspace(parent, name); |
82 | } | 101 | } |