diff --git a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs index 70f2c1a4c5..25eb54104e 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs @@ -180,11 +180,12 @@ namespace Avalonia.Win32 return LoadIcon(requestIcon, requestDpi)?.Handle ?? default; case WindowsMessage.WM_KEYDOWN: + e = TryCreateRawKeyEventArgs(RawKeyEventType.KeyDown, timestamp, wParam, lParam, true); + break; + case WindowsMessage.WM_SYSKEYDOWN: - { - e = TryCreateRawKeyEventArgs(RawKeyEventType.KeyDown, timestamp, wParam, lParam); - break; - } + e = TryCreateRawKeyEventArgs(RawKeyEventType.KeyDown, timestamp, wParam, lParam, false); + break; case WindowsMessage.WM_SYSCOMMAND: // Disable system handling of Alt/F10 menu keys. @@ -199,11 +200,15 @@ namespace Avalonia.Win32 } case WindowsMessage.WM_KEYUP: + e = TryCreateRawKeyEventArgs(RawKeyEventType.KeyUp, timestamp, wParam, lParam, true); + _ignoreWmChar = false; + break; + case WindowsMessage.WM_SYSKEYUP: - { - e = TryCreateRawKeyEventArgs(RawKeyEventType.KeyUp, timestamp, wParam, lParam); - break; - } + e = TryCreateRawKeyEventArgs(RawKeyEventType.KeyUp, timestamp, wParam, lParam, false); + _ignoreWmChar = false; + break; + case WindowsMessage.WM_CHAR: { if (Imm32InputMethod.Current.IsComposing) @@ -219,6 +224,7 @@ namespace Avalonia.Win32 e = new RawTextInputEventArgs(WindowsKeyboardDevice.Instance, timestamp, Owner, text); } + _ignoreWmChar = false; break; } @@ -881,7 +887,7 @@ namespace Avalonia.Win32 // is handled. _ignoreWmChar = e.Handled; } - } + } if (s_intermediatePointsPooledList.Count > 0) { @@ -1314,13 +1320,16 @@ namespace Avalonia.Win32 return modifiers; } - private RawKeyEventArgs? TryCreateRawKeyEventArgs(RawKeyEventType eventType, ulong timestamp, IntPtr wParam, IntPtr lParam) + private RawKeyEventArgs? TryCreateRawKeyEventArgs(RawKeyEventType eventType, ulong timestamp, IntPtr wParam, IntPtr lParam, bool useKeySymbol) { var virtualKey = ToInt32(wParam); var keyData = ToInt32(lParam); var key = KeyInterop.KeyFromVirtualKey(virtualKey, keyData); var physicalKey = KeyInterop.PhysicalKeyFromVirtualKey(virtualKey, keyData); - var keySymbol = KeyInterop.GetKeySymbol(virtualKey, keyData); + + // Avoid calling GetKeySymbol() for WM_SYSKEYDOWN/UP: + // it ultimately calls User32!ToUnicodeEx, which messes up the keyboard state in this case. + var keySymbol = useKeySymbol ? KeyInterop.GetKeySymbol(virtualKey, keyData) : null; if (key == Key.None && physicalKey == PhysicalKey.None && string.IsNullOrWhiteSpace(keySymbol)) return null;