aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.clang-format13
-rw-r--r--include/sway/config.h3
-rw-r--r--include/sway/output.h1
-rw-r--r--sway/commands/hide_edge_borders.c2
-rw-r--r--sway/handlers.c4
-rw-r--r--sway/layout.c7
-rw-r--r--sway/main.c29
-rw-r--r--sway/output.c76
8 files changed, 127 insertions, 8 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
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 <none|vertical|horizontal|both>'");
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 <unistd.h>
#include <getopt.h>
#include <sys/capability.h>
+#ifdef __linux__
+#include <sys/prctl.h>
+#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.