Fix emoji variation selector width calculation in string_advance

Addresses issue where emoji with variation selectors (like ❣️, ♥️) were
incorrectly calculated as width 1 instead of width 2, causing display
overflow in modern terminals.

- Add variation selector detection (0xFE0F) in string_advance_with_grapheme_support()
- Apply special width handling for base emoji + variation selector combinations
- Ensures consistent width calculation with input field processing
- Fixes chat window overflow issues in terminals like Ghostty

This brings string_advance logic in line with unichar_array_advance_cluster
which already had proper variation selector handling.
This commit is contained in:
kofany 2025-09-10 20:55:25 +02:00
commit becc4f9068

View file

@ -42,6 +42,7 @@ static int string_advance_with_grapheme_support(char const **str, int policy)
const char *start = *str;
const char *pos = *str;
int cluster_width = 0;
int has_variation_selector = 0;
utf8proc_ssize_t bytes;
if (policy != TREAT_STRING_AS_UTF8) {
@ -69,6 +70,11 @@ static int string_advance_with_grapheme_support(char const **str, int policy)
break;
}
/* Check for variation selector */
if (codepoint == 0xFE0F) {
has_variation_selector = 1;
}
/* Add this codepoint's width to the cluster */
if (unichar_isprint(codepoint)) {
int char_width = i_wcwidth(codepoint);
@ -81,6 +87,12 @@ static int string_advance_with_grapheme_support(char const **str, int policy)
pos += bytes;
}
/* Special handling for emoji with variation selector */
if (has_variation_selector && cluster_width == 1) {
/* Base emoji (like ❣ U+2763, ♥ U+2665) + variation selector should have width 2 */
cluster_width = 2;
}
*str = pos;
return cluster_width > 0 ? cluster_width : 1;
}