[PATCH 1/3] vt: don't make VS16 widening depend on earlier screen contents

From: Nicolas Pitre

Date: Mon Oct 19 2026 - 17:21:37 EST


From: Nicolas Pitre <npitre@xxxxxxxxxxxx>

VS16 (U+FE0F) widens the preceding character only when that character
can be found in the Unicode screen memory. But that memory is allocated
on demand, when the first double-width character is displayed. Until
then vc_uniscr_getc() returns 0 and the VS16 is ignored.

The same sequence, e.g. U+203C U+FE0F, therefore takes one column on a
console that hasn't displayed any double-width character yet, and two
columns afterwards.

Allocate the Unicode screen memory when a VS16 shows up so the
preceding character is always available. vc_uniscr_check() populates
it from the current screen content, which includes that character.

Fixes: 95b05de0a566 ("vt: properly support zero-width Unicode code points")
Assisted-by: LLM
Signed-off-by: Nicolas Pitre <npitre@xxxxxxxxxxxx>
---
drivers/tty/vt/vt.c | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 49a140b49eff..335253aec549 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -3128,6 +3128,15 @@ static int vc_process_ucs(struct vc_data *vc, int *c, int *tc)
}

/* From here the preceding character, if any, must be single-width. */
+
+ /*
+ * The Unicode screen memory is allocated only when required. VS16
+ * needs it to find the character it applies to, so it can't depend
+ * on whether a double-width character was displayed earlier.
+ */
+ if (curr_c == UCS_VS16)
+ vc_uniscr_check(vc);
+
prev_c = vc_uniscr_getc(vc, -1);

if (curr_c == UCS_VS16 && prev_c != 0) {
--
2.55.0