From aae236819e5e3b238d1b1d2d10c696dc78060970 Mon Sep 17 00:00:00 2001 From: txf Date: Thu, 22 Jan 2026 19:25:26 +0000 Subject: [PATCH] Add pad-extend option --- config.c | 4 ++ config.h | 1 + render.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 114 insertions(+), 16 deletions(-) diff --git a/config.c b/config.c index 7599a100..1b770b5c 100644 --- a/config.c +++ b/config.c @@ -977,6 +977,9 @@ parse_section_main(struct context *ctx) return true; } + else if (streq(key, "pad-extend")) + return value_to_bool(ctx, &conf->pad_extend); + else if (streq(key, "resize-delay-ms")) return value_to_uint16(ctx, 10, &conf->resize_delay_ms); @@ -3458,6 +3461,7 @@ config_load(struct config *conf, const char *conf_path, }, .pad_x = 0, .pad_y = 0, + .pad_extend = false, .center_when = CENTER_MAXIMIZED_AND_FULLSCREEN, .resize_by_cells = true, .resize_keep_grid = true, diff --git a/config.h b/config.h index 7face9f0..3da031ca 100644 --- a/config.h +++ b/config.h @@ -234,6 +234,7 @@ struct config { unsigned pad_x; unsigned pad_y; + bool pad_extend; enum center_when center_when; bool resize_by_cells; diff --git a/render.c b/render.c index 857c7d7a..03f1cf2c 100644 --- a/render.c +++ b/render.c @@ -1246,44 +1246,133 @@ render_urgency(struct terminal *term, struct buffer *buf) }); } +static uint32_t +cell_bg_color(const struct terminal *term, const struct cell *cell) +{ + switch (cell->attrs.bg_src) { + case COLOR_RGB: + return cell->attrs.bg; + case COLOR_BASE16: + case COLOR_BASE256: + return term->colors.table[cell->attrs.bg]; + case COLOR_DEFAULT: + default: + return term->reverse ? term->colors.fg : term->colors.bg; + } +} + static void render_margin(struct terminal *term, struct buffer *buf, int start_line, int end_line, bool apply_damage) { - /* Fill area outside the cell grid with the default background color */ const int rmargin = term->width - term->margins.right; const int bmargin = term->height - term->margins.bottom; const int line_count = end_line - start_line; const bool gamma_correct = wayl_do_linear_blending(term->wl, term->conf); - const uint32_t _bg = !term->reverse ? term->colors.bg : term->colors.fg; + const uint32_t default_bg = !term->reverse ? term->colors.bg : term->colors.fg; uint16_t alpha = term->colors.alpha; - if (term->window->is_fullscreen) { - /* Disable alpha in fullscreen - see render_cell() for details */ + if (term->window->is_fullscreen) alpha = 0xffff; - } - pixman_color_t bg = color_hex_to_pixman_with_alpha(_bg, alpha, gamma_correct); + pixman_color_t bg = color_hex_to_pixman_with_alpha(default_bg, alpha, gamma_correct); - pixman_image_fill_rectangles( - PIXMAN_OP_SRC, buf->pix[0], &bg, 4, + /* Default behavior: fill with background color */ + pixman_image_fill_rectangles(PIXMAN_OP_SRC, buf->pix[0], &bg, 4, (pixman_rectangle16_t[]){ - /* Top */ {0, 0, term->width, term->margins.top}, - - /* Bottom */ {0, bmargin, term->width, term->margins.bottom}, - - /* Left */ {0, term->margins.top + start_line * term->cell_height, term->margins.left, line_count * term->cell_height}, - - /* Right */ {rmargin, term->margins.top + start_line * term->cell_height, term->margins.right, line_count * term->cell_height}, - }); + }); + /* Extended mode: overlay edge cell colors */ + if (!term->conf->pad_extend) + goto done; + + /* Left/right margins: extend each row's edge cell colors */ + for (int r = 0; r < term->rows; r++) { + struct row *row = grid_row_in_view(term->grid, r); + if (row == NULL || row->cells == NULL) + continue; + + int y = term->margins.top + r * term->cell_height; + + uint32_t left_bg = cell_bg_color(term, &row->cells[0]); + if (left_bg != default_bg) { + pixman_color_t c = color_hex_to_pixman_with_alpha(left_bg, alpha, gamma_correct); + pixman_image_fill_rectangles(PIXMAN_OP_SRC, buf->pix[0], &c, 1, + &(pixman_rectangle16_t){0, y, term->margins.left, term->cell_height}); + } + + uint32_t right_bg = cell_bg_color(term, &row->cells[term->cols - 1]); + if (right_bg != default_bg) { + pixman_color_t c = color_hex_to_pixman_with_alpha(right_bg, alpha, gamma_correct); + pixman_image_fill_rectangles(PIXMAN_OP_SRC, buf->pix[0], &c, 1, + &(pixman_rectangle16_t){rmargin, y, term->margins.right, term->cell_height}); + } + } + + /* Top/bottom margins: extend each column's edge cell colors */ + struct row *top_row = grid_row_in_view(term->grid, 0); + struct row *bot_row = grid_row_in_view(term->grid, term->rows - 1); + + for (int c = 0; c < term->cols; c++) { + int x = term->margins.left + c * term->cell_width; + + if (top_row != NULL && top_row->cells != NULL) { + uint32_t top_bg = cell_bg_color(term, &top_row->cells[c]); + if (top_bg != default_bg) { + pixman_color_t col = color_hex_to_pixman_with_alpha(top_bg, alpha, gamma_correct); + pixman_image_fill_rectangles(PIXMAN_OP_SRC, buf->pix[0], &col, 1, + &(pixman_rectangle16_t){x, 0, term->cell_width, term->margins.top}); + } + } + + if (bot_row != NULL && bot_row->cells != NULL) { + uint32_t bot_bg = cell_bg_color(term, &bot_row->cells[c]); + if (bot_bg != default_bg) { + pixman_color_t col = color_hex_to_pixman_with_alpha(bot_bg, alpha, gamma_correct); + pixman_image_fill_rectangles(PIXMAN_OP_SRC, buf->pix[0], &col, 1, + &(pixman_rectangle16_t){x, bmargin, term->cell_width, term->margins.bottom}); + } + } + } + + /* Fill corners with horizontal edge colors (priority) */ + if (top_row != NULL && top_row->cells != NULL) { + uint32_t tl = cell_bg_color(term, &top_row->cells[0]); + uint32_t tr = cell_bg_color(term, &top_row->cells[term->cols - 1]); + if (tl != default_bg) { + pixman_color_t c = color_hex_to_pixman_with_alpha(tl, alpha, gamma_correct); + pixman_image_fill_rectangles(PIXMAN_OP_SRC, buf->pix[0], &c, 1, + &(pixman_rectangle16_t){0, 0, term->margins.left, term->margins.top}); + } + if (tr != default_bg) { + pixman_color_t c = color_hex_to_pixman_with_alpha(tr, alpha, gamma_correct); + pixman_image_fill_rectangles(PIXMAN_OP_SRC, buf->pix[0], &c, 1, + &(pixman_rectangle16_t){rmargin, 0, term->margins.right, term->margins.top}); + } + } + if (bot_row != NULL && bot_row->cells != NULL) { + uint32_t bl = cell_bg_color(term, &bot_row->cells[0]); + uint32_t br = cell_bg_color(term, &bot_row->cells[term->cols - 1]); + if (bl != default_bg) { + pixman_color_t c = color_hex_to_pixman_with_alpha(bl, alpha, gamma_correct); + pixman_image_fill_rectangles(PIXMAN_OP_SRC, buf->pix[0], &c, 1, + &(pixman_rectangle16_t){0, bmargin, term->margins.left, term->margins.bottom}); + } + if (br != default_bg) { + pixman_color_t c = color_hex_to_pixman_with_alpha(br, alpha, gamma_correct); + pixman_image_fill_rectangles(PIXMAN_OP_SRC, buf->pix[0], &c, 1, + &(pixman_rectangle16_t){rmargin, bmargin, term->margins.right, term->margins.bottom}); + } + } + +done: if (term->render.urgency) render_urgency(term, buf); @@ -3618,6 +3707,10 @@ grid_render(struct terminal *term) pixman_region32_fini(&damage); + /* Re-render margins to extend edge cell colors if enabled */ + if (term->conf->pad_extend) + render_margin(term, buf, 0, term->rows, true); + render_overlay(term); render_ime_preedit(term, buf); render_scrollback_position(term);