diff --git a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs index 89d5009da54..88a0744e3ee 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs @@ -151,8 +151,8 @@ protected virtual unsafe IntPtr AppWndProc(IntPtr hWnd, uint msg, IntPtr wParam, } 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 @@ protected virtual unsafe IntPtr AppWndProc(IntPtr hWnd, uint msg, IntPtr wParam, { 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 4c3165eaf90..e4f52682853 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -90,6 +90,7 @@ public partial class WindowImpl : IWindowImpl, EglGlPlatformSurface.IEglWindowGl private bool _shown; private bool _hiddenWindowIsParent; private uint _langid; + private bool _ignoreWmChar; public WindowImpl() {