From 84358788aae8472166bc01013515e09f9bc2f40c Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 10 Jan 2017 23:30:34 -0500 Subject: [PATCH 1/6] Update .clang-format - not entirely usable yet I've run into a situation where clang-format does not support the necessary style rules. It will have to be patched before clang-format is fully adopted into Sway. Use this file with caution. --- .clang-format | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.clang-format b/.clang-format index 83d50545..5818da3c 100644 --- a/.clang-format +++ b/.clang-format @@ -1,7 +1,16 @@ BasedOnStyle: LLVM -IndentWidth: 8 +IndentWidth: 4 +TabWidth: 4 UseTab: Always BreakBeforeBraces: Attach AllowShortIfStatementsOnASingleLine: false IndentCaseLabels: false -ColumnLimit: 0 +SortIncludes: false +ColumnLimit: 80 +AlignAfterOpenBracket: DontAlign +BinPackParameters: false +BinPackArguments: false +ContinuationIndentWidth: 8 +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortLoopsOnASingleLine: true +ReflowComments: false From 527c259d063a4d7ca2bfd62b3b877bb70419535b Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 11 Jan 2017 21:13:44 -0500 Subject: [PATCH 2/6] Fix #1008 --- sway/handlers.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sway/handlers.c b/sway/handlers.c index 3abe2fca..ad6c1c19 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -807,6 +807,10 @@ static bool swayc_border_check(swayc_t *c, const void *_origin) { const struct wlc_point *origin = _origin; const struct wlc_geometry title_bar = c->title_bar_geometry; + if (c->border_type != B_NORMAL) { + return false; + } + if (origin->x >= title_bar.origin.x && origin->y >= title_bar.origin.y && origin->x < title_bar.origin.x + (int32_t)title_bar.size.w && origin->y < title_bar.origin.y + (int32_t)title_bar.size.h) { From ea1313d80d5ee1623b00c8cdf6e7ff8a7e14c2ae Mon Sep 17 00:00:00 2001 From: Mykyta Holubakha Date: Thu, 12 Jan 2017 04:25:03 +0200 Subject: [PATCH 3/6] Keep CAP_SYS_PTRACE with suid binary --- sway/main.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/sway/main.c b/sway/main.c index e8a02e7a..6c74aab2 100644 --- a/sway/main.c +++ b/sway/main.c @@ -10,6 +10,9 @@ #include #include #include +#ifdef __linux__ +#include +#endif #include "sway/extensions.h" #include "sway/layout.h" #include "sway/config.h" @@ -289,6 +292,18 @@ int main(int argc, char **argv) { return 0; } +#ifdef __linux__ + bool suid = false; + if (getuid() != geteuid() || getgid() != getegid()) { + // Retain capabilities after setuid() + if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) { + sway_log(L_ERROR, "Cannot keep caps after setuid()"); + exit(EXIT_FAILURE); + } + suid = true; + } +#endif + // we need to setup logging before wlc_init in case it fails. if (debug) { init_log(L_DEBUG); @@ -311,6 +326,19 @@ int main(int argc, char **argv) { } register_extensions(); +#ifdef __linux__ + if (suid) { + // Drop every cap except CAP_SYS_PTRACE + cap_t caps = cap_init(); + cap_value_t keep = CAP_SYS_PTRACE; + if (cap_set_flag(caps, CAP_PERMITTED, 1, &keep, CAP_SET) || + cap_set_flag(caps, CAP_EFFECTIVE, 1, &keep, CAP_SET) || + cap_set_proc(caps)) { + sway_log(L_ERROR, "Failed to drop extra capabilities"); + exit(EXIT_FAILURE); + } + } +#endif // handle SIGTERM signals signal(SIGTERM, sig_handler); From d9ba61d7e91c5aceef1a6a736dc65f0594b9be2a Mon Sep 17 00:00:00 2001 From: Mykyta Holubakha Date: Thu, 12 Jan 2017 04:35:09 +0200 Subject: [PATCH 4/6] Log capability dropping --- sway/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sway/main.c b/sway/main.c index 6c74aab2..7bf71b53 100644 --- a/sway/main.c +++ b/sway/main.c @@ -331,6 +331,7 @@ int main(int argc, char **argv) { // Drop every cap except CAP_SYS_PTRACE cap_t caps = cap_init(); cap_value_t keep = CAP_SYS_PTRACE; + sway_log(L_INFO, "Dropping extra capabilities"); if (cap_set_flag(caps, CAP_PERMITTED, 1, &keep, CAP_SET) || cap_set_flag(caps, CAP_EFFECTIVE, 1, &keep, CAP_SET) || cap_set_proc(caps)) { From c04819e8c080e40e1e872c8624c60c4a51087019 Mon Sep 17 00:00:00 2001 From: Frantisek Fladung Date: Thu, 12 Jan 2017 12:11:04 +0100 Subject: [PATCH 5/6] Implement hide_edge_borders smart (like in i3 4.13) --- include/sway/config.h | 3 ++- sway/commands/hide_edge_borders.c | 2 ++ sway/layout.c | 7 +++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/sway/config.h b/include/sway/config.h index 4a14cd36..febde63d 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -178,7 +178,8 @@ enum edge_border_types { E_NONE, /**< Don't hide edge borders */ E_VERTICAL, /**< hide vertical edge borders */ E_HORIZONTAL, /**< hide horizontal edge borders */ - E_BOTH /**< hide vertical and horizontal edge borders */ + E_BOTH, /**< hide vertical and horizontal edge borders */ + E_SMART /**< hide both if precisely one window is present in workspace */ }; enum command_context { diff --git a/sway/commands/hide_edge_borders.c b/sway/commands/hide_edge_borders.c index 0be940c1..cb4f052d 100644 --- a/sway/commands/hide_edge_borders.c +++ b/sway/commands/hide_edge_borders.c @@ -15,6 +15,8 @@ struct cmd_results *cmd_hide_edge_borders(int argc, char **argv) { config->hide_edge_borders = E_HORIZONTAL; } else if (strcasecmp(argv[0], "both") == 0) { config->hide_edge_borders = E_BOTH; + } else if (strcasecmp(argv[0], "smart") == 0) { + config->hide_edge_borders = E_SMART; } else { return cmd_results_new(CMD_INVALID, "hide_edge_borders", "Expected 'hide_edge_borders '"); diff --git a/sway/layout.c b/sway/layout.c index ea4a680d..bb37a360 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -665,6 +665,13 @@ void update_geometry(swayc_t *container) { border_bottom = 0; } } + + if (config->hide_edge_borders == E_SMART && workspace->children->length == 1) { + border_top = 0; + border_bottom = 0; + border_left = 0; + border_right = 0; + } } int title_bar_height = config->font_height + 4; //borders + padding From eda4bad725b8a76accdb2a9c648efa046b88c0c0 Mon Sep 17 00:00:00 2001 From: Daniel Kessler Date: Fri, 13 Jan 2017 16:06:10 -0800 Subject: [PATCH 6/6] Add output wrapping This fixes issue #733. Now if the user focuses output right but is at the rightmost monitor, the focus will wrap the the leftmost monitor. This commit adds a new function, swayc_opposite_output, which selects the opposite output given a position and a direction. Now, when calling output_by_name, we first check if there is an adjacent output to switch to. If that fails, we call swayc_opposite_output to handle wrapping. --- include/sway/output.h | 1 + sway/output.c | 76 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 72 insertions(+), 5 deletions(-) diff --git a/include/sway/output.h b/include/sway/output.h index e8afd5ed..e1bdd3f0 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -7,6 +7,7 @@ // Position is absolute coordinates on the edge where the adjacent output // should be searched for. swayc_t *output_by_name(const char* name, const struct wlc_point *abs_pos); +swayc_t *swayc_opposite_output(enum movement_direction dir, const struct wlc_point *abs_pos); swayc_t *swayc_adjacent_output(swayc_t *output, enum movement_direction dir, const struct wlc_point *abs_pos, bool pick_closest); // Place absolute coordinates for given container into given wlc_point. diff --git a/sway/output.c b/sway/output.c index b337b143..c0f29c5a 100644 --- a/sway/output.c +++ b/sway/output.c @@ -13,14 +13,29 @@ void output_get_scaled_size(wlc_handle handle, struct wlc_size *size) { } swayc_t *output_by_name(const char* name, const struct wlc_point *abs_pos) { + swayc_t *output = NULL; + // If there is no output directly next to the current one, use + // swayc_opposite_output to wrap. if (strcasecmp(name, "left") == 0) { - return swayc_adjacent_output(NULL, MOVE_LEFT, abs_pos, true); + output = swayc_adjacent_output(NULL, MOVE_LEFT, abs_pos, true); + if (!output) { + output = swayc_opposite_output(MOVE_RIGHT, abs_pos); + } } else if (strcasecmp(name, "right") == 0) { - return swayc_adjacent_output(NULL, MOVE_RIGHT, abs_pos, true); + output = swayc_adjacent_output(NULL, MOVE_RIGHT, abs_pos, true); + if (!output) { + output = swayc_opposite_output(MOVE_LEFT, abs_pos); + } } else if (strcasecmp(name, "up") == 0) { - return swayc_adjacent_output(NULL, MOVE_UP, abs_pos, true); + output = swayc_adjacent_output(NULL, MOVE_UP, abs_pos, true); + if (!output) { + output = swayc_opposite_output(MOVE_DOWN, abs_pos); + } } else if (strcasecmp(name, "down") == 0) { - return swayc_adjacent_output(NULL, MOVE_DOWN, abs_pos, true); + output = swayc_adjacent_output(NULL, MOVE_DOWN, abs_pos, true); + if (!output) { + output = swayc_opposite_output(MOVE_UP, abs_pos); + } } else { for(int i = 0; i < root_container.children->length; ++i) { swayc_t *c = root_container.children->items[i]; @@ -29,7 +44,58 @@ swayc_t *output_by_name(const char* name, const struct wlc_point *abs_pos) { } } } - return NULL; + return output; +} + +swayc_t *swayc_opposite_output(enum movement_direction dir, + const struct wlc_point *abs_pos) { + + // Search through all the outputs and pick the output whose edge covers the + // given position, and is at leftmost/rightmost/upmost/downmost side of the + // screen (decided by the direction given). + swayc_t *opposite = NULL; + char *dir_text = NULL; + switch(dir) { + case MOVE_LEFT: + case MOVE_RIGHT: ; + for (int i = 0; i < root_container.children->length; ++i) { + swayc_t *c = root_container.children->items[i]; + if (abs_pos->y >= c->y && abs_pos->y <= c->y + c->height) { + if (!opposite) { + opposite = c; + } else if ((dir == MOVE_LEFT && c->x < opposite->x) + || (dir == MOVE_RIGHT && c->x > opposite->x)) { + opposite = c; + } + } + } + dir_text = dir == MOVE_LEFT ? "leftmost" : "rightmost"; + break; + case MOVE_UP: + case MOVE_DOWN: ; + for (int i = 0; i < root_container.children->length; ++i) { + swayc_t *c = root_container.children->items[i]; + if (abs_pos->x >= c->x && abs_pos->x <= c->x + c->width) { + if (!opposite) { + opposite = c; + } else if ((dir == MOVE_UP && c->y < opposite->y) + || (dir == MOVE_DOWN && c->y > opposite->y)) { + opposite = c; + } + } + } + dir_text = dir == MOVE_UP ? "upmost" : "downmost"; + break; + default: + sway_abort("Function called with invalid argument."); + break; + } + if (opposite) { + sway_log(L_DEBUG, "%s (%.0fx%.0f+%.0f+%.0f) is %s from y-position %i", + opposite->name, opposite->width, opposite->height, opposite->x, opposite->y, + dir_text, abs_pos->y); + } + return opposite; } // Position is where on the edge (as absolute position) the adjacent output should be searched for.