From 3afe317e4637d511bb4f795d20d8e0467c0e42bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 29 Nov 2021 19:23:58 +0100 Subject: [PATCH] render: fix csd border rendering glitch when width > 5px CSD borders are always *at least* 5px. If url.border-width=0, those 5px are all fully transparent (and act as interactive resize handles). As csd.border-width increases, the number of transparent pixels decrease. Once csd.border-width >= 5, the border is fully opaque. When csd.border-width > 5, then width of the border is (obviously) more than 5px. But, when rendering the opaque part of the border, we still used 5px for the invisible part, which caused some pixman rectangles to have negative x/y coordinates. This resulted in rendering glitches due to overflows in pixman when rendering the borders. The fix is to ensure the total border size is always at least, but not *always* 5px. That is, set it to max(5, csd.border-width). This patch also fixes an issue where the CSD borders were not dimmed (like the titlebar) when the window looses input focus. Closes #823 --- CHANGELOG.md | 3 +++ render.c | 26 ++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c3ad3e4..19f5c7ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,9 @@ unrelated cells (https://codeberg.org/dnkl/foot/issues/816). * OSC-8 URIs incorrectly being dropped when resizing the terminal window with the alternate screen active. +* CSD border not being dimmed when window is not focused. +* Visual corruption with large CSD borders + (https://codeberg.org/dnkl/foot/issues/823). ### Security diff --git a/render.c b/render.c index 2710c0a2..cd38d712 100644 --- a/render.c +++ b/render.c @@ -1763,14 +1763,16 @@ render_csd_border(struct terminal *term, enum csd_surface surf_idx, * The “visible” border. */ - int bwidth = term->conf->csd.border_width; /* Full border size */ - int vwidth = term->conf->csd.border_width_visible; /* Visibls size */ + int bwidth = max(term->conf->csd.border_width, + term->conf->csd.border_width_visible); /* Full border size */ + int vwidth = term->conf->csd.border_width_visible; /* Visibls size */ if (vwidth > 0) { const struct config *conf = term->conf; int x = 0, y = 0, w = 0, h = 0; + switch (surf_idx) { case CSD_SURF_TOP: case CSD_SURF_BOTTOM: @@ -1788,17 +1790,33 @@ render_csd_border(struct terminal *term, enum csd_surface surf_idx, h = info->height; break; - default: - break; + case CSD_SURF_TITLE: + case CSD_SURF_MINIMIZE: + case CSD_SURF_MAXIMIZE: + case CSD_SURF_CLOSE: + case CSD_SURF_COUNT: + BUG("unexpected CSD surface type"); } + xassert(x >= 0); + xassert(y >= 0); + xassert(w >= 0); + xassert(h >= 0); + + xassert(x + w <= info->width); + xassert(y + h <= info->height); + uint32_t _color = conf->csd.color.border_set ? conf->csd.color.border : conf->csd.color.title_set ? conf->csd.color.title : 0xffu << 24 | term->conf->colors.fg; + if (!term->visual_focus) + _color = color_dim(term, _color); + uint16_t alpha = _color >> 24 | (_color >> 24 << 8); pixman_color_t color = color_hex_to_pixman_with_alpha(_color, alpha); + pixman_image_fill_rectangles( PIXMAN_OP_SRC, buf->pix[0], &color, 1, &(pixman_rectangle16_t){x, y, w, h});