diff --git a/sway/commands.c b/sway/commands.c index 2e1cdc2c..37ead367 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -108,6 +108,7 @@ static struct cmd_handler handlers[] = { { "font", cmd_font }, { "for_window", cmd_for_window }, { "fullscreen", cmd_fullscreen }, + { "hide_edge_borders", cmd_hide_edge_borders }, { "include", cmd_include }, { "input", cmd_input }, { "mode", cmd_mode }, diff --git a/sway/commands/hide_edge_borders.c b/sway/commands/hide_edge_borders.c new file mode 100644 index 00000000..7d70055b --- /dev/null +++ b/sway/commands/hide_edge_borders.c @@ -0,0 +1,37 @@ +#include "sway/commands.h" +#include "sway/config.h" +#include "sway/tree/container.h" +#include "sway/tree/view.h" + +static void _configure_view(struct sway_container *con, void *data) { + if (con->type == C_VIEW) { + view_autoconfigure(con->sway_view); + } +} + +struct cmd_results *cmd_hide_edge_borders(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "hide_edge_borders", EXPECTED_EQUAL_TO, 1))) { + return error; + } + + if (strcmp(argv[0], "none") == 0) { + config->hide_edge_borders = E_NONE; + } else if (strcmp(argv[0], "vertical") == 0) { + config->hide_edge_borders = E_VERTICAL; + } else if (strcmp(argv[0], "horizontal") == 0) { + config->hide_edge_borders = E_HORIZONTAL; + } else if (strcmp(argv[0], "both") == 0) { + config->hide_edge_borders = E_BOTH; + } else if (strcmp(argv[0], "smart") == 0) { + config->hide_edge_borders = E_SMART; + } else { + return cmd_results_new(CMD_INVALID, "hide_edge_borders", + "Expected 'hide_edge_borders " + "'"); + } + + container_for_each_descendant_dfs(&root_container, _configure_view, NULL); + + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} diff --git a/sway/desktop/output.c b/sway/desktop/output.c index a25139b4..c3bff03d 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -14,6 +14,7 @@ #include #include #include "log.h" +#include "sway/config.h" #include "sway/input/input-manager.h" #include "sway/input/seat.h" #include "sway/layers.h" @@ -321,82 +322,96 @@ static void render_container_simple_border_normal(struct sway_output *output, struct wlr_box box; float color[4]; - // Child border - left edge - memcpy(&color, colors->child_border, sizeof(float) * 4); - color[3] *= con->alpha; - box.x = con->x; - box.y = con->y + 1; - box.width = con->sway_view->border_thickness; - box.height = con->height - 1; - render_rect(output->wlr_output, output_damage, &box, color); - - // Child border - right edge - if (con->parent->children->length == 1 && con->parent->layout == L_HORIZ) { - memcpy(&color, colors->indicator, sizeof(float) * 4); - } else { - memcpy(&color, colors->child_border, sizeof(float) * 4); - } - color[3] *= con->alpha; - box.x = con->x + con->width - con->sway_view->border_thickness; - box.y = con->y + 1; - box.width = con->sway_view->border_thickness; - box.height = con->height - 1; - render_rect(output->wlr_output, output_damage, &box, color); + struct sway_container *workspace = container_parent(con, C_WORKSPACE); + int other_views = workspace->children->length - 1; - // Child border - bottom edge - if (con->parent->children->length == 1 && con->parent->layout == L_VERT) { - memcpy(&color, colors->indicator, sizeof(float) * 4); - } else { + if (config->hide_edge_borders != E_VERTICAL + && config->hide_edge_borders != E_BOTH + && (config->hide_edge_borders != E_SMART || other_views)) { + // Child border - left edge memcpy(&color, colors->child_border, sizeof(float) * 4); - } - color[3] *= con->alpha; - box.x = con->x; - box.y = con->y + con->height - con->sway_view->border_thickness; - box.width = con->width; - box.height = con->sway_view->border_thickness; - render_rect(output->wlr_output, output_damage, &box, color); - - // Single pixel bar above title - memcpy(&color, colors->border, sizeof(float) * 4); - color[3] *= con->alpha; - box.x = con->x; - box.y = con->y; - box.width = con->width; - box.height = 1; - render_rect(output->wlr_output, output_damage, &box, color); - - // Single pixel bar below title - box.x = con->x + con->sway_view->border_thickness; - box.y = con->sway_view->y - 1; - box.width = con->width - con->sway_view->border_thickness * 2; - box.height = 1; - render_rect(output->wlr_output, output_damage, &box, color); - - // Title background - memcpy(&color, colors->background, sizeof(float) * 4); - color[3] *= con->alpha; - box.x = con->x + con->sway_view->border_thickness; - box.y = con->y + 1; - box.width = con->width - con->sway_view->border_thickness * 2; - box.height = con->sway_view->y - con->y - 2; - render_rect(output->wlr_output, output_damage, &box, color); - - // Title text - if (title_texture) { - float output_scale = output->wlr_output->scale; - struct wlr_box texture_box = { - .x = box.x * output_scale, - .y = box.y * output_scale, - }; - wlr_texture_get_size(title_texture, - &texture_box.width, &texture_box.height); - - float matrix[9]; - wlr_matrix_project_box(matrix, &texture_box, WL_OUTPUT_TRANSFORM_NORMAL, - 0.0, output->wlr_output->transform_matrix); - - render_texture(output->wlr_output, output_damage, title_texture, - &texture_box, matrix, 1.0); + color[3] *= con->alpha; + box.x = con->x; + box.y = con->y + 1; + box.width = con->sway_view->border_thickness; + box.height = con->height - 1; + render_rect(output->wlr_output, output_damage, &box, color); + + // Child border - right edge + if (con->parent->children->length == 1 + && con->parent->layout == L_HORIZ) { + memcpy(&color, colors->indicator, sizeof(float) * 4); + } else { + memcpy(&color, colors->child_border, sizeof(float) * 4); + } + color[3] *= con->alpha; + box.x = con->x + con->width - con->sway_view->border_thickness; + box.y = con->y + 1; + box.width = con->sway_view->border_thickness; + box.height = con->height - 1; + render_rect(output->wlr_output, output_damage, &box, color); + } + + if (config->hide_edge_borders != E_HORIZONTAL + && config->hide_edge_borders != E_BOTH + && (config->hide_edge_borders != E_SMART || other_views)) { + // Child border - bottom edge + if (con->parent->children->length == 1 + && con->parent->layout == L_VERT) { + memcpy(&color, colors->indicator, sizeof(float) * 4); + } else { + memcpy(&color, colors->child_border, sizeof(float) * 4); + } + color[3] *= con->alpha; + box.x = con->x; + box.y = con->y + con->height - con->sway_view->border_thickness; + box.width = con->width; + box.height = con->sway_view->border_thickness; + render_rect(output->wlr_output, output_damage, &box, color); + + // Single pixel bar above title + memcpy(&color, colors->border, sizeof(float) * 4); + color[3] *= con->alpha; + box.x = con->x; + box.y = con->y; + box.width = con->width; + box.height = 1; + render_rect(output->wlr_output, output_damage, &box, color); + + // Single pixel bar below title + box.x = con->x + con->sway_view->border_thickness; + box.y = con->sway_view->y - 1; + box.width = con->width - con->sway_view->border_thickness * 2; + box.height = 1; + render_rect(output->wlr_output, output_damage, &box, color); + + // Title background + memcpy(&color, colors->background, sizeof(float) * 4); + color[3] *= con->alpha; + box.x = con->x + con->sway_view->border_thickness; + box.y = con->y + 1; + box.width = con->width - con->sway_view->border_thickness * 2; + box.height = con->sway_view->y - con->y - 2; + render_rect(output->wlr_output, output_damage, &box, color); + + // Title text + if (title_texture) { + float output_scale = output->wlr_output->scale; + struct wlr_box texture_box = { + .x = box.x * output_scale, + .y = box.y * output_scale, + }; + wlr_texture_get_size(title_texture, + &texture_box.width, &texture_box.height); + + float matrix[9]; + wlr_matrix_project_box(matrix, &texture_box, + WL_OUTPUT_TRANSFORM_NORMAL, + 0.0, output->wlr_output->transform_matrix); + + render_texture(output->wlr_output, output_damage, title_texture, + &texture_box, matrix, 1.0); + } } } @@ -409,47 +424,60 @@ static void render_container_simple_border_pixel(struct sway_output *output, struct wlr_box box; float color[4]; - // Child border - left edge - memcpy(&color, colors->child_border, sizeof(float) * 4); - color[3] *= con->alpha; - box.x = con->x; - box.y = con->y; - box.width = con->sway_view->border_thickness; - box.height = con->height; - render_rect(output->wlr_output, output_damage, &box, color); - - // Child border - right edge - if (con->parent->children->length == 1 && con->parent->layout == L_HORIZ) { - memcpy(&color, colors->indicator, sizeof(float) * 4); - } else { - memcpy(&color, colors->child_border, sizeof(float) * 4); - } - color[3] *= con->alpha; - box.x = con->x + con->width - con->sway_view->border_thickness; - box.y = con->y; - box.width = con->sway_view->border_thickness; - box.height = con->height; - render_rect(output->wlr_output, output_damage, &box, color); - - // Child border - top edge - box.x = con->x; - box.y = con->y; - box.width = con->width; - box.height = con->sway_view->border_thickness; - render_rect(output->wlr_output, output_damage, &box, color); - - // Child border - bottom edge - if (con->parent->children->length == 1 && con->parent->layout == L_VERT) { - memcpy(&color, colors->indicator, sizeof(float) * 4); - } else { + struct sway_container *workspace = container_parent(con, C_WORKSPACE); + int other_views = workspace->children->length - 1; + + if (config->hide_edge_borders != E_VERTICAL + && config->hide_edge_borders != E_BOTH + && (config->hide_edge_borders != E_SMART || other_views)) { + // Child border - left edge memcpy(&color, colors->child_border, sizeof(float) * 4); + color[3] *= con->alpha; + box.x = con->x; + box.y = con->y; + box.width = con->sway_view->border_thickness; + box.height = con->height; + render_rect(output->wlr_output, output_damage, &box, color); + + // Child border - right edge + if (con->parent->children->length == 1 + && con->parent->layout == L_HORIZ) { + memcpy(&color, colors->indicator, sizeof(float) * 4); + } else { + memcpy(&color, colors->child_border, sizeof(float) * 4); + } + color[3] *= con->alpha; + box.x = con->x + con->width - con->sway_view->border_thickness; + box.y = con->y; + box.width = con->sway_view->border_thickness; + box.height = con->height; + render_rect(output->wlr_output, output_damage, &box, color); + } + + if (config->hide_edge_borders != E_HORIZONTAL + && config->hide_edge_borders != E_BOTH + && (config->hide_edge_borders != E_SMART || other_views)) { + // Child border - top edge + box.x = con->x; + box.y = con->y; + box.width = con->width; + box.height = con->sway_view->border_thickness; + render_rect(output->wlr_output, output_damage, &box, color); + + // Child border - bottom edge + if (con->parent->children->length == 1 + && con->parent->layout == L_VERT) { + memcpy(&color, colors->indicator, sizeof(float) * 4); + } else { + memcpy(&color, colors->child_border, sizeof(float) * 4); + } + color[3] *= con->alpha; + box.x = con->x; + box.y = con->y + con->height - con->sway_view->border_thickness; + box.width = con->width; + box.height = con->sway_view->border_thickness; + render_rect(output->wlr_output, output_damage, &box, color); } - color[3] *= con->alpha; - box.x = con->x; - box.y = con->y + con->height - con->sway_view->border_thickness; - box.width = con->width; - box.height = con->sway_view->border_thickness; - render_rect(output->wlr_output, output_damage, &box, color); } static void render_container(struct sway_output *output, diff --git a/sway/meson.build b/sway/meson.build index f70a8e44..acf4a3e4 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -41,6 +41,7 @@ sway_sources = files( 'commands/font.c', 'commands/for_window.c', 'commands/fullscreen.c', + 'commands/hide_edge_borders.c', 'commands/kill.c', 'commands/opacity.c', 'commands/include.c', diff --git a/sway/tree/view.c b/sway/tree/view.c index afd7eade..c2496f0d 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -100,6 +100,9 @@ void view_autoconfigure(struct sway_view *view) { return; } + struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); + int other_views = ws->children->length - 1; + double x, y, width, height; x = y = width = height = 0; switch (view->border) { @@ -110,18 +113,51 @@ void view_autoconfigure(struct sway_view *view) { height = view->swayc->height; break; case B_PIXEL: - x = view->swayc->x + view->border_thickness; - y = view->swayc->y + view->border_thickness; - width = view->swayc->width - view->border_thickness * 2; - height = view->swayc->height - view->border_thickness * 2; + if (view->swayc->layout > L_VERT + || config->hide_edge_borders == E_NONE + || config->hide_edge_borders == E_HORIZONTAL + || (config->hide_edge_borders == E_SMART && other_views)) { + x = view->swayc->x + view->border_thickness; + width = view->swayc->width - view->border_thickness * 2; + } else { + x = view->swayc->x; + width = view->swayc->width; + } + if (view->swayc->layout > L_VERT + || config->hide_edge_borders == E_NONE + || config->hide_edge_borders == E_VERTICAL + || (config->hide_edge_borders == E_SMART && other_views)) { + y = view->swayc->y + view->border_thickness; + height = view->swayc->height - view->border_thickness * 2; + } else { + y = view->swayc->y; + height = view->swayc->height; + } break; case B_NORMAL: - // Height is: border + title height + border + view height + border - x = view->swayc->x + view->border_thickness; - y = view->swayc->y + config->font_height + view->border_thickness * 2; - width = view->swayc->width - view->border_thickness * 2; - height = view->swayc->height - config->font_height - - view->border_thickness * 3; + if (view->swayc->layout > L_VERT + || config->hide_edge_borders == E_NONE + || config->hide_edge_borders == E_HORIZONTAL + || (config->hide_edge_borders == E_SMART && other_views)) { + x = view->swayc->x + view->border_thickness; + width = view->swayc->width - view->border_thickness * 2; + } else { + x = view->swayc->x; + width = view->swayc->width; + } + if (view->swayc->layout > L_VERT + || config->hide_edge_borders == E_NONE + || config->hide_edge_borders == E_VERTICAL + || (config->hide_edge_borders == E_SMART && other_views)) { + // Height is: border + title height + border + view height + border + y = view->swayc->y + config->font_height + + view->border_thickness * 2; + height = view->swayc->height - config->font_height + - view->border_thickness * 3; + } else { + y = view->swayc->y; + height = view->swayc->height; + } break; }