From 5e4de143de6c43ab54a5df7cea169674f8ea79a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 27 Oct 2021 18:27:08 +0200 Subject: [PATCH 1/3] csd: add support for a visible border MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we’re using CSDs, we’ve up until now rendered a 5px invisible border. This border handles interactive resizing. I.e. hovering it changes the mouse cursor, and mouse button events are used to start an interactive resize. This patch makes it possible to color part of (or the entire) border, with a configurable color. To facilitate this, two new options have been added: * csd.border-width * csd.border-color border-width defaults to 0, resulting in the look we’re used to. border-color defaults to the title bar color. If the title bar color hasn’t been set, it defaults to the default foreground color (just like the title bar color does). This means that, setting border-width but not border-color, results in a border that blends with the title bar. --- CHANGELOG.md | 2 ++ config.c | 29 +++++++++++++++++++++-- config.h | 3 +++ doc/foot.ini.5.scd | 11 +++++++++ foot.ini | 2 ++ render.c | 59 ++++++++++++++++++++++++++++++++++++++++++---- 6 files changed, 99 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf2848ed..2e409cbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,8 @@ action will not be sent to the application (https://codeberg.org/dnkl/foot/issues/765). * Color schemes are now installed to `${datadir}/foot/themes`. +* `[csd].border-width` and `[csd].border-color`, allowing you to + configure the width and color of the CSD border. ### Changed diff --git a/config.c b/config.c index bd9ebbf2..4e772aa1 100644 --- a/config.c +++ b/config.c @@ -1489,7 +1489,9 @@ parse_section_csd(const char *key, const char *value, struct config *conf, else if (strcmp(key, "size") == 0) { unsigned long pixels; if (!str_to_ulong(value, 10, &pixels)) { - LOG_AND_NOTIFY_ERR("%s:%d: expected an integer, got '%s'", path, lineno, value); + LOG_AND_NOTIFY_ERR( + "%s:%d: [csd]: size: expected an integer, got '%s'", + path, lineno, value); return false; } @@ -1499,7 +1501,9 @@ parse_section_csd(const char *key, const char *value, struct config *conf, else if (strcmp(key, "button-width") == 0) { unsigned long pixels; if (!str_to_ulong(value, 10, &pixels)) { - LOG_AND_NOTIFY_ERR("%s:%d: expected an integer, got '%s'", path, lineno, value); + LOG_AND_NOTIFY_ERR( + "%s:%d: [csd]: button-width: expected an integer, got '%s'", + path, lineno, value); return false; } @@ -1542,6 +1546,27 @@ parse_section_csd(const char *key, const char *value, struct config *conf, conf->csd.color.close = color; } + else if (strcmp(key, "border-color") == 0) { + uint32_t color; + if (!str_to_color(value, &color, true, conf, path, lineno, "csd", "border-color")) + return false; + + conf->csd.color.border_set = true; + conf->csd.color.border = color; + } + + else if (strcmp(key, "border-width") == 0) { + unsigned long width; + if (!str_to_ulong(value, 10, &width)) { + LOG_AND_NOTIFY_ERR( + "%s:%u: [csd]: border-width: expected an integer, got '%s'", + path, lineno, value); + return false; + } + + conf->csd.border_width_visible = width; + } + else { LOG_AND_NOTIFY_ERR("%s:%u: [csd]: %s: invalid action", path, lineno, key); diff --git a/config.h b/config.h index db4bc275..b47c3537 100644 --- a/config.h +++ b/config.h @@ -214,6 +214,7 @@ struct config { int title_height; int border_width; + int border_width_visible; int button_width; struct { @@ -222,11 +223,13 @@ struct config { bool minimize_set:1; bool maximize_set:1; bool close_set:1; + bool border_set:1; uint32_t title; uint32_t buttons; uint32_t minimize; uint32_t maximize; uint32_t close; + uint32_t border; } color; struct config_font_list font; diff --git a/doc/foot.ini.5.scd b/doc/foot.ini.5.scd index 0eba49dd..669a2ee9 100644 --- a/doc/foot.ini.5.scd +++ b/doc/foot.ini.5.scd @@ -564,6 +564,17 @@ component. title bar size. That is, all *:size* and *:pixelsize* attributes will be ignored. Default: _primary font_. +*border-width* + Width of the border, in pixels (subject to output scaling). Note + that the border encompasses the entire window, including the title + bar. Default: _0_. + +*border-color* + Color of border, on the format AARRGGBB. By default, the title bar + color is used. If the title bar color has not been set, the + default foreground color (from the color scheme) is used. Default: + _titlebar color_. + *button-width* Width, in pixels (subject to output scaling), of the minimize/maximize/close buttons. Default: _26_. diff --git a/foot.ini b/foot.ini index b37aa383..72921bb7 100644 --- a/foot.ini +++ b/foot.ini @@ -98,6 +98,8 @@ # size=26 # font= # color= +# border-width=0 +# border-color= # button-width=26 # button-color= # button-minimize-color= diff --git a/render.c b/render.c index ddeb72f4..5d93074e 100644 --- a/render.c +++ b/render.c @@ -1508,7 +1508,8 @@ get_csd_data(const struct terminal *term, enum csd_surface surf_idx) /* Only title bar is rendered in maximized mode */ const int border_width = !term->window->is_maximized - ? term->conf->csd.border_width * term->scale : 0; + ? max(term->conf->csd.border_width, + term->conf->csd.border_width_visible) * term->scale : 0; const int title_height = term->window->is_fullscreen ? 0 @@ -1565,12 +1566,12 @@ render_csd_part(struct terminal *term, { xassert(term->window->csd_mode == CSD_YES); - pixman_image_t *src = pixman_image_create_solid_fill(color); + //pixman_image_t *src = pixman_image_create_solid_fill(color); pixman_image_fill_rectangles( PIXMAN_OP_SRC, buf->pix[0], color, 1, &(pixman_rectangle16_t){0, 0, buf->width, buf->height}); - pixman_image_unref(src); + //pixman_image_unref(src); } static void @@ -1729,8 +1730,56 @@ render_csd_border(struct terminal *term, enum csd_surface surf_idx, xassert(info->width % term->scale == 0); xassert(info->height % term->scale == 0); - pixman_color_t color = color_hex_to_pixman_with_alpha(0, 0); - render_csd_part(term, surf, buf, info->width, info->height, &color); + { + pixman_color_t color = color_hex_to_pixman_with_alpha(0, 0); + render_csd_part(term, surf, buf, info->width, info->height, &color); + } + + /* + * The “visible” border. + */ + + int bwidth = term->conf->csd.border_width; /* 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: + x = bwidth - vwidth; + y = surf_idx == CSD_SURF_TOP ? info->height - vwidth : 0; + w = info->width - 2 * x; + h = vwidth; + break; + + case CSD_SURF_LEFT: + case CSD_SURF_RIGHT: + x = surf_idx == CSD_SURF_LEFT ? bwidth - vwidth : 0; + y = 0; + w = vwidth; + h = info->height; + break; + + default: + break; + } + + 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; + 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}); + } + csd_commit(term, surf, buf); } From 61635b413228a03ddbc535a429d6f5597969f327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 29 Oct 2021 19:30:11 +0200 Subject: [PATCH 2/3] foot.ini: csd.border-color: -> --- foot.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/foot.ini b/foot.ini index 72921bb7..acd066a7 100644 --- a/foot.ini +++ b/foot.ini @@ -99,7 +99,7 @@ # font= # color= # border-width=0 -# border-color= +# border-color= # button-width=26 # button-color= # button-minimize-color= From e69c3e5b1e87a27c86fb4ca27c0078a00f5727ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 29 Oct 2021 19:31:09 +0200 Subject: [PATCH 3/3] =?UTF-8?q?render:=20csd=5Fpart:=20we=20don=E2=80=99t?= =?UTF-8?q?=20use=20the=20=E2=80=98src=E2=80=99=20pixman=20image?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- render.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/render.c b/render.c index 5d93074e..f232c0be 100644 --- a/render.c +++ b/render.c @@ -1566,12 +1566,9 @@ render_csd_part(struct terminal *term, { xassert(term->window->csd_mode == CSD_YES); - //pixman_image_t *src = pixman_image_create_solid_fill(color); - pixman_image_fill_rectangles( PIXMAN_OP_SRC, buf->pix[0], color, 1, &(pixman_rectangle16_t){0, 0, buf->width, buf->height}); - //pixman_image_unref(src); } static void