diff --git a/.github/actions/spelling/expect/expect.txt b/.github/actions/spelling/expect/expect.txt index 1bc205f6721..b5f048bc3c2 100644 --- a/.github/actions/spelling/expect/expect.txt +++ b/.github/actions/spelling/expect/expect.txt @@ -224,6 +224,7 @@ CFuzz cgscrn chafa changelist +chaof charinfo charset CHARSETINFO @@ -2763,6 +2764,9 @@ xes xff XFile XFORM +xin +xinchaof +xinxinchaof XManifest XMath XMFLOAT diff --git a/src/cascadia/TerminalControl/TSFInputControl.cpp b/src/cascadia/TerminalControl/TSFInputControl.cpp index 8cee7ffe154..7e9de19e99a 100644 --- a/src/cascadia/TerminalControl/TSFInputControl.cpp +++ b/src/cascadia/TerminalControl/TSFInputControl.cpp @@ -102,9 +102,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation _inputBuffer.clear(); _selection = {}; _activeTextStart = 0; - _editContext.NotifyFocusLeave(); _editContext.NotifyTextChanged({ 0, INT32_MAX }, 0, _selection); - _editContext.NotifyFocusEnter(); TextBlock().Text({}); } } @@ -375,7 +373,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation incomingText); _selection = args.NewSelection(); // GH#5054: Pressing backspace might move the caret before the _activeTextStart. - _activeTextStart = ::base::ClampMin(_activeTextStart, ::base::ClampedNumeric(range.StartCaretPosition)); + _activeTextStart = std::min(_activeTextStart, _inputBuffer.size()); // Emojis/Kaomojis/Symbols chosen through the IME without starting composition // will be sent straight through to the terminal. diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 8db8af3e8b3..b3e7fd1e26d 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -932,6 +932,19 @@ namespace winrt::Microsoft::Terminal::Control::implementation return; } + // GH#11479: TSF wants to be notified of any character input via ICoreTextEditContext::NotifyTextChanged(). + // TSF is built and tested around the idea that you inform it of any text changes that happen + // when it doesn't currently compose characters. For instance writing "xin chaof" with the + // Vietnamese IME should produce "xin chào". After writing "xin" it'll emit a composition + // completion event and we'll write "xin" to the shell. It now has no input focus and won't know + // about the whitespace. If you then write "chaof", it'll emit another composition completion + // event for "xinchaof" and the resulting output in the shell will finally read "xinxinchaof". + // A composition completion event technically doesn't mean that the completed text is now + // immutable after all. We could (and probably should) inform TSF of any input changes, + // but we technically aren't a text input field. The immediate solution was + // to simply force TSF to clear its text whenever we have input focus. + TSFInputControl().ClearBuffer(); + _HidePointerCursorHandlers(*this, nullptr); const auto ch = e.Character(); @@ -1193,12 +1206,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation { const auto window = CoreWindow::GetForCurrentThread(); - if (vkey == VK_ESCAPE || - vkey == VK_RETURN) - { - TSFInputControl().ClearBuffer(); - } - // If the terminal translated the key, mark the event as handled. // This will prevent the system from trying to get the character out // of it and sending us a CharacterReceived event.