mirror of
https://github.com/swaywm/sway.git
synced 2026-05-03 06:46:26 -04:00
simplify border renderering and fix border thickness
This commit is contained in:
parent
10f0f4418f
commit
da0c25bc9d
1 changed files with 182 additions and 140 deletions
|
|
@ -224,130 +224,11 @@ static void render_view(struct sway_view *view, struct sway_output *output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all title textures from children of a parent.
|
* Render decorations for a view with "border normal".
|
||||||
*/
|
|
||||||
static struct wlr_texture **get_title_textures(struct sway_container *con) {
|
|
||||||
struct sway_seat *seat = input_manager_current_seat(input_manager);
|
|
||||||
struct sway_container *focus = seat_get_focus(seat);
|
|
||||||
int num_tabs = con->children->length;
|
|
||||||
struct wlr_texture **title_texture =
|
|
||||||
malloc(num_tabs * sizeof(struct wlr_texture));
|
|
||||||
|
|
||||||
for (int i = 0; i < con->children->length; ++i) {
|
|
||||||
struct sway_container *child = con->children->items[i];
|
|
||||||
|
|
||||||
if (child->type == C_VIEW) {
|
|
||||||
if (child->sway_view->border != B_NONE) {
|
|
||||||
if (focus == child) {
|
|
||||||
title_texture[i] = child->title_focused;
|
|
||||||
} else if (seat_get_focus_inactive(seat, con) == child) {
|
|
||||||
title_texture[i] = child->title_focused_inactive;
|
|
||||||
} else {
|
|
||||||
title_texture[i] = child->title_unfocused;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return title_texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Render decorations for the top border with "border normal".
|
|
||||||
*/
|
|
||||||
static void render_container_top_border_normal(struct sway_output *output,
|
|
||||||
struct sway_container *con, struct border_colors *colors,
|
|
||||||
struct wlr_texture *title_texture, int depth) {
|
|
||||||
|
|
||||||
struct wlr_renderer *renderer =
|
|
||||||
wlr_backend_get_renderer(output->wlr_output->backend);
|
|
||||||
struct wlr_box box;
|
|
||||||
float color[4];
|
|
||||||
size_t num_tabs = 1;
|
|
||||||
size_t tab_width = 1;
|
|
||||||
|
|
||||||
if (con->parent->layout == L_TABBED) {
|
|
||||||
num_tabs = con->parent->children->length;
|
|
||||||
tab_width = (con->width / num_tabs);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Single pixel bar above title
|
|
||||||
memcpy(&color, colors->border, sizeof(float) * 4);
|
|
||||||
color[3] *= con->alpha;
|
|
||||||
box.x = con->x + depth * tab_width;
|
|
||||||
box.y = con->y;
|
|
||||||
box.width = con->width / num_tabs;
|
|
||||||
box.height = 1;
|
|
||||||
scale_box(&box, output->wlr_output->scale);
|
|
||||||
wlr_render_rect(renderer, &box, color,
|
|
||||||
output->wlr_output->transform_matrix);
|
|
||||||
|
|
||||||
// Single pixel bar below title
|
|
||||||
box.x = con->x + depth * tab_width;
|
|
||||||
box.y = con->sway_view->y - 1;
|
|
||||||
box.width = con->width / num_tabs;
|
|
||||||
box.height = 1;
|
|
||||||
scale_box(&box, output->wlr_output->scale);
|
|
||||||
wlr_render_rect(renderer, &box, color,
|
|
||||||
output->wlr_output->transform_matrix);
|
|
||||||
|
|
||||||
// Title background
|
|
||||||
memcpy(&color, colors->background, sizeof(float) * 4);
|
|
||||||
color[3] *= con->alpha;
|
|
||||||
box.x = con->x + depth * tab_width;
|
|
||||||
box.y = con->y + 1;
|
|
||||||
box.width = con->width / num_tabs + 2;
|
|
||||||
box.height = con->sway_view->y - con->y - 2;
|
|
||||||
scale_box(&box, output->wlr_output->scale);
|
|
||||||
wlr_render_rect(renderer, &box, color,
|
|
||||||
output->wlr_output->transform_matrix);
|
|
||||||
|
|
||||||
// Title text
|
|
||||||
if (title_texture) {
|
|
||||||
wlr_renderer_scissor(renderer, &box);
|
|
||||||
wlr_render_texture(renderer, title_texture,
|
|
||||||
output->wlr_output->transform_matrix, box.x + 2, box.y, 1);
|
|
||||||
wlr_renderer_scissor(renderer, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Render decorations for the top border for tabbed view with "border normal".
|
|
||||||
*/
|
|
||||||
static void render_container_top_tabbed_border_normal(struct sway_output *output,
|
|
||||||
struct sway_container *con, struct wlr_texture **title_texture,
|
|
||||||
int focus_number, bool active) {
|
|
||||||
|
|
||||||
int index_tabs = con->parent->children->length - 1;
|
|
||||||
int index_left_of_focus = focus_number - 1;
|
|
||||||
struct border_colors *unfocused = &config->border_colors.unfocused;
|
|
||||||
struct border_colors *focus_color;
|
|
||||||
|
|
||||||
if (active) {
|
|
||||||
focus_color = &config->border_colors.focused;
|
|
||||||
} else {
|
|
||||||
focus_color = &config->border_colors.focused_inactive;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index_left_of_focus >= 0) {
|
|
||||||
for (int i = 0; i <= index_left_of_focus; ++i) {
|
|
||||||
render_container_top_border_normal(output, con, unfocused, title_texture[i], i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
render_container_top_border_normal(output, con, focus_color, title_texture[focus_number], focus_number);
|
|
||||||
if (index_tabs > index_left_of_focus) {
|
|
||||||
for (int j = focus_number + 1; j <= index_tabs; ++j) {
|
|
||||||
render_container_top_border_normal(output, con, unfocused, title_texture[j], j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Render decorations for a horizontal or vertical view with "border normal".
|
|
||||||
*/
|
*/
|
||||||
static void render_container_simple_border_normal(struct sway_output *output,
|
static void render_container_simple_border_normal(struct sway_output *output,
|
||||||
struct sway_container *con, struct border_colors *colors,
|
struct sway_container *con, struct border_colors *colors,
|
||||||
struct wlr_texture *title_texture, bool top) {
|
struct wlr_texture *title_texture) {
|
||||||
|
|
||||||
struct wlr_renderer *renderer =
|
struct wlr_renderer *renderer =
|
||||||
wlr_backend_get_renderer(output->wlr_output->backend);
|
wlr_backend_get_renderer(output->wlr_output->backend);
|
||||||
struct wlr_box box;
|
struct wlr_box box;
|
||||||
|
|
@ -394,8 +275,43 @@ static void render_container_simple_border_normal(struct sway_output *output,
|
||||||
wlr_render_rect(renderer, &box, color,
|
wlr_render_rect(renderer, &box, color,
|
||||||
output->wlr_output->transform_matrix);
|
output->wlr_output->transform_matrix);
|
||||||
|
|
||||||
if (top) {
|
// Single pixel bar above title
|
||||||
render_container_top_border_normal(output, con, colors, title_texture, 0);
|
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;
|
||||||
|
scale_box(&box, output->wlr_output->scale);
|
||||||
|
wlr_render_rect(renderer, &box, color,
|
||||||
|
output->wlr_output->transform_matrix);
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
scale_box(&box, output->wlr_output->scale);
|
||||||
|
wlr_render_rect(renderer, &box, color,
|
||||||
|
output->wlr_output->transform_matrix);
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
scale_box(&box, output->wlr_output->scale);
|
||||||
|
wlr_render_rect(renderer, &box, color,
|
||||||
|
output->wlr_output->transform_matrix);
|
||||||
|
|
||||||
|
// Title text
|
||||||
|
if (title_texture) {
|
||||||
|
wlr_renderer_scissor(renderer, &box);
|
||||||
|
wlr_render_texture(renderer, title_texture,
|
||||||
|
output->wlr_output->transform_matrix, box.x, box.y, 1);
|
||||||
|
wlr_renderer_scissor(renderer, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -409,6 +325,7 @@ static void render_container_simple_border_pixel(struct sway_output *output,
|
||||||
struct wlr_box box;
|
struct wlr_box box;
|
||||||
float color[4];
|
float color[4];
|
||||||
|
|
||||||
|
// Child border - left edge
|
||||||
memcpy(&color, colors->child_border, sizeof(float) * 4);
|
memcpy(&color, colors->child_border, sizeof(float) * 4);
|
||||||
color[3] *= con->alpha;
|
color[3] *= con->alpha;
|
||||||
box.x = con->x;
|
box.x = con->x;
|
||||||
|
|
@ -460,19 +377,129 @@ static void render_container_simple_border_pixel(struct sway_output *output,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render decorations for a tabbed view with "border normal".
|
* Render decorations for the left, right, and bottom edge of a view with "border normal".
|
||||||
*/
|
*/
|
||||||
|
static void render_container_border_outline_normal(struct sway_output *output,
|
||||||
|
struct sway_container *con, struct border_colors *colors) {
|
||||||
|
struct wlr_renderer *renderer =
|
||||||
|
wlr_backend_get_renderer(output->wlr_output->backend);
|
||||||
|
struct wlr_box box;
|
||||||
|
float color[4];
|
||||||
|
|
||||||
static void render_container_tabbed_border_normal(struct sway_output *output,
|
// Child border - left edge
|
||||||
struct sway_container *con, struct wlr_texture **title_texture,
|
memcpy(&color, colors->child_border, sizeof(float) * 4);
|
||||||
int depth, bool active) {
|
color[3] *= con->alpha;
|
||||||
|
box.x = con->x;
|
||||||
|
box.y = con->y + (con->sway_view->y - con->y);
|
||||||
|
box.width = con->sway_view->border_thickness;
|
||||||
|
box.height = con->height;
|
||||||
|
scale_box(&box, output->wlr_output->scale);
|
||||||
|
wlr_render_rect(renderer, &box, color,
|
||||||
|
output->wlr_output->transform_matrix);
|
||||||
|
|
||||||
struct border_colors *focused_color = &config->border_colors.focused;
|
// Child border - right edge
|
||||||
render_container_simple_border_normal(output, con, focused_color,
|
if (con->parent->children->length == 1 && con->parent->layout == L_HORIZ) {
|
||||||
NULL, false);
|
memcpy(&color, colors->indicator, sizeof(float) * 4);
|
||||||
render_container_top_tabbed_border_normal(output, con, title_texture,
|
} else {
|
||||||
depth, active);
|
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 + (con->sway_view->y - con->y);
|
||||||
|
box.width = con->sway_view->border_thickness;
|
||||||
|
box.height = con->height;
|
||||||
|
scale_box(&box, output->wlr_output->scale);
|
||||||
|
wlr_render_rect(renderer, &box, color,
|
||||||
|
output->wlr_output->transform_matrix);
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
scale_box(&box, output->wlr_output->scale);
|
||||||
|
wlr_render_rect(renderer, &box, color,
|
||||||
|
output->wlr_output->transform_matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render decorations for the top border for tabbed view with "border normal".
|
||||||
|
*/
|
||||||
|
static void render_container_top_tabbed_border_normal(struct sway_output *output,
|
||||||
|
struct sway_container *con, struct border_colors *colors,
|
||||||
|
struct wlr_texture *title_texture, size_t depth) {
|
||||||
|
|
||||||
|
struct wlr_renderer *renderer =
|
||||||
|
wlr_backend_get_renderer(output->wlr_output->backend);
|
||||||
|
struct wlr_box box;
|
||||||
|
float color[4];
|
||||||
|
size_t num_tabs = con->parent->children->length;
|
||||||
|
float tab_width = con->width / num_tabs;
|
||||||
|
|
||||||
|
// Single pixel bar above title
|
||||||
|
memcpy(&color, colors->border, sizeof(float) * 4);
|
||||||
|
color[3] *= con->alpha;
|
||||||
|
box.x = con->x + depth * tab_width;
|
||||||
|
box.y = con->y;
|
||||||
|
box.width = con->width / num_tabs;
|
||||||
|
box.height = 1;
|
||||||
|
scale_box(&box, output->wlr_output->scale);
|
||||||
|
wlr_render_rect(renderer, &box, color,
|
||||||
|
output->wlr_output->transform_matrix);
|
||||||
|
|
||||||
|
// Single pixel bar below title
|
||||||
|
box.x = con->x + depth*tab_width;
|
||||||
|
box.y = con->sway_view->y - 1;
|
||||||
|
box.width = con->width / num_tabs;
|
||||||
|
box.height = 1;
|
||||||
|
scale_box(&box, output->wlr_output->scale);
|
||||||
|
wlr_render_rect(renderer, &box, color,
|
||||||
|
output->wlr_output->transform_matrix);
|
||||||
|
|
||||||
|
// Single pixel wide vertical line tab separator on the left
|
||||||
|
box.x = con->x + depth * tab_width;
|
||||||
|
box.y = con->y + 1;
|
||||||
|
box.width = con->sway_view->border_thickness;
|
||||||
|
box.height = con->sway_view->y - con->y - 2;
|
||||||
|
scale_box(&box, output->wlr_output->scale);
|
||||||
|
wlr_render_rect(renderer, &box, color,
|
||||||
|
output->wlr_output->transform_matrix);
|
||||||
|
|
||||||
|
// Single pixel wide verticl line tab separator on the right
|
||||||
|
box.x = con->x + (depth + 1) * tab_width - con->sway_view->border_thickness;
|
||||||
|
box.y = con->y + 1;
|
||||||
|
box.width = con->sway_view->border_thickness;
|
||||||
|
box.height = con->sway_view->y - con->y - 2;
|
||||||
|
scale_box(&box, output->wlr_output->scale);
|
||||||
|
wlr_render_rect(renderer, &box, color,
|
||||||
|
output->wlr_output->transform_matrix);
|
||||||
|
|
||||||
|
// Title background
|
||||||
|
memcpy(&color, colors->background, sizeof(float) * 4);
|
||||||
|
color[3] *= con->alpha;
|
||||||
|
box.x = con->x + con->sway_view->border_thickness + depth * tab_width;
|
||||||
|
box.y = con->y + 1;
|
||||||
|
box.width = con->width / num_tabs - con->sway_view->border_thickness * 2;
|
||||||
|
box.height = con->sway_view->y - con->y - 2;
|
||||||
|
scale_box(&box, output->wlr_output->scale);
|
||||||
|
wlr_render_rect(renderer, &box, color,
|
||||||
|
output->wlr_output->transform_matrix);
|
||||||
|
|
||||||
|
// Title text
|
||||||
|
if (title_texture) {
|
||||||
|
wlr_renderer_scissor(renderer, &box);
|
||||||
|
wlr_render_texture(renderer, title_texture,
|
||||||
|
output->wlr_output->transform_matrix, box.x, box.y, 1);
|
||||||
|
wlr_renderer_scissor(renderer, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void render_container(struct sway_output *output,
|
static void render_container(struct sway_output *output,
|
||||||
struct sway_container *con);
|
struct sway_container *con);
|
||||||
|
|
||||||
|
|
@ -507,7 +534,7 @@ static void render_container_simple(struct sway_output *output,
|
||||||
|
|
||||||
if (child->sway_view->border == B_NORMAL) {
|
if (child->sway_view->border == B_NORMAL) {
|
||||||
render_container_simple_border_normal(output, child,
|
render_container_simple_border_normal(output, child,
|
||||||
colors, title_texture, true);
|
colors, title_texture);
|
||||||
} else {
|
} else {
|
||||||
render_container_simple_border_pixel(output, child, colors);
|
render_container_simple_border_pixel(output, child, colors);
|
||||||
}
|
}
|
||||||
|
|
@ -526,27 +553,42 @@ static void render_container_tabbed(struct sway_output *output,
|
||||||
struct sway_container *con) {
|
struct sway_container *con) {
|
||||||
struct sway_seat *seat = input_manager_current_seat(input_manager);
|
struct sway_seat *seat = input_manager_current_seat(input_manager);
|
||||||
struct sway_container *focus = seat_get_focus(seat);
|
struct sway_container *focus = seat_get_focus(seat);
|
||||||
struct wlr_texture **title_texture = get_title_textures(con);
|
|
||||||
|
|
||||||
|
struct sway_container *active_child = NULL;
|
||||||
|
struct border_colors *focused_colors = &config->border_colors.focused;
|
||||||
for (int i = 0; i < con->children->length; ++i) {
|
for (int i = 0; i < con->children->length; ++i) {
|
||||||
struct sway_container *child = con->children->items[i];
|
struct sway_container *child = con->children->items[i];
|
||||||
|
|
||||||
if (child->type == C_VIEW) {
|
if (child->type == C_VIEW) {
|
||||||
|
struct border_colors *colors;
|
||||||
|
struct wlr_texture *title_texture;
|
||||||
if (child->sway_view->border != B_NONE) {
|
if (child->sway_view->border != B_NONE) {
|
||||||
if (focus == child) {
|
if (focus == child) {
|
||||||
render_container_tabbed_border_normal(output, child,
|
colors = &config->border_colors.focused;
|
||||||
title_texture, i, true);
|
title_texture = child->title_focused;
|
||||||
render_view(child->sway_view, output);
|
active_child = child;
|
||||||
} else if (seat_get_focus_inactive(seat, con) == child) {
|
} else if (seat_get_focus_inactive(seat, con) == child) {
|
||||||
render_container_tabbed_border_normal(output, child,
|
colors= &config->border_colors.focused_inactive;
|
||||||
title_texture, i, false);
|
title_texture = child->title_focused_inactive;
|
||||||
render_view(child->sway_view, output);
|
active_child = child;
|
||||||
|
} else {
|
||||||
|
colors = &config->border_colors.unfocused;
|
||||||
|
title_texture = child->title_unfocused;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
render_container_top_tabbed_border_normal(output, child, colors,
|
||||||
|
title_texture, i);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
render_container(output, child);
|
render_container(output, child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (active_child) {
|
||||||
|
render_container_border_outline_normal(output, active_child, focused_colors);
|
||||||
|
render_view(active_child->sway_view, output);
|
||||||
|
} else {
|
||||||
|
wlr_log(L_INFO, "tabbed layout has no active child");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue