From 04281dde58a18f7f5f7b6d21e91d954a9c875b63 Mon Sep 17 00:00:00 2001 From: SadPencil Date: Thu, 23 Oct 2025 04:46:40 +0800 Subject: [PATCH 1/3] Revert "Improves IME ESC key handling" This reverts commit a3e835ddc86e80b4364778bdd9a1d56b2fa326a9. --- src/TSMapEditor/UI/IME/IMEHandler.cs | 45 +++++----------------------- 1 file changed, 8 insertions(+), 37 deletions(-) diff --git a/src/TSMapEditor/UI/IME/IMEHandler.cs b/src/TSMapEditor/UI/IME/IMEHandler.cs index b2bc5d70..083fcc83 100644 --- a/src/TSMapEditor/UI/IME/IMEHandler.cs +++ b/src/TSMapEditor/UI/IME/IMEHandler.cs @@ -42,11 +42,7 @@ protected set public bool CompositionEmpty => string.IsNullOrEmpty(_composition); - /// - /// Indicates whether an IME event has been received ever. Used to distinguish IME users from non-IME users. - /// protected bool IMEEventReceived = false; - protected bool LastActionIMEChatInput = true; private void OnCompositionChanged(string oldValue, string newValue) @@ -77,35 +73,22 @@ protected virtual void OnIMETextInput(char character) { //Debug.WriteLine($"IME: OnIMETextInput: {character} {(short)character}; IMEFocus is null? {IMEFocus == null}"); + IMEEventReceived = true; LastActionIMEChatInput = true; - // Handle ESC. The IME reports ESC key as a text input. - if (character == 27) + if (IMEFocus != null) { - LastActionIMEChatInput = false; - if (HandleEscapeKey()) + // Handle ESC + if (character == 27 && CompositionEmpty) { - // Do not return this ESC key back to the textbox if HandleEscapeKey returns true. - return; + IMEFocus.Text = string.Empty; } else { - // handleChatInput() method rejects the ESC message. Therefore, we need to manually clear the TextBox here. - if (IMEFocus != null) - { - // TODO: wrap this logic as a new action in RegisterXNATextBox(). This requires an API breaking change on XNAUI, and therefore left as a TODO. - IMEFocus.Text = string.Empty; - } - - return; + TextBoxHandleChatInputCallbacks.TryGetValue(IMEFocus, out var handleChatInput); + handleChatInput?.Invoke(character); } } - - if (IMEFocus != null) - { - TextBoxHandleChatInputCallbacks.TryGetValue(IMEFocus, out var handleChatInput); - handleChatInput?.Invoke(character); - } } public void SetIMETextInputRectangle(WindowManager manager) @@ -228,21 +211,9 @@ bool IIMEHandler.HandleEnterKey(XNATextBox sender) => false; bool IIMEHandler.HandleEscapeKey(XNATextBox sender) - { - return HandleEscapeKey(); - } - - private bool HandleEscapeKey() { //Debug.WriteLine($"IME: HandleEscapeKey: handled: {IMEEventReceived}"); - - // This method disables the ESC handling of the TextBox as long as the user has used IME. - // This is because IME users often use ESC to cancel composition, and even if currently the composition is empty, - // the user still expects ESC to cancel composition rather than deleting the whole sentence. - // For example, the user might mistakenly hit ESC key twice to cancel composition -- deleting the whole sentence is definitely a heavy punishment for such a small mistake. - - // Note: "!string.IsNullOrEmpty(Composition) =>IMEEventReceived" should hold, but just in case - return IMEEventReceived || !string.IsNullOrEmpty(Composition); + return IMEEventReceived; } void IIMEHandler.OnTextChanged(XNATextBox sender) { } From 11c253d5fb7805088659bdfa90f6fa1e5ab16eb4 Mon Sep 17 00:00:00 2001 From: SadPencil Date: Thu, 23 Oct 2025 04:46:43 +0800 Subject: [PATCH 2/3] Revert "Allow clearing text box with ESC if IME composition is empty" This reverts commit 88185ee8f190d2c69829c853f4603d2f7f0a1120. --- src/TSMapEditor/UI/IME/IMEHandler.cs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/TSMapEditor/UI/IME/IMEHandler.cs b/src/TSMapEditor/UI/IME/IMEHandler.cs index 083fcc83..ce6d92cb 100644 --- a/src/TSMapEditor/UI/IME/IMEHandler.cs +++ b/src/TSMapEditor/UI/IME/IMEHandler.cs @@ -78,16 +78,8 @@ protected virtual void OnIMETextInput(char character) if (IMEFocus != null) { - // Handle ESC - if (character == 27 && CompositionEmpty) - { - IMEFocus.Text = string.Empty; - } - else - { - TextBoxHandleChatInputCallbacks.TryGetValue(IMEFocus, out var handleChatInput); - handleChatInput?.Invoke(character); - } + TextBoxHandleChatInputCallbacks.TryGetValue(IMEFocus, out var handleChatInput); + handleChatInput?.Invoke(character); } } From 3238170b7ce5d65764c9944069d4ff2332841bcb Mon Sep 17 00:00:00 2001 From: SadPencil Date: Thu, 23 Oct 2025 04:49:20 +0800 Subject: [PATCH 3/3] Improve IME handling for ESC key --- src/TSMapEditor/UI/IME/IMEHandler.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/TSMapEditor/UI/IME/IMEHandler.cs b/src/TSMapEditor/UI/IME/IMEHandler.cs index ce6d92cb..26ada1a7 100644 --- a/src/TSMapEditor/UI/IME/IMEHandler.cs +++ b/src/TSMapEditor/UI/IME/IMEHandler.cs @@ -42,7 +42,11 @@ protected set public bool CompositionEmpty => string.IsNullOrEmpty(_composition); + /// + /// Indicates whether an IME event has been received ever. Used to distinguish IME users from non-IME users. + /// protected bool IMEEventReceived = false; + protected bool LastActionIMEChatInput = true; private void OnCompositionChanged(string oldValue, string newValue) @@ -73,7 +77,6 @@ protected virtual void OnIMETextInput(char character) { //Debug.WriteLine($"IME: OnIMETextInput: {character} {(short)character}; IMEFocus is null? {IMEFocus == null}"); - IMEEventReceived = true; LastActionIMEChatInput = true; if (IMEFocus != null) @@ -205,7 +208,15 @@ bool IIMEHandler.HandleEnterKey(XNATextBox sender) bool IIMEHandler.HandleEscapeKey(XNATextBox sender) { //Debug.WriteLine($"IME: HandleEscapeKey: handled: {IMEEventReceived}"); - return IMEEventReceived; + + // This method disables the ESC handling of the TextBox as long as the user has ever used IME. + // This is because IME users often use ESC to cancel composition. Even if currently the composition is empty, + // the user still expects ESC to cancel composition rather than deleting the whole sentence. + // For example, the user might mistakenly hit ESC key twice to cancel composition -- deleting the whole sentence is definitely a heavy punishment for such a small mistake. + + // Note: "!CompositionEmpty => IMEEventReceived" should hold, but just in case + + return IMEEventReceived || !CompositionEmpty; } void IIMEHandler.OnTextChanged(XNATextBox sender) { }