From d7742d031276a19160dc9317ff6fb5aac861d853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 12 Jun 2026 15:34:12 +0200 Subject: [PATCH] term: do not allow codepoint merging into grapheme clusters directly after a cursor move That is, only do grapheme clustering when printing codepoints in sequence, without any cursor movements in between. Closes #2383 --- CHANGELOG.md | 7 +++++++ terminal.c | 13 ++++++++++++- terminal.h | 2 ++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16bf715d..803408af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,6 +73,13 @@ ## Unreleased ### Added ### Changed + +* Do not allow codepoints to be merged into grapheme clusters directly + after a cursor move ([#2383][2383]). + +[2383]: https://codeberg.org/dnkl/foot/issues/2383 + + ### Deprecated ### Removed ### Fixed diff --git a/terminal.c b/terminal.c index 8eafbcbe..374d4371 100644 --- a/terminal.c +++ b/terminal.c @@ -4086,6 +4086,10 @@ term_print(struct terminal *term, char32_t wc, int width, bool insert_mode_disab xassert(!grid->cursor.lcf); grid->cursor.point.col = col; + +#if defined(FOOT_GRAPHEME_CLUSTERING) + term->vt.codepoint_merging_ok = true; +#endif } static void @@ -4126,6 +4130,9 @@ ascii_printer_fast(struct terminal *term, char32_t wc) xassert(!grid->cursor.lcf); grid->cursor.point.col = col; +#if defined(FOOT_GRAPHEME_CLUSTERING) + term->vt.codepoint_merging_ok = true; +#endif if (unlikely(row->extra != NULL)) { grid_row_uri_range_erase(row, uri_start, uri_start); @@ -4210,7 +4217,11 @@ term_process_and_print_non_ascii(struct terminal *term, char32_t wc) { int width = c32width(wc); bool insert_mode_disable = false; - const bool grapheme_clustering = term->grapheme_shaping; + const bool grapheme_clustering = term->grapheme_shaping +#if defined(FOOT_GRAPHEME_CLUSTERING) + && term->vt.codepoint_merging_ok +#endif + ; #if !defined(FOOT_GRAPHEME_CLUSTERING) xassert(!grapheme_clustering); diff --git a/terminal.h b/terminal.h index 446d5f23..7e95697e 100644 --- a/terminal.h +++ b/terminal.h @@ -264,6 +264,7 @@ struct vt { char32_t last_printed; #if defined(FOOT_GRAPHEME_CLUSTERING) utf8proc_int32_t grapheme_state; + bool codepoint_merging_ok; #endif char32_t utf8; struct { @@ -994,5 +995,6 @@ static inline void term_reset_grapheme_state(struct terminal *term) { #if defined(FOOT_GRAPHEME_CLUSTERING) term->vt.grapheme_state = 0; + term->vt.codepoint_merging_ok = false; #endif }