diff options
-rw-r--r-- | include/log.h | 2 | ||||
-rw-r--r-- | include/output.h | 10 | ||||
-rw-r--r-- | sway/commands.c | 45 | ||||
-rw-r--r-- | sway/focus.c | 2 | ||||
-rw-r--r-- | sway/handlers.c | 61 | ||||
-rw-r--r-- | sway/layout.c | 2 | ||||
-rw-r--r-- | sway/log.c | 27 | ||||
-rw-r--r-- | sway/output.c | 91 |
8 files changed, 171 insertions, 69 deletions
diff --git a/include/log.h b/include/log.h index f8deaf26..806725a6 100644 --- a/include/log.h +++ b/include/log.h | |||
@@ -23,4 +23,6 @@ bool _sway_assert(bool condition, const char* format, ...) __attribute__((format | |||
23 | void error_handler(int sig); | 23 | void error_handler(int sig); |
24 | 24 | ||
25 | void layout_log(const swayc_t *c, int depth); | 25 | void layout_log(const swayc_t *c, int depth); |
26 | const char *swayc_type_string(enum swayc_types type); | ||
27 | void swayc_log(log_importance_t verbosity, swayc_t *cont, const char* format, ...) __attribute__((format(printf,3,4))); | ||
26 | #endif | 28 | #endif |
diff --git a/include/output.h b/include/output.h new file mode 100644 index 00000000..10ff0596 --- /dev/null +++ b/include/output.h | |||
@@ -0,0 +1,10 @@ | |||
1 | #ifndef _SWAY_OUTPUT_H | ||
2 | #define _SWAY_OUTPUT_H | ||
3 | |||
4 | #include "container.h" | ||
5 | #include "focus.h" | ||
6 | |||
7 | swayc_t *output_by_name(const char* name); | ||
8 | swayc_t *swayc_adjacent_output(swayc_t *output, enum movement_direction dir); | ||
9 | |||
10 | #endif | ||
diff --git a/sway/commands.c b/sway/commands.c index 8c45dabe..0102fc5a 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -494,6 +494,8 @@ static struct cmd_results *cmd_move(int argc, char **argv) { | |||
494 | if ((error = checkarg(argc, "move", EXPECTED_AT_LEAST, 1))) { | 494 | if ((error = checkarg(argc, "move", EXPECTED_AT_LEAST, 1))) { |
495 | return error; | 495 | return error; |
496 | } | 496 | } |
497 | const char* expected_syntax = "Expected 'move <left|right|up|down>' or " | ||
498 | "'move <container|window> to workspace <name>'"; | ||
497 | swayc_t *view = get_focused_container(&root_container); | 499 | swayc_t *view = get_focused_container(&root_container); |
498 | 500 | ||
499 | if (strcasecmp(argv[0], "left") == 0) { | 501 | if (strcasecmp(argv[0], "left") == 0) { |
@@ -505,31 +507,33 @@ static struct cmd_results *cmd_move(int argc, char **argv) { | |||
505 | } else if (strcasecmp(argv[0], "down") == 0) { | 507 | } else if (strcasecmp(argv[0], "down") == 0) { |
506 | move_container(view, MOVE_DOWN); | 508 | move_container(view, MOVE_DOWN); |
507 | } else if (strcasecmp(argv[0], "container") == 0 || strcasecmp(argv[0], "window") == 0) { | 509 | } else if (strcasecmp(argv[0], "container") == 0 || strcasecmp(argv[0], "window") == 0) { |
508 | // "move container to workspace x" | 510 | // "move container ... |
509 | if ((error = checkarg(argc, "move container/window", EXPECTED_EQUAL_TO, 4))) { | 511 | if ((error = checkarg(argc, "move container/window", EXPECTED_AT_LEAST, 4))) { |
510 | return error; | 512 | return error; |
511 | } else if ( strcasecmp(argv[1], "to") != 0 || strcasecmp(argv[2], "workspace") != 0) { | 513 | } else if ( strcasecmp(argv[1], "to") == 0 && strcasecmp(argv[2], "workspace") == 0) { |
512 | return cmd_results_new(CMD_INVALID, "move", "Expected 'move %s to workspace <name>'", argv[0]); | 514 | // move container to workspace x |
513 | } | 515 | if (view->type != C_CONTAINER && view->type != C_VIEW) { |
514 | 516 | return cmd_results_new(CMD_FAILURE, "move", "Can only move containers and views."); | |
515 | if (view->type != C_CONTAINER && view->type != C_VIEW) { | 517 | } |
516 | return cmd_results_new(CMD_FAILURE, "move", "Can only move containers and views."); | ||
517 | } | ||
518 | 518 | ||
519 | const char *ws_name = argv[3]; | 519 | const char *ws_name = argv[3]; |
520 | if (argc == 5) { | 520 | if (argc == 5) { |
521 | // move "container to workspace number x" | 521 | // move "container to workspace number x" |
522 | ws_name = argv[4]; | 522 | ws_name = argv[4]; |
523 | } | 523 | } |
524 | 524 | ||
525 | swayc_t *ws = workspace_by_name(ws_name); | 525 | swayc_t *ws = workspace_by_name(ws_name); |
526 | if (ws == NULL) { | 526 | if (ws == NULL) { |
527 | ws = workspace_create(ws_name); | 527 | ws = workspace_create(ws_name); |
528 | } | ||
529 | move_container_to(view, get_focused_container(ws)); | ||
530 | } else { | ||
531 | return cmd_results_new(CMD_INVALID, "move", expected_syntax); | ||
528 | } | 532 | } |
529 | move_container_to(view, get_focused_container(ws)); | ||
530 | } else if (strcasecmp(argv[0], "scratchpad") == 0) { | 533 | } else if (strcasecmp(argv[0], "scratchpad") == 0) { |
534 | // move scratchpad ... | ||
531 | if (view->type != C_CONTAINER && view->type != C_VIEW) { | 535 | if (view->type != C_CONTAINER && view->type != C_VIEW) { |
532 | return cmd_results_new(CMD_FAILURE, "move", "Can only move containers and views."); | 536 | return cmd_results_new(CMD_FAILURE, "move scratchpad", "Can only move containers and views."); |
533 | } | 537 | } |
534 | swayc_t *view = get_focused_container(&root_container); | 538 | swayc_t *view = get_focused_container(&root_container); |
535 | int i; | 539 | int i; |
@@ -554,8 +558,7 @@ static struct cmd_results *cmd_move(int argc, char **argv) { | |||
554 | } | 558 | } |
555 | set_focused_container(focused); | 559 | set_focused_container(focused); |
556 | } else { | 560 | } else { |
557 | return cmd_results_new(CMD_INVALID, "move", | 561 | return cmd_results_new(CMD_INVALID, "move", expected_syntax); |
558 | "Expected 'move <left|right|up|down>' or 'move <container|window> to workspace <name>'"); | ||
559 | } | 562 | } |
560 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 563 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
561 | } | 564 | } |
diff --git a/sway/focus.c b/sway/focus.c index 0c1f8c9e..1aa7579b 100644 --- a/sway/focus.c +++ b/sway/focus.c | |||
@@ -76,7 +76,7 @@ bool set_focused_container(swayc_t *c) { | |||
76 | if (locked_container_focus || !c) { | 76 | if (locked_container_focus || !c) { |
77 | return false; | 77 | return false; |
78 | } | 78 | } |
79 | sway_log(L_DEBUG, "Setting focus to %p:%ld", c, c->handle); | 79 | swayc_log(L_DEBUG, c, "Setting focus to %p:%ld", c, c->handle); |
80 | 80 | ||
81 | // Get workspace for c, get that workspaces current focused container. | 81 | // Get workspace for c, get that workspaces current focused container. |
82 | swayc_t *workspace = swayc_active_workspace_for(c); | 82 | swayc_t *workspace = swayc_active_workspace_for(c); |
diff --git a/sway/handlers.c b/sway/handlers.c index c0b775db..c777e692 100644 --- a/sway/handlers.c +++ b/sway/handlers.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include "stringop.h" | 13 | #include "stringop.h" |
14 | #include "workspace.h" | 14 | #include "workspace.h" |
15 | #include "container.h" | 15 | #include "container.h" |
16 | #include "output.h" | ||
16 | #include "focus.h" | 17 | #include "focus.h" |
17 | #include "input_state.h" | 18 | #include "input_state.h" |
18 | #include "resize.h" | 19 | #include "resize.h" |
@@ -364,62 +365,30 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct | |||
364 | // don't do the switch if the pointer is in a mode. | 365 | // don't do the switch if the pointer is in a mode. |
365 | if (config->seamless_mouse && !pointer_state.mode && | 366 | if (config->seamless_mouse && !pointer_state.mode && |
366 | !pointer_state.left.held && !pointer_state.right.held && !pointer_state.scroll.held) { | 367 | !pointer_state.left.held && !pointer_state.right.held && !pointer_state.scroll.held) { |
367 | swayc_t *output = swayc_active_output(); | ||
368 | 368 | ||
369 | // TODO: This implementation is naïve: We assume all outputs are | 369 | swayc_t *output = swayc_active_output(), *adjacent = NULL; |
370 | // perfectly aligned (ie. only a single output per edge which covers | ||
371 | // the whole edge). | ||
372 | if (origin->x == 0) { // Left edge | 370 | if (origin->x == 0) { // Left edge |
373 | for(int i = 0; i < root_container.children->length; ++i) { | 371 | if ((adjacent = swayc_adjacent_output(output, MOVE_LEFT))) { |
374 | swayc_t *c = root_container.children->items[i]; | 372 | if (workspace_switch(adjacent)) { |
375 | if (c == output || c->type != C_OUTPUT) { | 373 | new_origin.x = adjacent->width; |
376 | continue; | ||
377 | } | ||
378 | if (c->y == output->y && c->x + c->width == output->x) { | ||
379 | sway_log(L_DEBUG, "%s is right of %s", output->name, c->name); | ||
380 | if (workspace_switch(c)) { | ||
381 | new_origin.x = c->width; | ||
382 | } | ||
383 | } | 374 | } |
384 | } | 375 | } |
385 | } else if ((double)origin->x == output->width) { // Right edge | 376 | } else if ((double)origin->x == output->width) { // Right edge |
386 | for(int i = 0; i < root_container.children->length; ++i) { | 377 | if ((adjacent = swayc_adjacent_output(output, MOVE_RIGHT))) { |
387 | swayc_t *c = root_container.children->items[i]; | 378 | if (workspace_switch(adjacent)) { |
388 | if (c == output || c->type != C_OUTPUT) { | 379 | new_origin.x = 0; |
389 | continue; | ||
390 | } | ||
391 | if (c->y == output->y && output->x + output->width == c->x) { | ||
392 | sway_log(L_DEBUG, "%s is left of %s", output->name, c->name); | ||
393 | if (workspace_switch(c)) { | ||
394 | new_origin.x = 0; | ||
395 | } | ||
396 | } | 380 | } |
397 | } | 381 | } |
398 | } | 382 | } else if (origin->y == 0) { // Top edge |
399 | if (origin->y == 0) { // Top edge | 383 | if ((adjacent = swayc_adjacent_output(output, MOVE_UP))) { |
400 | for(int i = 0; i < root_container.children->length; ++i) { | 384 | if (workspace_switch(adjacent)) { |
401 | swayc_t *c = root_container.children->items[i]; | 385 | new_origin.y = adjacent->height; |
402 | if (c == output || c->type != C_OUTPUT) { | ||
403 | continue; | ||
404 | } | ||
405 | if (output->x == c->x && c->y + c->height == output->y) { | ||
406 | sway_log(L_DEBUG, "%s is below %s", output->name, c->name); | ||
407 | if (workspace_switch(c)) { | ||
408 | new_origin.y = c->height; | ||
409 | } | ||
410 | } | 386 | } |
411 | } | 387 | } |
412 | } else if ((double)origin->y == output->height) { // Bottom edge | 388 | } else if ((double)origin->y == output->height) { // Bottom edge |
413 | for(int i = 0; i < root_container.children->length; ++i) { | 389 | if ((adjacent = swayc_adjacent_output(output, MOVE_DOWN))) { |
414 | swayc_t *c = root_container.children->items[i]; | 390 | if (workspace_switch(adjacent)) { |
415 | if (c == output || c->type != C_OUTPUT) { | 391 | new_origin.y = 0; |
416 | continue; | ||
417 | } | ||
418 | if (output->x == c->x && output->y + output->height == c->y) { | ||
419 | sway_log(L_DEBUG, "%s is above %s", output->name, c->name); | ||
420 | if (workspace_switch(c)) { | ||
421 | new_origin.y = 0; | ||
422 | } | ||
423 | } | 392 | } |
424 | } | 393 | } |
425 | } | 394 | } |
diff --git a/sway/layout.c b/sway/layout.c index 3cd873d6..6388a9b2 100644 --- a/sway/layout.c +++ b/sway/layout.c | |||
@@ -349,7 +349,7 @@ void update_geometry(swayc_t *container) { | |||
349 | static void arrange_windows_r(swayc_t *container, double width, double height) { | 349 | static void arrange_windows_r(swayc_t *container, double width, double height) { |
350 | int i; | 350 | int i; |
351 | if (width == -1 || height == -1) { | 351 | if (width == -1 || height == -1) { |
352 | sway_log(L_DEBUG, "Arranging layout for %p", container); | 352 | swayc_log(L_DEBUG, container, "Arranging layout for %p", container); |
353 | width = container->width; | 353 | width = container->width; |
354 | height = container->height; | 354 | height = container->height; |
355 | } | 355 | } |
@@ -187,4 +187,31 @@ void layout_log(const swayc_t *c, int depth) { | |||
187 | } | 187 | } |
188 | } | 188 | } |
189 | } | 189 | } |
190 | |||
191 | const char *swayc_type_string(enum swayc_types type) { | ||
192 | return type == C_ROOT ? "ROOT" : | ||
193 | type == C_OUTPUT ? "OUTPUT" : | ||
194 | type == C_WORKSPACE ? "WORKSPACE" : | ||
195 | type == C_CONTAINER ? "CONTAINER" : | ||
196 | type == C_VIEW ? "VIEW" : | ||
197 | "UNKNOWN"; | ||
198 | } | ||
199 | |||
200 | // Like sway_log, but also appends some info about given container to log output. | ||
201 | void swayc_log(log_importance_t verbosity, swayc_t *cont, const char* format, ...) { | ||
202 | sway_assert(cont, "swayc_log: no container ..."); | ||
203 | va_list args; | ||
204 | va_start(args, format); | ||
205 | char *txt = malloc(128); | ||
206 | vsprintf(txt, format, args); | ||
207 | va_end(args); | ||
208 | |||
209 | char *debug_txt = malloc(32); | ||
210 | snprintf(debug_txt, 32, "%s '%s'", swayc_type_string(cont->type), cont->name); | ||
211 | |||
212 | sway_log(verbosity, "%s (%s)", txt, debug_txt); | ||
213 | free(txt); | ||
214 | free(debug_txt); | ||
215 | } | ||
216 | |||
190 | /* XXX:DEBUG:XXX */ | 217 | /* XXX:DEBUG:XXX */ |
diff --git a/sway/output.c b/sway/output.c new file mode 100644 index 00000000..5044b7aa --- /dev/null +++ b/sway/output.c | |||
@@ -0,0 +1,91 @@ | |||
1 | #include <strings.h> | ||
2 | #include "output.h" | ||
3 | #include "log.h" | ||
4 | |||
5 | swayc_t *output_by_name(const char* name) { | ||
6 | if (strcasecmp(name, "left") == 0) { | ||
7 | return swayc_adjacent_output(NULL, MOVE_LEFT); | ||
8 | } else if (strcasecmp(name, "right") == 0) { | ||
9 | return swayc_adjacent_output(NULL, MOVE_RIGHT); | ||
10 | } else if (strcasecmp(name, "up") == 0) { | ||
11 | return swayc_adjacent_output(NULL, MOVE_UP); | ||
12 | } else if (strcasecmp(name, "down") == 0) { | ||
13 | return swayc_adjacent_output(NULL, MOVE_DOWN); | ||
14 | } else { | ||
15 | for(int i = 0; i < root_container.children->length; ++i) { | ||
16 | swayc_t *c = root_container.children->items[i]; | ||
17 | if (c->type == C_OUTPUT && strcasecmp(c->name, name) == 0) { | ||
18 | return c; | ||
19 | } | ||
20 | } | ||
21 | } | ||
22 | return NULL; | ||
23 | } | ||
24 | |||
25 | swayc_t *swayc_adjacent_output(swayc_t *output, enum movement_direction dir) { | ||
26 | // TODO: This implementation is naïve: We assume all outputs are | ||
27 | // perfectly aligned (ie. only a single output per edge which covers | ||
28 | // the whole edge). | ||
29 | if (!output) { | ||
30 | output = swayc_active_output(); | ||
31 | } | ||
32 | swayc_t *adjacent = NULL; | ||
33 | switch(dir) { | ||
34 | case MOVE_LEFT: | ||
35 | for(int i = 0; i < root_container.children->length; ++i) { | ||
36 | swayc_t *c = root_container.children->items[i]; | ||
37 | if (c == output || c->type != C_OUTPUT) { | ||
38 | continue; | ||
39 | } | ||
40 | if (c->y == output->y && c->x + c->width == output->x) { | ||
41 | sway_log(L_DEBUG, "%s is left of current output %s", c->name, output->name); | ||
42 | adjacent = c; | ||
43 | break; | ||
44 | } | ||
45 | } | ||
46 | break; | ||
47 | case MOVE_RIGHT: | ||
48 | for(int i = 0; i < root_container.children->length; ++i) { | ||
49 | swayc_t *c = root_container.children->items[i]; | ||
50 | if (c == output || c->type != C_OUTPUT) { | ||
51 | continue; | ||
52 | } | ||
53 | if (c->y == output->y && output->x + output->width == c->x) { | ||
54 | sway_log(L_DEBUG, "%s is right of current output %s", c->name, output->name); | ||
55 | adjacent = c; | ||
56 | break; | ||
57 | } | ||
58 | } | ||
59 | break; | ||
60 | case MOVE_UP: | ||
61 | for(int i = 0; i < root_container.children->length; ++i) { | ||
62 | swayc_t *c = root_container.children->items[i]; | ||
63 | if (c == output || c->type != C_OUTPUT) { | ||
64 | continue; | ||
65 | } | ||
66 | if (output->x == c->x && c->y + c->height == output->y) { | ||
67 | sway_log(L_DEBUG, "%s is above current output %s", c->name, output->name); | ||
68 | adjacent = c; | ||
69 | break; | ||
70 | } | ||
71 | } | ||
72 | break; | ||
73 | case MOVE_DOWN: | ||
74 | for(int i = 0; i < root_container.children->length; ++i) { | ||
75 | swayc_t *c = root_container.children->items[i]; | ||
76 | if (c == output || c->type != C_OUTPUT) { | ||
77 | continue; | ||
78 | } | ||
79 | if (output->x == c->x && output->y + output->height == c->y) { | ||
80 | sway_log(L_DEBUG, "%s is below current output %s", c->name, output->name); | ||
81 | adjacent = c; | ||
82 | break; | ||
83 | } | ||
84 | } | ||
85 | break; | ||
86 | default: | ||
87 | sway_abort("Function called with invalid argument."); | ||
88 | break; | ||
89 | } | ||
90 | return adjacent; | ||
91 | } | ||