From fba9bb6853695d039913ac8cec2025f2239f22f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 29 Aug 2025 12:48:37 +0200 Subject: [PATCH] render: fix hollow cursor style for "extra" cursors When the cursor is "block style", i.e. either when the window is focused and the cursor is block, or when unfocused and we're supposed to draw a hollow cursor, then we need to draw it *before* compositing the glyph. In all other cases (i.e. beam and underline cursors), it should be rendered after the glyph. With the addition of "extra" cursors, the logic for determining which type it is has become much more complex, and the single if-statement we had was wrong (it didn't handle "extra" cursors correctly). Fix by splitting up all the checks into multiple if-statements. --- render.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 11 deletions(-) diff --git a/render.c b/render.c index cd02aa76..b86f1c5f 100644 --- a/render.c +++ b/render.c @@ -1124,11 +1124,60 @@ render_cell(struct terminal *term, pixman_image_t *pix, mtx_unlock(&term->render.workers.lock); } - if (unlikely(term->kbd_focus && - ((has_primary_cursor && term->cursor_style == CURSOR_BLOCK) || - extra_cursor == MULTI_CURSOR_SHAPE_BLOCK || - (extra_cursor == MULTI_CURSOR_SHAPE_PRIMARY && term->cursor_style == CURSOR_BLOCK)))) - { + bool has_cursor = false; + bool draw_cursor_before_glyph = false; + + if (unlikely(has_primary_cursor || extra_cursor != MULTI_CURSOR_SHAPE_NONE)) { + has_cursor = true; + + if (likely(has_primary_cursor)) { + if (term->kbd_focus) { + draw_cursor_before_glyph = term->cursor_style == CURSOR_BLOCK; + } else { + const struct config *conf = term->conf; + + switch (conf->cursor.unfocused_style) { + case CURSOR_UNFOCUSED_UNCHANGED: + draw_cursor_before_glyph = term->cursor_style == CURSOR_BLOCK; + break; + + case CURSOR_UNFOCUSED_HOLLOW: + draw_cursor_before_glyph = true; + break; + + case CURSOR_UNFOCUSED_NONE: + break; + } + } + } else { + if (term->kbd_focus) { + draw_cursor_before_glyph = + extra_cursor == MULTI_CURSOR_SHAPE_BLOCK || + (extra_cursor == MULTI_CURSOR_SHAPE_PRIMARY && + term->cursor_style == CURSOR_BLOCK); + } else { + const struct config *conf = term->conf; + + switch (conf->cursor.unfocused_style) { + case CURSOR_UNFOCUSED_UNCHANGED: + draw_cursor_before_glyph = + extra_cursor == MULTI_CURSOR_SHAPE_BLOCK || + (extra_cursor == MULTI_CURSOR_SHAPE_PRIMARY && + term->cursor_style == CURSOR_BLOCK); + break; + + case CURSOR_UNFOCUSED_HOLLOW: + draw_cursor_before_glyph = true; + break; + + case CURSOR_UNFOCUSED_NONE: + break; + } + } + } + } + + if (unlikely(draw_cursor_before_glyph)) { const pixman_color_t bg_without_alpha = color_hex_to_pixman(_bg, gamma_correct); draw_cursor(term, cell, font, pix, &fg, &bg_without_alpha, x, y, cell_cols, extra_cursor); } @@ -1279,12 +1328,7 @@ render_cell(struct terminal *term, pixman_image_t *pix, } draw_cursor: - /* TODO: simplify this expression */ - if ((has_primary_cursor && (term->cursor_style != CURSOR_BLOCK || !term->kbd_focus)) || - (extra_cursor != MULTI_CURSOR_SHAPE_NONE && - extra_cursor != MULTI_CURSOR_SHAPE_BLOCK && - !(extra_cursor == MULTI_CURSOR_SHAPE_PRIMARY && term->cursor_style == CURSOR_BLOCK))) - { + if (unlikely(has_cursor && !draw_cursor_before_glyph)) { const pixman_color_t bg_without_alpha = color_hex_to_pixman(_bg, gamma_correct); draw_cursor(term, cell, font, pix, &fg, &bg_without_alpha, x, y, cell_cols, extra_cursor); }