diff --git a/docs/changelog.rst b/docs/changelog.rst index af114e0c1..0053714dd 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -122,6 +122,8 @@ Detailed list of changes - Watchers: A new event for global watchers corresponding to the tab bar being changed (:disc:`8842`) +- Fix a regression in 0.40.0 that broke handing of the VS16 variation selector when it caused a character to reflow to the next line (:iss:`8848`) + 0.42.2 [2025-07-16] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/kitty/screen.c b/kitty/screen.c index 1f18a110a..c9bd6e08e 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -944,7 +944,8 @@ move_cursor_past_multicell(Screen *self, index_type required_width) { } static void -move_widened_char_past_multiline_chars(Screen *self, CPUCell* cpu_cell, GPUCell *gpu_cell, index_type xpos, index_type ypos) { +move_widened_char_past_multiline_chars(Screen *self, text_loop_state *s, CPUCell* cpu_cell, GPUCell *gpu_cell, index_type xpos, index_type ypos) { + index_type before = self->cursor->y; self->cursor->x = xpos; self->cursor->y = ypos; if (move_cursor_past_multicell(self, 2)) { CPUCell *cp; GPUCell *gp; @@ -957,6 +958,8 @@ move_widened_char_past_multiline_chars(Screen *self, CPUCell* cpu_cell, GPUCell self->cursor->x++; } *cpu_cell = (CPUCell){0}; *gpu_cell = (GPUCell){0}; + if (self->cursor->y == before) init_segmentation_state(self, s); + else init_text_loop_line(self, s); } static bool @@ -984,8 +987,7 @@ draw_combining_char(Screen *self, text_loop_state *s, char_type ch) { CPUCell *second = cp + xpos + 1; if (second->is_multicell) { if (second->y) { - move_widened_char_past_multiline_chars(self, cpu_cell, gpu_cell, xpos, s->prev.y); - init_segmentation_state(self, s); + move_widened_char_past_multiline_chars(self, s, cpu_cell, gpu_cell, xpos, s->prev.y); return; } nuke_multicell_char_at(self, xpos + 1, s->prev.y, false); @@ -994,8 +996,7 @@ draw_combining_char(Screen *self, text_loop_state *s, char_type ch) { self->cursor->x++; *second = *cpu_cell; second->x = 1; } else { - move_widened_char_past_multiline_chars(self, cpu_cell, gpu_cell, xpos, s->prev.y); - init_segmentation_state(self, s); + move_widened_char_past_multiline_chars(self, s, cpu_cell, gpu_cell, xpos, s->prev.y); } } } else if (ch == VS15) { diff --git a/kitty_tests/screen.py b/kitty_tests/screen.py index 03ad0d43e..41b81f431 100644 --- a/kitty_tests/screen.py +++ b/kitty_tests/screen.py @@ -732,6 +732,10 @@ class TestScreen(BaseTest): self.ae(s.text_for_selection(), ('a\u00adb',)) def test_variation_selectors(self): + s = self.create_screen(cols=3) + q = '*\ufe0f' + s.draw(q*(s.columns+1)) + self.ae(str(s.line(0)), q*(s.columns//2)) s = self.create_screen(cols=8) def widths(text, *widths): s.reset()