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..acd066a7 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..f232c0be 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,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 @@ -1729,8 +1727,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); }