mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
term: insert-mode: handle combining characters correctly
When the client application emits combining characters, for example multi-codepoint emojis, in insert-mode, we ended up pushing partial graphemes to the right, for each codepoint, resulting in too many cells (and with the wrong content) being inserted. The fix is fairly simple; don't "insert" when appending characters to an existing grapheme cluster. This isn't something we can detect easily in print_insert() (it would require us to do grapheme clustering again). Fortunately, we do have the required information in action_utf8_print(). So, pass this information as a boolean to term_print(). Closes #1947
This commit is contained in:
parent
dd01783f88
commit
88dcde3ed8
5 changed files with 14 additions and 6 deletions
|
|
@ -105,9 +105,13 @@
|
||||||
([#1929][1929]).
|
([#1929][1929]).
|
||||||
* Foot not closing file descriptors for unrecognized or `no_keymap`
|
* Foot not closing file descriptors for unrecognized or `no_keymap`
|
||||||
keymaps.
|
keymaps.
|
||||||
|
* Combining characters (including emojis consisting of multiple
|
||||||
|
codepoints) not being handled correctly when _insert mode_ is
|
||||||
|
enabled ([#1947][1947]).
|
||||||
|
|
||||||
[1918]: https://codeberg.org/dnkl/foot/issues/1918
|
[1918]: https://codeberg.org/dnkl/foot/issues/1918
|
||||||
[1929]: https://codeberg.org/dnkl/foot/issues/1929
|
[1929]: https://codeberg.org/dnkl/foot/issues/1929
|
||||||
|
[1947]: https://codeberg.org/dnkl/foot/issues/1947
|
||||||
|
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
|
||||||
2
csi.c
2
csi.c
|
|
@ -793,7 +793,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
const int width = c32width(term->vt.last_printed);
|
const int width = c32width(term->vt.last_printed);
|
||||||
if (width > 0) {
|
if (width > 0) {
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
term_print(term, term->vt.last_printed, width);
|
term_print(term, term->vt.last_printed, width, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -3896,7 +3896,7 @@ term_fill(struct terminal *term, int r, int c, uint8_t data, size_t count,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
term_print(struct terminal *term, char32_t wc, int width)
|
term_print(struct terminal *term, char32_t wc, int width, bool insert_mode_disable)
|
||||||
{
|
{
|
||||||
xassert(width > 0);
|
xassert(width > 0);
|
||||||
|
|
||||||
|
|
@ -3918,7 +3918,8 @@ term_print(struct terminal *term, char32_t wc, int width)
|
||||||
}
|
}
|
||||||
|
|
||||||
print_linewrap(term);
|
print_linewrap(term);
|
||||||
print_insert(term, width);
|
if (!insert_mode_disable)
|
||||||
|
print_insert(term, width);
|
||||||
|
|
||||||
int col = grid->cursor.point.col;
|
int col = grid->cursor.point.col;
|
||||||
|
|
||||||
|
|
@ -3990,7 +3991,7 @@ term_print(struct terminal *term, char32_t wc, int width)
|
||||||
static void
|
static void
|
||||||
ascii_printer_generic(struct terminal *term, char32_t wc)
|
ascii_printer_generic(struct terminal *term, char32_t wc)
|
||||||
{
|
{
|
||||||
term_print(term, wc, 1);
|
term_print(term, wc, 1, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
||||||
|
|
@ -894,7 +894,8 @@ void term_cursor_up(struct terminal *term, int count);
|
||||||
void term_cursor_down(struct terminal *term, int count);
|
void term_cursor_down(struct terminal *term, int count);
|
||||||
void term_cursor_blink_update(struct terminal *term);
|
void term_cursor_blink_update(struct terminal *term);
|
||||||
|
|
||||||
void term_print(struct terminal *term, char32_t wc, int width);
|
void term_print(struct terminal *term, char32_t wc, int width,
|
||||||
|
bool insert_mode_disable);
|
||||||
void term_fill(struct terminal *term, int row, int col, uint8_t c, size_t count,
|
void term_fill(struct terminal *term, int row, int col, uint8_t c, size_t count,
|
||||||
bool use_sgr_attrs);
|
bool use_sgr_attrs);
|
||||||
|
|
||||||
|
|
|
||||||
4
vt.c
4
vt.c
|
|
@ -703,6 +703,7 @@ static void
|
||||||
action_utf8_print(struct terminal *term, char32_t wc)
|
action_utf8_print(struct terminal *term, char32_t wc)
|
||||||
{
|
{
|
||||||
int width = c32width(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)
|
#if !defined(FOOT_GRAPHEME_CLUSTERING)
|
||||||
|
|
@ -757,6 +758,7 @@ action_utf8_print(struct terminal *term, char32_t wc)
|
||||||
if (base_width > 0) {
|
if (base_width > 0) {
|
||||||
term->grid->cursor.point.col = col;
|
term->grid->cursor.point.col = col;
|
||||||
term->grid->cursor.lcf = false;
|
term->grid->cursor.lcf = false;
|
||||||
|
insert_mode_disable = true;
|
||||||
|
|
||||||
if (composed == NULL) {
|
if (composed == NULL) {
|
||||||
bool base_from_primary;
|
bool base_from_primary;
|
||||||
|
|
@ -954,7 +956,7 @@ action_utf8_print(struct terminal *term, char32_t wc)
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (width > 0)
|
if (width > 0)
|
||||||
term_print(term, wc, width);
|
term_print(term, wc, width, insert_mode_disable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue