From 33f0e42063758cf409b2149f64281f4fa4d96b62 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Mon, 17 Jan 2022 16:22:08 +0100 Subject: [PATCH] win32: Don't raise TextInput event when KeyDown was handled. On win32, returning handled from `WM_KEYDOWN` doesn't automatically prevent a `WM_CHAR` message, resulting in #5849. Fix this by setting a flag after `WM_KEYDOWN` is handled which will make the following `WM_CHAR` message be ignored. This is the second attempt at fixing this after it was decided that https://github.com/AvaloniaUI/Avalonia/pull/7351 was not the right approach. Fixes #5849 --- src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs | 13 +++++++++++-- src/Windows/Avalonia.Win32/WindowImpl.cs | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs index 89d5009da5..88a0744e3e 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs @@ -151,8 +151,8 @@ namespace Avalonia.Win32 } case WindowsMessage.WM_CHAR: { - // Ignore control chars - if (ToInt32(wParam) >= 32) + // Ignore control chars and chars that were handled in WM_KEYDOWN. + if (ToInt32(wParam) >= 32 && !_ignoreWmChar) { e = new RawTextInputEventArgs(WindowsKeyboardDevice.Instance, timestamp, _owner, new string((char)ToInt32(wParam), 1)); @@ -519,6 +519,15 @@ namespace Avalonia.Win32 { Input(e); + if ((WindowsMessage)msg == WindowsMessage.WM_KEYDOWN) + { + // Handling a WM_KEYDOWN message should cause the subsequent WM_CHAR message to + // be ignored. This should be safe to do as WM_CHAR should only be produced in + // response to the call to TranslateMessage/DispatchMessage after a WM_KEYDOWN + // is handled. + _ignoreWmChar = e.Handled; + } + if (e.Handled) { return IntPtr.Zero; diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 4c3165eaf9..e4f5268285 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -90,6 +90,7 @@ namespace Avalonia.Win32 private bool _shown; private bool _hiddenWindowIsParent; private uint _langid; + private bool _ignoreWmChar; public WindowImpl() {