From c22b71aa50cc0b74848be1db1723376a736f7b3a Mon Sep 17 00:00:00 2001 From: Yatao Li Date: Thu, 6 Aug 2020 17:41:32 +0800 Subject: [PATCH 1/3] update build.ps1 to put downloaded dotnet in PATH --- build.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.ps1 b/build.ps1 index 57e2f800758..3672e82d3bd 100644 --- a/build.ps1 +++ b/build.ps1 @@ -62,6 +62,8 @@ else { } else { ExecSafe { & $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion -NoPath } } + + $env:PATH="$DotNetDirectory;$env:PATH" } Write-Output "Microsoft (R) .NET Core SDK version $(& $env:DOTNET_EXE --version)" From 8109684fe8b83906c37619354d72820327ea8423 Mon Sep 17 00:00:00 2001 From: Yatao Li Date: Thu, 6 Aug 2020 23:19:16 +0800 Subject: [PATCH 2/3] add mapped key string to raw key event --- .../Remote/Server/RemoteServerTopLevelImpl.cs | 1 + src/Avalonia.Headless/HeadlessWindowImpl.cs | 8 ++--- src/Avalonia.Headless/IHeadlessWindow.cs | 4 +-- src/Avalonia.Input/Raw/RawKeyEventArgs.cs | 6 +++- src/Avalonia.Native/WindowImplBase.cs | 4 ++- src/Avalonia.Remote.Protocol/InputMessages.cs | 1 + src/Avalonia.X11/X11Window.cs | 33 ++++++++++--------- .../Wpf/WpfTopLevelImpl.cs | 4 +-- .../Avalonia.Win32/Input/KeyInterop.cs | 1 + .../Avalonia.Win32/WindowImpl.AppWndProc.cs | 16 +++++---- .../TopLevelTests.cs | 3 +- .../KeyboardDeviceTests.cs | 4 +-- 12 files changed, 50 insertions(+), 35 deletions(-) diff --git a/src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs b/src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs index 931c27c5752..e556560c51f 100644 --- a/src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs +++ b/src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs @@ -230,6 +230,7 @@ protected virtual void OnMessage(IAvaloniaRemoteTransportConnection transport, o InputRoot, key.IsDown ? RawKeyEventType.KeyDown : RawKeyEventType.KeyUp, (Key)key.Key, + key.MappedKey, GetAvaloniaRawInputModifiers(key.Modifiers))); }, DispatcherPriority.Input); } diff --git a/src/Avalonia.Headless/HeadlessWindowImpl.cs b/src/Avalonia.Headless/HeadlessWindowImpl.cs index 8f4fa5e3041..22c09bf78e8 100644 --- a/src/Avalonia.Headless/HeadlessWindowImpl.cs +++ b/src/Avalonia.Headless/HeadlessWindowImpl.cs @@ -247,14 +247,14 @@ public IRef GetLastRenderedFrame() public AcrylicPlatformCompensationLevels AcrylicCompensationLevels => new AcrylicPlatformCompensationLevels(1, 1, 1); - void IHeadlessWindow.KeyPress(Key key, RawInputModifiers modifiers) + void IHeadlessWindow.KeyPress(Key key, string mappedKey, RawInputModifiers modifiers) { - Input?.Invoke(new RawKeyEventArgs(_keyboard, Timestamp, InputRoot, RawKeyEventType.KeyDown, key, modifiers)); + Input?.Invoke(new RawKeyEventArgs(_keyboard, Timestamp, InputRoot, RawKeyEventType.KeyDown, key, mappedKey, modifiers)); } - void IHeadlessWindow.KeyRelease(Key key, RawInputModifiers modifiers) + void IHeadlessWindow.KeyRelease(Key key, string mappedKey, RawInputModifiers modifiers) { - Input?.Invoke(new RawKeyEventArgs(_keyboard, Timestamp, InputRoot, RawKeyEventType.KeyUp, key, modifiers)); + Input?.Invoke(new RawKeyEventArgs(_keyboard, Timestamp, InputRoot, RawKeyEventType.KeyUp, key, mappedKey, modifiers)); } void IHeadlessWindow.MouseDown(Point point, int button, RawInputModifiers modifiers) diff --git a/src/Avalonia.Headless/IHeadlessWindow.cs b/src/Avalonia.Headless/IHeadlessWindow.cs index 282662f98ba..49934caf48b 100644 --- a/src/Avalonia.Headless/IHeadlessWindow.cs +++ b/src/Avalonia.Headless/IHeadlessWindow.cs @@ -8,8 +8,8 @@ namespace Avalonia.Headless public interface IHeadlessWindow { IRef GetLastRenderedFrame(); - void KeyPress(Key key, RawInputModifiers modifiers); - void KeyRelease(Key key, RawInputModifiers modifiers); + void KeyPress(Key key, string mappedKey, RawInputModifiers modifiers); + void KeyRelease(Key key, string mappedKey, RawInputModifiers modifiers); void MouseDown(Point point, int button, RawInputModifiers modifiers = RawInputModifiers.None); void MouseMove(Point point, RawInputModifiers modifiers = RawInputModifiers.None); void MouseUp(Point point, int button, RawInputModifiers modifiers = RawInputModifiers.None); diff --git a/src/Avalonia.Input/Raw/RawKeyEventArgs.cs b/src/Avalonia.Input/Raw/RawKeyEventArgs.cs index 6ed073d006d..396a042df50 100644 --- a/src/Avalonia.Input/Raw/RawKeyEventArgs.cs +++ b/src/Avalonia.Input/Raw/RawKeyEventArgs.cs @@ -13,16 +13,20 @@ public RawKeyEventArgs( ulong timestamp, IInputRoot root, RawKeyEventType type, - Key key, RawInputModifiers modifiers) + Key key, + string mappedKey, RawInputModifiers modifiers) : base(device, timestamp, root) { Key = key; + MappedKey = mappedKey; Type = type; Modifiers = modifiers; } public Key Key { get; set; } + public string MappedKey { get; set; } + public RawInputModifiers Modifiers { get; set; } public RawKeyEventType Type { get; set; } diff --git a/src/Avalonia.Native/WindowImplBase.cs b/src/Avalonia.Native/WindowImplBase.cs index 4b13666eddb..56135924b54 100644 --- a/src/Avalonia.Native/WindowImplBase.cs +++ b/src/Avalonia.Native/WindowImplBase.cs @@ -259,7 +259,9 @@ public bool RawKeyEvent(AvnRawKeyEventType type, uint timeStamp, AvnInputModifie { Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1); - var args = new RawKeyEventArgs(_keyboard, timeStamp, _inputRoot, (RawKeyEventType)type, (Key)key, (RawInputModifiers)modifiers); + var args = new RawKeyEventArgs(_keyboard, timeStamp, _inputRoot, (RawKeyEventType)type, + (Key)key, null, // TODO mapped key + (RawInputModifiers)modifiers); Input?.Invoke(args); diff --git a/src/Avalonia.Remote.Protocol/InputMessages.cs b/src/Avalonia.Remote.Protocol/InputMessages.cs index 6b8cdebbcc9..d4b591fd76e 100644 --- a/src/Avalonia.Remote.Protocol/InputMessages.cs +++ b/src/Avalonia.Remote.Protocol/InputMessages.cs @@ -73,6 +73,7 @@ public class KeyEventMessage : InputEventMessageBase { public bool IsDown { get; set; } public Key Key { get; set; } + public string MappedKey { get; set; } } [AvaloniaRemoteMessageGuid("C174102E-7405-4594-916F-B10B8248A17D")] diff --git a/src/Avalonia.X11/X11Window.cs b/src/Avalonia.X11/X11Window.cs index 0c0b942bcd8..6474edf76e8 100644 --- a/src/Avalonia.X11/X11Window.cs +++ b/src/Avalonia.X11/X11Window.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Diagnostics; using System.Linq; @@ -511,25 +512,27 @@ void OnEventSync(XEvent ev) && key > X11Key.Num_Lock && key <= X11Key.KP_9) key = (X11Key)XKeycodeToKeysym(_x11.Display, ev.KeyEvent.keycode, index ? 0 : 1).ToInt32(); - + var len = Xutf8LookupString(_xic, ref ev, buffer, 40, out _, out _); + string mappedKey = null; + if (len != 0) + { + mappedKey = Encoding.UTF8.GetString(buffer, len); + if (mappedKey.Length == 1) + { + if (mappedKey[0] < ' ' || mappedKey[0] == 0x7f) //Control codes or DEL + mappedKey = null; + } + } + ScheduleInput(new RawKeyEventArgs(_keyboard, (ulong)ev.KeyEvent.time.ToInt64(), _inputRoot, ev.type == XEventName.KeyPress ? RawKeyEventType.KeyDown : RawKeyEventType.KeyUp, - X11KeyTransform.ConvertKey(key), TranslateModifiers(ev.KeyEvent.state)), ref ev); + X11KeyTransform.ConvertKey(key), mappedKey, + TranslateModifiers(ev.KeyEvent.state)), ref ev); - if (ev.type == XEventName.KeyPress) + if (ev.type == XEventName.KeyPress && mappedKey != null) { - var len = Xutf8LookupString(_xic, ref ev, buffer, 40, out _, out _); - if (len != 0) - { - var text = Encoding.UTF8.GetString(buffer, len); - if (text.Length == 1) - { - if (text[0] < ' ' || text[0] == 0x7f) //Control codes or DEL - return; - } - ScheduleInput(new RawTextInputEventArgs(_keyboard, (ulong)ev.KeyEvent.time.ToInt64(), _inputRoot, text), - ref ev); - } + ScheduleInput(new RawTextInputEventArgs(_keyboard, (ulong)ev.KeyEvent.time.ToInt64(), _inputRoot, mappedKey), + ref ev); } } } diff --git a/src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs b/src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs index 3467a33d161..c502bd25cd8 100644 --- a/src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs +++ b/src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs @@ -214,12 +214,12 @@ protected override void OnMouseWheel(MouseWheelEventArgs e) => protected override void OnKeyDown(KeyEventArgs e) => _ttl.Input?.Invoke(new RawKeyEventArgs(_keyboard, (uint) e.Timestamp, _inputRoot, RawKeyEventType.KeyDown, - (Key) e.Key, + (Key) e.Key, null, // TODO mapped key, should be WindowsKeyboardDevice.Instance.StringFromVirtualKey(vk) GetModifiers(null))); protected override void OnKeyUp(KeyEventArgs e) => _ttl.Input?.Invoke(new RawKeyEventArgs(_keyboard, (uint)e.Timestamp, _inputRoot, RawKeyEventType.KeyUp, - (Key)e.Key, + (Key) e.Key, null, // TODO mapped key GetModifiers(null))); protected override void OnTextInput(TextCompositionEventArgs e) diff --git a/src/Windows/Avalonia.Win32/Input/KeyInterop.cs b/src/Windows/Avalonia.Win32/Input/KeyInterop.cs index f5b2d462ab6..1dec5196bd6 100644 --- a/src/Windows/Avalonia.Win32/Input/KeyInterop.cs +++ b/src/Windows/Avalonia.Win32/Input/KeyInterop.cs @@ -436,5 +436,6 @@ public static int VirtualKeyFromKey(Key key) return result; } + } } diff --git a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs index 25a34561fc4..2d668672a20 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs @@ -103,13 +103,14 @@ protected virtual unsafe IntPtr AppWndProc(IntPtr hWnd, uint msg, IntPtr wParam, case WindowsMessage.WM_KEYDOWN: case WindowsMessage.WM_SYSKEYDOWN: { - e = new RawKeyEventArgs( - WindowsKeyboardDevice.Instance, - timestamp, - _owner, - RawKeyEventType.KeyDown, - KeyInterop.KeyFromVirtualKey(ToInt32(wParam), ToInt32(lParam)), - WindowsKeyboardDevice.Instance.Modifiers); + e = new RawKeyEventArgs( + WindowsKeyboardDevice.Instance, + timestamp, + _owner, + RawKeyEventType.KeyDown, + KeyInterop.KeyFromVirtualKey(ToInt32(wParam), ToInt32(lParam)), + WindowsKeyboardDevice.Instance.StringFromVirtualKey((uint)ToInt32(wParam)), + WindowsKeyboardDevice.Instance.Modifiers); break; } @@ -128,6 +129,7 @@ protected virtual unsafe IntPtr AppWndProc(IntPtr hWnd, uint msg, IntPtr wParam, _owner, RawKeyEventType.KeyUp, KeyInterop.KeyFromVirtualKey(ToInt32(wParam), ToInt32(lParam)), + WindowsKeyboardDevice.Instance.StringFromVirtualKey((uint)ToInt32(wParam)), WindowsKeyboardDevice.Instance.Modifiers); break; } diff --git a/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs b/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs index 6b30aed257b..bbde9c02982 100644 --- a/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs @@ -207,7 +207,8 @@ public void Impl_Input_Should_Pass_Input_To_InputManager() 0, target, RawKeyEventType.KeyDown, - Key.A, RawInputModifiers.None); + Key.A, "a", + RawInputModifiers.None); impl.Object.Input(input); inputManagerMock.Verify(x => x.ProcessInput(input)); diff --git a/tests/Avalonia.Input.UnitTests/KeyboardDeviceTests.cs b/tests/Avalonia.Input.UnitTests/KeyboardDeviceTests.cs index df0a077c7f4..4be51386e6b 100644 --- a/tests/Avalonia.Input.UnitTests/KeyboardDeviceTests.cs +++ b/tests/Avalonia.Input.UnitTests/KeyboardDeviceTests.cs @@ -19,7 +19,7 @@ public void Keypresses_Should_Be_Sent_To_Root_If_No_Focused_Element() 0, root.Object, RawKeyEventType.KeyDown, - Key.A, + Key.A, "a", RawInputModifiers.None)); root.Verify(x => x.RaiseEvent(It.IsAny())); @@ -43,7 +43,7 @@ public void Keypresses_Should_Be_Sent_To_Focused_Element() 0, root, RawKeyEventType.KeyDown, - Key.A, + Key.A, "a", RawInputModifiers.None)); focused.Verify(x => x.RaiseEvent(It.IsAny())); From 97c4da3a40a772e9190994ce8262c3bb2bddb9d2 Mon Sep 17 00:00:00 2001 From: Yatao Li Date: Fri, 7 Aug 2020 00:11:08 +0800 Subject: [PATCH 3/3] add mapped key to KeyEventArgs --- src/Avalonia.Input/KeyEventArgs.cs | 2 ++ src/Avalonia.Input/KeyboardDevice.cs | 1 + src/Avalonia.Input/Raw/RawKeyEventArgs.cs | 9 +++++++++ 3 files changed, 12 insertions(+) diff --git a/src/Avalonia.Input/KeyEventArgs.cs b/src/Avalonia.Input/KeyEventArgs.cs index 267376262be..9db3dd06a91 100644 --- a/src/Avalonia.Input/KeyEventArgs.cs +++ b/src/Avalonia.Input/KeyEventArgs.cs @@ -9,6 +9,8 @@ public class KeyEventArgs : RoutedEventArgs public Key Key { get; set; } + public string MappedKey { get; set; } + [Obsolete("Use KeyModifiers")] public InputModifiers Modifiers => (InputModifiers)KeyModifiers; public KeyModifiers KeyModifiers { get; set; } diff --git a/src/Avalonia.Input/KeyboardDevice.cs b/src/Avalonia.Input/KeyboardDevice.cs index 0321b0bdf36..f662307e13c 100644 --- a/src/Avalonia.Input/KeyboardDevice.cs +++ b/src/Avalonia.Input/KeyboardDevice.cs @@ -85,6 +85,7 @@ public void ProcessRawEvent(RawInputEventArgs e) RoutedEvent = routedEvent, Device = this, Key = keyInput.Key, + MappedKey = keyInput.MappedKey, KeyModifiers = KeyModifiersUtils.ConvertToKey(keyInput.Modifiers), Source = element, }; diff --git a/src/Avalonia.Input/Raw/RawKeyEventArgs.cs b/src/Avalonia.Input/Raw/RawKeyEventArgs.cs index 396a042df50..59d084fed04 100644 --- a/src/Avalonia.Input/Raw/RawKeyEventArgs.cs +++ b/src/Avalonia.Input/Raw/RawKeyEventArgs.cs @@ -23,6 +23,15 @@ public RawKeyEventArgs( Modifiers = modifiers; } + public RawKeyEventArgs( + IKeyboardDevice device, + ulong timestamp, + IInputRoot root, + RawKeyEventType type, + Key key, + RawInputModifiers modifiers) + : this(device, timestamp, root, type, key, null, modifiers) { } + public Key Key { get; set; } public string MappedKey { get; set; }