Clip title bars so that they cannot be rendered outside the container.

Title bars can be rendered outside the container in stacked containers
with too many children or in deep splits where a lot of title bars are rendered.
This commit is contained in:
Dimitris Triantafyllidis 2021-01-20 05:21:43 +02:00
parent d358aab8d9
commit 13a1f7771a

View file

@ -439,6 +439,19 @@ static void render_titlebar(struct sway_output *output,
int titlebar_v_padding = config->titlebar_v_padding; int titlebar_v_padding = config->titlebar_v_padding;
enum alignment title_align = config->title_align; enum alignment title_align = config->title_align;
struct wlr_box clip_box = {
.x = floor(con->current.x - output_x),
.y = 0,
.width = con->current.width,
.height = con->current.y - output_y + con->current.height,
};
scale_box(&clip_box, output_scale);
pixman_region32_t clipped_output_damage;
pixman_region32_init(&clipped_output_damage);
pixman_region32_intersect_rect(&clipped_output_damage, output_damage,
clip_box.x, clip_box.y, clip_box.width, clip_box.height);
// Single pixel bar above title // Single pixel bar above title
memcpy(&color, colors->border, sizeof(float) * 4); memcpy(&color, colors->border, sizeof(float) * 4);
premultiply_alpha(color, con->alpha); premultiply_alpha(color, con->alpha);
@ -447,7 +460,7 @@ static void render_titlebar(struct sway_output *output,
box.width = width; box.width = width;
box.height = titlebar_border_thickness; box.height = titlebar_border_thickness;
scale_box(&box, output_scale); scale_box(&box, output_scale);
render_rect(output, output_damage, &box, color); render_rect(output, &clipped_output_damage, &box, color);
// Single pixel bar below title // Single pixel bar below title
box.x = x; box.x = x;
@ -455,7 +468,7 @@ static void render_titlebar(struct sway_output *output,
box.width = width; box.width = width;
box.height = titlebar_border_thickness; box.height = titlebar_border_thickness;
scale_box(&box, output_scale); scale_box(&box, output_scale);
render_rect(output, output_damage, &box, color); render_rect(output, &clipped_output_damage, &box, color);
// Single pixel left edge // Single pixel left edge
box.x = x; box.x = x;
@ -463,7 +476,7 @@ static void render_titlebar(struct sway_output *output,
box.width = titlebar_border_thickness; box.width = titlebar_border_thickness;
box.height = container_titlebar_height() - titlebar_border_thickness * 2; box.height = container_titlebar_height() - titlebar_border_thickness * 2;
scale_box(&box, output_scale); scale_box(&box, output_scale);
render_rect(output, output_damage, &box, color); render_rect(output, &clipped_output_damage, &box, color);
// Single pixel right edge // Single pixel right edge
box.x = x + width - titlebar_border_thickness; box.x = x + width - titlebar_border_thickness;
@ -471,7 +484,7 @@ static void render_titlebar(struct sway_output *output,
box.width = titlebar_border_thickness; box.width = titlebar_border_thickness;
box.height = container_titlebar_height() - titlebar_border_thickness * 2; box.height = container_titlebar_height() - titlebar_border_thickness * 2;
scale_box(&box, output_scale); scale_box(&box, output_scale);
render_rect(output, output_damage, &box, color); render_rect(output, &clipped_output_damage, &box, color);
int inner_x = x - output_x + titlebar_h_padding; int inner_x = x - output_x + titlebar_h_padding;
int bg_y = y + titlebar_border_thickness; int bg_y = y + titlebar_border_thickness;
@ -519,7 +532,7 @@ static void render_titlebar(struct sway_output *output,
if (ob_inner_width < texture_box.width) { if (ob_inner_width < texture_box.width) {
texture_box.width = ob_inner_width; texture_box.width = ob_inner_width;
} }
render_texture(output->wlr_output, output_damage, marks_texture, render_texture(output->wlr_output, &clipped_output_damage, marks_texture,
NULL, &texture_box, matrix, con->alpha); NULL, &texture_box, matrix, con->alpha);
// Padding above // Padding above
@ -529,12 +542,12 @@ static void render_titlebar(struct sway_output *output,
box.y = round((y + titlebar_border_thickness) * output_scale); box.y = round((y + titlebar_border_thickness) * output_scale);
box.width = texture_box.width; box.width = texture_box.width;
box.height = ob_padding_above; box.height = ob_padding_above;
render_rect(output, output_damage, &box, color); render_rect(output, &clipped_output_damage, &box, color);
// Padding below // Padding below
box.y += ob_padding_above + texture_box.height; box.y += ob_padding_above + texture_box.height;
box.height = ob_padding_below; box.height = ob_padding_below;
render_rect(output, output_damage, &box, color); render_rect(output, &clipped_output_damage, &box, color);
} }
// Title text // Title text
@ -595,7 +608,7 @@ static void render_titlebar(struct sway_output *output,
texture_box.width = ob_inner_width - ob_marks_width; texture_box.width = ob_inner_width - ob_marks_width;
} }
render_texture(output->wlr_output, output_damage, title_texture, render_texture(output->wlr_output, &clipped_output_damage, title_texture,
NULL, &texture_box, matrix, con->alpha); NULL, &texture_box, matrix, con->alpha);
// Padding above // Padding above
@ -605,12 +618,12 @@ static void render_titlebar(struct sway_output *output,
box.y = round((y + titlebar_border_thickness) * output_scale); box.y = round((y + titlebar_border_thickness) * output_scale);
box.width = texture_box.width; box.width = texture_box.width;
box.height = ob_padding_above; box.height = ob_padding_above;
render_rect(output, output_damage, &box, color); render_rect(output, &clipped_output_damage, &box, color);
// Padding below // Padding below
box.y += ob_padding_above + texture_box.height; box.y += ob_padding_above + texture_box.height;
box.height = ob_padding_below; box.height = ob_padding_below;
render_rect(output, output_damage, &box, color); render_rect(output, &clipped_output_damage, &box, color);
} }
// Determine the left + right extends of the textures (output-buffer local) // Determine the left + right extends of the textures (output-buffer local)
@ -644,7 +657,7 @@ static void render_titlebar(struct sway_output *output,
box.x = ob_left_x + ob_left_width + round(output_x * output_scale); box.x = ob_left_x + ob_left_width + round(output_x * output_scale);
box.y = round(bg_y * output_scale); box.y = round(bg_y * output_scale);
box.height = ob_bg_height; box.height = ob_bg_height;
render_rect(output, output_damage, &box, color); render_rect(output, &clipped_output_damage, &box, color);
} }
// Padding on left side // Padding on left side
@ -658,7 +671,7 @@ static void render_titlebar(struct sway_output *output,
if (box.x + box.width < left_x) { if (box.x + box.width < left_x) {
box.width += left_x - box.x - box.width; box.width += left_x - box.x - box.width;
} }
render_rect(output, output_damage, &box, color); render_rect(output, &clipped_output_damage, &box, color);
// Padding on right side // Padding on right side
box.x = x + width - titlebar_h_padding; box.x = x + width - titlebar_h_padding;
@ -672,7 +685,9 @@ static void render_titlebar(struct sway_output *output,
box.width += box.x - right_rx; box.width += box.x - right_rx;
box.x = right_rx; box.x = right_rx;
} }
render_rect(output, output_damage, &box, color); render_rect(output, &clipped_output_damage, &box, color);
pixman_region32_fini(&clipped_output_damage);
} }
/** /**