From 1d3901b66f097b314f0e924a55a09fb681b00c11 Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Sun, 25 Oct 2015 01:20:00 +0200 Subject: sway/output: Create, move code from handlers.c here. --- include/output.h | 10 ++++++ sway/handlers.c | 61 +++++++++--------------------------- sway/output.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 46 deletions(-) create mode 100644 include/output.h create mode 100644 sway/output.c 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 @@ +#ifndef _SWAY_OUTPUT_H +#define _SWAY_OUTPUT_H + +#include "container.h" +#include "focus.h" + +swayc_t *output_by_name(const char* name); +swayc_t *swayc_adjacent_output(swayc_t *output, enum movement_direction dir); + +#endif 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 @@ #include "stringop.h" #include "workspace.h" #include "container.h" +#include "output.h" #include "focus.h" #include "input_state.h" #include "resize.h" @@ -364,62 +365,30 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct // don't do the switch if the pointer is in a mode. if (config->seamless_mouse && !pointer_state.mode && !pointer_state.left.held && !pointer_state.right.held && !pointer_state.scroll.held) { - swayc_t *output = swayc_active_output(); - // TODO: This implementation is naïve: We assume all outputs are - // perfectly aligned (ie. only a single output per edge which covers - // the whole edge). + swayc_t *output = swayc_active_output(), *adjacent = NULL; if (origin->x == 0) { // Left edge - for(int i = 0; i < root_container.children->length; ++i) { - swayc_t *c = root_container.children->items[i]; - if (c == output || c->type != C_OUTPUT) { - continue; - } - if (c->y == output->y && c->x + c->width == output->x) { - sway_log(L_DEBUG, "%s is right of %s", output->name, c->name); - if (workspace_switch(c)) { - new_origin.x = c->width; - } + if ((adjacent = swayc_adjacent_output(output, MOVE_LEFT))) { + if (workspace_switch(adjacent)) { + new_origin.x = adjacent->width; } } } else if ((double)origin->x == output->width) { // Right edge - for(int i = 0; i < root_container.children->length; ++i) { - swayc_t *c = root_container.children->items[i]; - if (c == output || c->type != C_OUTPUT) { - continue; - } - if (c->y == output->y && output->x + output->width == c->x) { - sway_log(L_DEBUG, "%s is left of %s", output->name, c->name); - if (workspace_switch(c)) { - new_origin.x = 0; - } + if ((adjacent = swayc_adjacent_output(output, MOVE_RIGHT))) { + if (workspace_switch(adjacent)) { + new_origin.x = 0; } } - } - if (origin->y == 0) { // Top edge - for(int i = 0; i < root_container.children->length; ++i) { - swayc_t *c = root_container.children->items[i]; - if (c == output || c->type != C_OUTPUT) { - continue; - } - if (output->x == c->x && c->y + c->height == output->y) { - sway_log(L_DEBUG, "%s is below %s", output->name, c->name); - if (workspace_switch(c)) { - new_origin.y = c->height; - } + } else if (origin->y == 0) { // Top edge + if ((adjacent = swayc_adjacent_output(output, MOVE_UP))) { + if (workspace_switch(adjacent)) { + new_origin.y = adjacent->height; } } } else if ((double)origin->y == output->height) { // Bottom edge - for(int i = 0; i < root_container.children->length; ++i) { - swayc_t *c = root_container.children->items[i]; - if (c == output || c->type != C_OUTPUT) { - continue; - } - if (output->x == c->x && output->y + output->height == c->y) { - sway_log(L_DEBUG, "%s is above %s", output->name, c->name); - if (workspace_switch(c)) { - new_origin.y = 0; - } + if ((adjacent = swayc_adjacent_output(output, MOVE_DOWN))) { + if (workspace_switch(adjacent)) { + new_origin.y = 0; } } } diff --git a/sway/output.c b/sway/output.c new file mode 100644 index 00000000..39c933f8 --- /dev/null +++ b/sway/output.c @@ -0,0 +1,95 @@ +#include +#include "output.h" +#include "log.h" + +swayc_t *output_by_name(const char* name) { + if (strcasecmp(name, "left") == 0) { + return swayc_adjacent_output(NULL, MOVE_LEFT); + } + else if (strcasecmp(name, "right") == 0) { + return swayc_adjacent_output(NULL, MOVE_RIGHT); + } + else if (strcasecmp(name, "up") == 0) { + return swayc_adjacent_output(NULL, MOVE_UP); + } + else if (strcasecmp(name, "down") == 0) { + return swayc_adjacent_output(NULL, MOVE_DOWN); + } + else { + for(int i = 0; i < root_container.children->length; ++i) { + swayc_t *c = root_container.children->items[i]; + if (c->type == C_OUTPUT && strcasecmp(c->name, name) == 0) { + return c; + } + } + } + return NULL; +} + +swayc_t *swayc_adjacent_output(swayc_t *output, enum movement_direction dir) { + // TODO: This implementation is naïve: We assume all outputs are + // perfectly aligned (ie. only a single output per edge which covers + // the whole edge). + if (!output) { + output = swayc_active_output(); + } + swayc_t *adjacent = NULL; + switch(dir) { + case MOVE_LEFT: + for(int i = 0; i < root_container.children->length; ++i) { + swayc_t *c = root_container.children->items[i]; + if (c == output || c->type != C_OUTPUT) { + continue; + } + if (c->y == output->y && c->x + c->width == output->x) { + sway_log(L_DEBUG, "%s is left of current output %s", c->name, output->name); + adjacent = c; + break; + } + } + break; + case MOVE_RIGHT: + for(int i = 0; i < root_container.children->length; ++i) { + swayc_t *c = root_container.children->items[i]; + if (c == output || c->type != C_OUTPUT) { + continue; + } + if (c->y == output->y && output->x + output->width == c->x) { + sway_log(L_DEBUG, "%s is right of current output %s", c->name, output->name); + adjacent = c; + break; + } + } + break; + case MOVE_UP: + for(int i = 0; i < root_container.children->length; ++i) { + swayc_t *c = root_container.children->items[i]; + if (c == output || c->type != C_OUTPUT) { + continue; + } + if (output->x == c->x && c->y + c->height == output->y) { + sway_log(L_DEBUG, "%s is above current output %s", c->name, output->name); + adjacent = c; + break; + } + } + break; + case MOVE_DOWN: + for(int i = 0; i < root_container.children->length; ++i) { + swayc_t *c = root_container.children->items[i]; + if (c == output || c->type != C_OUTPUT) { + continue; + } + if (output->x == c->x && output->y + output->height == c->y) { + sway_log(L_DEBUG, "%s is below current output %s", c->name, output->name); + adjacent = c; + break; + } + } + break; + default: + sway_abort("Function called with invalid argument."); + break; + } + return adjacent; +} -- cgit v1.2.3 From 4f9c90d0c178b89889d0f060329a3c8d2706f160 Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Sun, 25 Oct 2015 00:34:57 +0200 Subject: log: Add swayc_log, use at a few key places. swayc_log works just like sway_log, but appends type and name from given container to the log output. --- include/log.h | 2 ++ sway/focus.c | 2 +- sway/layout.c | 2 +- sway/log.c | 27 +++++++++++++++++++++++++++ 4 files changed, 31 insertions(+), 2 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 void error_handler(int sig); void layout_log(const swayc_t *c, int depth); +const char *swayc_type_string(enum swayc_types type); +void swayc_log(log_importance_t verbosity, swayc_t *cont, const char* format, ...) __attribute__((format(printf,3,4))); #endif 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) { if (locked_container_focus || !c) { return false; } - sway_log(L_DEBUG, "Setting focus to %p:%ld", c, c->handle); + swayc_log(L_DEBUG, c, "Setting focus to %p:%ld", c, c->handle); // Get workspace for c, get that workspaces current focused container. swayc_t *workspace = swayc_active_workspace_for(c); 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) { static void arrange_windows_r(swayc_t *container, double width, double height) { int i; if (width == -1 || height == -1) { - sway_log(L_DEBUG, "Arranging layout for %p", container); + swayc_log(L_DEBUG, container, "Arranging layout for %p", container); width = container->width; height = container->height; } diff --git a/sway/log.c b/sway/log.c index a206d971..62be73e5 100644 --- a/sway/log.c +++ b/sway/log.c @@ -187,4 +187,31 @@ void layout_log(const swayc_t *c, int depth) { } } } + +const char *swayc_type_string(enum swayc_types type) { + return type == C_ROOT ? "ROOT" : + type == C_OUTPUT ? "OUTPUT" : + type == C_WORKSPACE ? "WORKSPACE" : + type == C_CONTAINER ? "CONTAINER" : + type == C_VIEW ? "VIEW" : + "UNKNOWN"; +} + +// Like sway_log, but also appends some info about given container to log output. +void swayc_log(log_importance_t verbosity, swayc_t *cont, const char* format, ...) { + sway_assert(cont, "swayc_log: no container ..."); + va_list args; + va_start(args, format); + char *txt = malloc(128); + vsprintf(txt, format, args); + va_end(args); + + char *debug_txt = malloc(32); + snprintf(debug_txt, 32, "%s '%s'", swayc_type_string(cont->type), cont->name); + + sway_log(verbosity, "%s (%s)", txt, debug_txt); + free(txt); + free(debug_txt); +} + /* XXX:DEBUG:XXX */ -- cgit v1.2.3 From 0f7bda60e42f29ff20ade3e2f74aa0943d10b1a4 Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Sat, 24 Oct 2015 16:55:21 +0200 Subject: commands: cmd_move: Fix "move container to workspace _number_ n" This is an undocumented feature (the word "number" is just ignored anyway), but it exists to be compatible with i3 config syntax. Plus some code cleanup at the same time. --- sway/commands.c | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) 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) { if ((error = checkarg(argc, "move", EXPECTED_AT_LEAST, 1))) { return error; } + const char* expected_syntax = "Expected 'move ' or " + "'move to workspace '"; swayc_t *view = get_focused_container(&root_container); if (strcasecmp(argv[0], "left") == 0) { @@ -505,31 +507,33 @@ static struct cmd_results *cmd_move(int argc, char **argv) { } else if (strcasecmp(argv[0], "down") == 0) { move_container(view, MOVE_DOWN); } else if (strcasecmp(argv[0], "container") == 0 || strcasecmp(argv[0], "window") == 0) { - // "move container to workspace x" - if ((error = checkarg(argc, "move container/window", EXPECTED_EQUAL_TO, 4))) { + // "move container ... + if ((error = checkarg(argc, "move container/window", EXPECTED_AT_LEAST, 4))) { return error; - } else if ( strcasecmp(argv[1], "to") != 0 || strcasecmp(argv[2], "workspace") != 0) { - return cmd_results_new(CMD_INVALID, "move", "Expected 'move %s to workspace '", argv[0]); - } - - if (view->type != C_CONTAINER && view->type != C_VIEW) { - return cmd_results_new(CMD_FAILURE, "move", "Can only move containers and views."); - } + } else if ( strcasecmp(argv[1], "to") == 0 && strcasecmp(argv[2], "workspace") == 0) { + // move container to workspace x + if (view->type != C_CONTAINER && view->type != C_VIEW) { + return cmd_results_new(CMD_FAILURE, "move", "Can only move containers and views."); + } - const char *ws_name = argv[3]; - if (argc == 5) { - // move "container to workspace number x" - ws_name = argv[4]; - } + const char *ws_name = argv[3]; + if (argc == 5) { + // move "container to workspace number x" + ws_name = argv[4]; + } - swayc_t *ws = workspace_by_name(ws_name); - if (ws == NULL) { - ws = workspace_create(ws_name); + swayc_t *ws = workspace_by_name(ws_name); + if (ws == NULL) { + ws = workspace_create(ws_name); + } + move_container_to(view, get_focused_container(ws)); + } else { + return cmd_results_new(CMD_INVALID, "move", expected_syntax); } - move_container_to(view, get_focused_container(ws)); } else if (strcasecmp(argv[0], "scratchpad") == 0) { + // move scratchpad ... if (view->type != C_CONTAINER && view->type != C_VIEW) { - return cmd_results_new(CMD_FAILURE, "move", "Can only move containers and views."); + return cmd_results_new(CMD_FAILURE, "move scratchpad", "Can only move containers and views."); } swayc_t *view = get_focused_container(&root_container); int i; @@ -554,8 +558,7 @@ static struct cmd_results *cmd_move(int argc, char **argv) { } set_focused_container(focused); } else { - return cmd_results_new(CMD_INVALID, "move", - "Expected 'move ' or 'move to workspace '"); + return cmd_results_new(CMD_INVALID, "move", expected_syntax); } return cmd_results_new(CMD_SUCCESS, NULL, NULL); } -- cgit v1.2.3 From aa14bf0a967e03f62c1e8a86b99b98ec766b7ae3 Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Sun, 25 Oct 2015 13:55:46 +0100 Subject: output: Fix code style. --- sway/output.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/sway/output.c b/sway/output.c index 39c933f8..5044b7aa 100644 --- a/sway/output.c +++ b/sway/output.c @@ -5,17 +5,13 @@ swayc_t *output_by_name(const char* name) { if (strcasecmp(name, "left") == 0) { return swayc_adjacent_output(NULL, MOVE_LEFT); - } - else if (strcasecmp(name, "right") == 0) { + } else if (strcasecmp(name, "right") == 0) { return swayc_adjacent_output(NULL, MOVE_RIGHT); - } - else if (strcasecmp(name, "up") == 0) { + } else if (strcasecmp(name, "up") == 0) { return swayc_adjacent_output(NULL, MOVE_UP); - } - else if (strcasecmp(name, "down") == 0) { + } else if (strcasecmp(name, "down") == 0) { return swayc_adjacent_output(NULL, MOVE_DOWN); - } - else { + } else { for(int i = 0; i < root_container.children->length; ++i) { swayc_t *c = root_container.children->items[i]; if (c->type == C_OUTPUT && strcasecmp(c->name, name) == 0) { -- cgit v1.2.3