[PR #15567] We've been trying to reach you about your WriteCharsLegacy's extended Emoji support #30673

Open
opened 2026-01-31 09:42:13 +00:00 by claunia · 0 comments
Owner

Original Pull Request: https://github.com/microsoft/terminal/pull/15567

State: closed
Merged: Yes


This is a complete rewrite of the old WriteCharsLegacy function
which is used when VT mode is disabled as well as for all interactive
console input handling on Windows. The previous code was almost
horrifying in some aspects as it first wrote the incoming text into a
local buffer, stripping/replacing any control characters. That's not
particular fast and never was. It's unknown why it was like that.

It also measured the width of each glyph to correctly determine the
cursor position and line wrapping. Presumably this used to work quite
well in the original console code, because it would then just copy
that local buffer into the destination text buffer, but with the
introduction of the broken and extremely slow OutputCellIterator
abstraction this would end up measuring all text twice and cause
disagreements between WriteCharsLegacy's idea of the cursor position
and OutputCellIterator's cursor position. Emoji input was basically
entirely broken. This PR fixes it by passing any incoming text
straight to the TextBuffer as well as by using its cursor positioning
facilities to correctly implement wrapping and backspace handling.

Backspacing over Emojis and an array of other aspects still don't work
correctly thanks to cmdline.cpp, but it works quite a lot better now.

Related to #8000
Closes #8839
Closes #10808

Validation Steps Performed

  • Printing various Unicode text
  • On an fgets() input line
    • Typing text works
    • Inserting text works anywhere
    • Ctrl+X is translated to ^X
    • Null is translated to ^@
      This was tested by hardcoding the OutputMode to 3 instead of 7.
    • Backspace only advances to start of the input
    • Backspace deletes the entire preceding tab
    • Backspace doesn't delete whitespace preceding a tab
    • Backspacing a force-wrapped wide glyph unwraps the line break
    • Backspacing ^X deletes both glyphs
    • Backspacing a force-wrapped tab deletes trailing whitespace
  • When executing
    fputs("foo: ", stdout);
    fgets(buffer, stdin);
    
    pressing tab and then backspace does not delete the whitespace
    that follows after the "foo:" string (= sOriginalXPosition).
**Original Pull Request:** https://github.com/microsoft/terminal/pull/15567 **State:** closed **Merged:** Yes --- This is a complete rewrite of the old `WriteCharsLegacy` function which is used when VT mode is disabled as well as for all interactive console input handling on Windows. The previous code was almost horrifying in some aspects as it first wrote the incoming text into a local buffer, stripping/replacing any control characters. That's not particular fast and never was. It's unknown why it was like that. It also measured the width of each glyph to correctly determine the cursor position and line wrapping. Presumably this used to work quite well in the original console code, because it would then just copy that local buffer into the destination text buffer, but with the introduction of the broken and extremely slow `OutputCellIterator` abstraction this would end up measuring all text twice and cause disagreements between `WriteCharsLegacy`'s idea of the cursor position and `OutputCellIterator`'s cursor position. Emoji input was basically entirely broken. This PR fixes it by passing any incoming text straight to the `TextBuffer` as well as by using its cursor positioning facilities to correctly implement wrapping and backspace handling. Backspacing over Emojis and an array of other aspects still don't work correctly thanks to cmdline.cpp, but it works quite a lot better now. Related to #8000 Closes #8839 Closes #10808 ## Validation Steps Performed * Printing various Unicode text ✅ * On an fgets() input line * Typing text works ✅ * Inserting text works anywhere ✅ * Ctrl+X is translated to ^X ✅ * Null is translated to ^@ ✅ This was tested by hardcoding the `OutputMode` to 3 instead of 7. * Backspace only advances to start of the input ✅ * Backspace deletes the entire preceding tab ✅ * Backspace doesn't delete whitespace preceding a tab ✅ * Backspacing a force-wrapped wide glyph unwraps the line break ✅ * Backspacing ^X deletes both glyphs ✅ * Backspacing a force-wrapped tab deletes trailing whitespace ✅ * When executing ```cpp fputs("foo: ", stdout); fgets(buffer, stdin); ``` pressing tab and then backspace does not delete the whitespace that follows after the "foo:" string (= `sOriginalXPosition`).
claunia added the pull-request label 2026-01-31 09:42:13 +00:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#30673