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 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/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/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/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) { diff --git a/sway/layout.c b/sway/layout.c index fdd2fe6b..4b30f729 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -717,6 +717,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 diff --git a/sway/main.c b/sway/main.c index e8a02e7a..7bf71b53 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,20 @@ 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; + 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)) { + sway_log(L_ERROR, "Failed to drop extra capabilities"); + exit(EXIT_FAILURE); + } + } +#endif // handle SIGTERM signals signal(SIGTERM, sig_handler); 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.