From c6bb23b7ddd6393c3d4a621bd2c610922a933867 Mon Sep 17 00:00:00 2001 From: "S. Christoffer Eliesen" Date: Sun, 25 Oct 2015 01:20:00 +0200 Subject: [PATCH 1/4] 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 000000000..10ff05969 --- /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 c0b775db3..c777e6926 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 000000000..39c933f82 --- /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; +} From 5a70853253633482b09ebdcbde0f4ec7502c7527 Mon Sep 17 00:00:00 2001 From: "S. Christoffer Eliesen" Date: Sun, 25 Oct 2015 00:34:57 +0200 Subject: [PATCH 2/4] 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 f8deaf268..806725a6a 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 0c1f8c9e8..1aa7579b2 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 3cd873d69..6388a9b2b 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 a206d9719..62be73e56 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 */ From c49e5340db64d9e8018696ecca55cacd14ee638a Mon Sep 17 00:00:00 2001 From: "S. Christoffer Eliesen" Date: Sat, 24 Oct 2015 16:55:21 +0200 Subject: [PATCH 3/4] 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 8c45dabe0..0102fc5a2 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]); - } + } 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."); + } - 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); + } + move_container_to(view, get_focused_container(ws)); + } else { + return cmd_results_new(CMD_INVALID, "move", expected_syntax); } - - 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 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); } From 83ca7d3a5ccc3943de80cd07bd52e7005b13ab75 Mon Sep 17 00:00:00 2001 From: "S. Christoffer Eliesen" Date: Sun, 25 Oct 2015 13:55:46 +0100 Subject: [PATCH 4/4] 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 39c933f82..5044b7aa0 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) {