Fix UTF-16 surrogate pair handling on Windows input (#1160)

Fix(Windows): Correctly handle UTF-16 surrogate pairs for non-BMP input.

Co-authored-by: ArthurSonzogni <sonzogniarthur@gmail.com>
This commit is contained in:
739C1AE2
2025-12-06 17:59:43 +08:00
committed by GitHub
parent d9c62b3678
commit 183a426efa
2 changed files with 11 additions and 2 deletions

View File

@@ -37,6 +37,9 @@ Next
output. Thanks @zozowell in #1064. output. Thanks @zozowell in #1064.
- Fix vertical `ftxui::Slider`. The "up" key was previously decreasing the - Fix vertical `ftxui::Slider`. The "up" key was previously decreasing the
value. Thanks @its-pablo in #1093 for reporting the issue. value. Thanks @its-pablo in #1093 for reporting the issue.
- Fix Windows UTF-16 key input handling. Emoji and other code points outside the
Basic Multilingual Plane (BMP) are now correctly processed. Thanks @739C1AE2
in #1160 for fixing the issue.
### Dom ### Dom
- Fix integer overflow in `ComputeShrinkHard`. Thanks @its-pablo in #1137 for - Fix integer overflow in `ComputeShrinkHard`. Thanks @its-pablo in #1137 for

View File

@@ -1098,6 +1098,7 @@ void ScreenInteractive::FetchTerminalEvents() {
// Convert the input events to FTXUI events. // Convert the input events to FTXUI events.
// For each event, we call the terminal input parser to convert it to // For each event, we call the terminal input parser to convert it to
// Event. // Event.
std::wstring wstring;
for (const auto& r : records) { for (const auto& r : records) {
switch (r.EventType) { switch (r.EventType) {
case KEY_EVENT: { case KEY_EVENT: {
@@ -1106,11 +1107,16 @@ void ScreenInteractive::FetchTerminalEvents() {
if (key_event.bKeyDown == FALSE) { if (key_event.bKeyDown == FALSE) {
continue; continue;
} }
std::wstring wstring; const wchar_t wc = key_event.uChar.UnicodeChar;
wstring += key_event.uChar.UnicodeChar; wstring += wc;
if (wc >= 0xd800 && wc <= 0xdbff) {
// Wait for the Low Surrogate to arrive in the next record.
continue;
}
for (auto it : to_string(wstring)) { for (auto it : to_string(wstring)) {
internal_->terminal_input_parser.Add(it); internal_->terminal_input_parser.Add(it);
} }
wstring.clear();
} break; } break;
case WINDOW_BUFFER_SIZE_EVENT: case WINDOW_BUFFER_SIZE_EVENT:
Post(Event::Special({0})); Post(Event::Special({0}));