Skip to content

Commit cff48c7

Browse files
[vtbackend] Screen: Fixes screen destruction on sibling cells when overwriting wide characters
Signed-off-by: Christian Parpart <[email protected]>
1 parent 790884b commit cff48c7

File tree

3 files changed

+16
-23
lines changed

3 files changed

+16
-23
lines changed

metainfo.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@
111111
<li>Fixes variable fonts loading</li>
112112
<li>Fixes Command modifier for input mappings, such as Command+C or Command+V on on MacOS (#1379).</li>
113113
<li>Fixes CSIu encoding of shift modifier produced characters (#1373).</li>
114+
<li>Fixes screen destruction on sibling cells when overwriting wide characters, such as Emoji, Kanji, etc.</li>
114115
<li>Changes VT sequence `DECSCUSR` (`CSI ? 0 SP q` and `CSI ? SP q`) to reset to user-configured cursor style (#1377).</li>
115116
<li>Remove `contour-latest` terminfo file. Please use `contour` terminfo instead.</li>
116117
<li>Adds `Command` as modifier to input mappings on MacOS to work along with `Meta` for convenience reasons (#1379).</li>

src/vtbackend/Screen.cpp

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -566,8 +566,7 @@ void Screen<Cell>::writeTextInternal(char32_t sourceCodepoint)
566566
else
567567
{
568568
auto const extendedWidth = usePreviousCell().appendCharacter(codepoint);
569-
if (extendedWidth > 0)
570-
clearAndAdvance(extendedWidth);
569+
clearAndAdvance(0, extendedWidth);
571570
_terminal->markCellDirty(_lastCursorPosition);
572571
}
573572

@@ -592,17 +591,19 @@ void Screen<Cell>::writeCharToCurrentAndAdvance(char32_t codepoint) noexcept
592591
{
593592
// Erase the left half of the wide char.
594593
Cell& prevCell = line.useCellAt(_cursor.position.column - 1);
595-
prevCell.reset();
594+
prevCell.reset(_cursor.graphicsRendition);
596595
}
597596

597+
auto const oldWidth = cell.width();
598+
598599
cell.write(_cursor.graphicsRendition,
599600
codepoint,
600601
static_cast<uint8_t>(unicode::width(codepoint)),
601602
_cursor.hyperlink);
602603

603604
_lastCursorPosition = _cursor.position;
604605

605-
clearAndAdvance(cell.width());
606+
clearAndAdvance(oldWidth, cell.width());
606607

607608
// TODO: maybe move selector API up? So we can make this call conditional,
608609
// and only call it when something is selected?
@@ -614,32 +615,23 @@ void Screen<Cell>::writeCharToCurrentAndAdvance(char32_t codepoint) noexcept
614615

615616
template <typename Cell>
616617
CRISPY_REQUIRES(CellConcept<Cell>)
617-
void Screen<Cell>::clearAndAdvance(int offset) noexcept
618+
void Screen<Cell>::clearAndAdvance(int oldWidth, int newWidth) noexcept
618619
{
619-
if (offset == 0)
620-
return;
621-
622620
bool const cursorInsideMargin =
623621
_terminal->isModeEnabled(DECMode::LeftRightMargin) && isCursorInsideMargins();
624622
auto const cellsAvailable = cursorInsideMargin ? *(margin().horizontal.to - _cursor.position.column) - 1
625623
: *pageSize().columns - *_cursor.position.column - 1;
626-
auto const n = min(offset, cellsAvailable);
627624

628-
if (n == offset)
629-
{
630-
_cursor.position.column++;
631-
auto& line = currentLine();
632-
for (int i = 1; i < n; ++i) // XXX It's not even clear if other TEs are doing that, too.
633-
{
634-
line.useCellAt(_cursor.position.column)
635-
.reset(_cursor.graphicsRendition.with(CellFlag::WideCharContinuation), _cursor.hyperlink);
636-
_cursor.position.column++;
637-
}
638-
}
625+
auto const sgr = newWidth > 1 ? _cursor.graphicsRendition.with(CellFlag::WideCharContinuation)
626+
: _cursor.graphicsRendition;
627+
auto& line = currentLine();
628+
for (int i = 1; i < min(max(oldWidth, newWidth), cellsAvailable); ++i)
629+
line.useCellAt(_cursor.position.column + i).reset(sgr, _cursor.hyperlink);
630+
631+
if (newWidth == min(newWidth, cellsAvailable))
632+
_cursor.position.column += ColumnOffset::cast_from(newWidth);
639633
else if (_cursor.autoWrap)
640-
{
641634
_cursor.wrapPending = true;
642-
}
643635
}
644636

645637
template <typename Cell>

src/vtbackend/Screen.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ class Screen final: public ScreenBase, public capabilities::StaticDatabase
616616
void linefeed(ColumnOffset column);
617617

618618
void writeCharToCurrentAndAdvance(char32_t codepoint) noexcept;
619-
void clearAndAdvance(int offset) noexcept;
619+
void clearAndAdvance(int oldWidth, int newWidth) noexcept;
620620

621621
void scrollUp(LineCount n, GraphicsAttributes sgr, Margin margin);
622622
void scrollUp(LineCount n, Margin margin);

0 commit comments

Comments
 (0)