From 3d4a2781b0654cf7e2f4a488c510d3bb624ac89f Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Sat, 10 Aug 2019 10:21:26 +0300 Subject: [PATCH] Switched key events to use KeyModifiers --- .../Platform/InProcessDragSource.cs | 16 ++++++---- .../Remote/Server/RemoteServerTopLevelImpl.cs | 6 +++- src/Avalonia.Diagnostics/DevTools.xaml.cs | 4 +-- src/Avalonia.Input/IKeyboardDevice.cs | 31 ++++++++++++++++++- src/Avalonia.Input/KeyEventArgs.cs | 5 ++- src/Avalonia.Input/KeyGesture.cs | 9 +++++- src/Avalonia.Input/KeyboardDevice.cs | 2 +- src/Avalonia.Input/Raw/RawKeyEventArgs.cs | 4 +-- src/Avalonia.Native/WindowImplBase.cs | 2 +- src/Avalonia.X11/X11Window.cs | 3 +- .../Input/WindowsKeyboardDevice.cs | 1 + src/Windows/Avalonia.Win32/WindowImpl.cs | 4 +-- .../TextBoxTests.cs | 30 +++++++++--------- .../TopLevelTests.cs | 2 +- .../TreeViewTests.cs | 6 ++-- 15 files changed, 87 insertions(+), 38 deletions(-) diff --git a/src/Avalonia.Controls/Platform/InProcessDragSource.cs b/src/Avalonia.Controls/Platform/InProcessDragSource.cs index 85916bcdd0..d4df41d2f2 100644 --- a/src/Avalonia.Controls/Platform/InProcessDragSource.cs +++ b/src/Avalonia.Controls/Platform/InProcessDragSource.cs @@ -57,11 +57,15 @@ namespace Avalonia.Platform } - private DragDropEffects RaiseEventAndUpdateCursor(RawDragEventType type, IInputElement root, Point pt, InputModifiers modifiers) + private DragDropEffects RaiseEventAndUpdateCursor(RawDragEventType type, IInputElement root, Point pt, + InputModifiers modifiers) + => RaiseEventAndUpdateCursor(type, root, pt, (RawInputModifiers)modifiers); + + private DragDropEffects RaiseEventAndUpdateCursor(RawDragEventType type, IInputElement root, Point pt, RawInputModifiers modifiers) { _lastPosition = pt; - RawDragEvent rawEvent = new RawDragEvent(_dragDrop, type, root, pt, _draggedData, _allowedEffects, modifiers); + RawDragEvent rawEvent = new RawDragEvent(_dragDrop, type, root, pt, _draggedData, _allowedEffects, (InputModifiers)modifiers); var tl = root.GetSelfAndVisualAncestors().OfType().FirstOrDefault(); tl.PlatformImpl?.Input(rawEvent); @@ -70,13 +74,13 @@ namespace Avalonia.Platform return effect; } - private DragDropEffects GetPreferredEffect(DragDropEffects effect, InputModifiers modifiers) + private DragDropEffects GetPreferredEffect(DragDropEffects effect, RawInputModifiers modifiers) { if (effect == DragDropEffects.Copy || effect == DragDropEffects.Move || effect == DragDropEffects.Link || effect == DragDropEffects.None) return effect; // No need to check for the modifiers. - if (effect.HasFlag(DragDropEffects.Link) && modifiers.HasFlag(InputModifiers.Alt)) + if (effect.HasFlag(DragDropEffects.Link) && modifiers.HasFlag(RawInputModifiers.Alt)) return DragDropEffects.Link; - if (effect.HasFlag(DragDropEffects.Copy) && modifiers.HasFlag(InputModifiers.Control)) + if (effect.HasFlag(DragDropEffects.Copy) && modifiers.HasFlag(RawInputModifiers.Control)) return DragDropEffects.Copy; return DragDropEffects.Move; } @@ -132,7 +136,7 @@ namespace Avalonia.Platform private void CancelDragging() { if (_lastRoot != null) - RaiseEventAndUpdateCursor(RawDragEventType.DragLeave, _lastRoot, _lastPosition, InputModifiers.None); + RaiseEventAndUpdateCursor(RawDragEventType.DragLeave, _lastRoot, _lastPosition, RawInputModifiers.None); UpdateCursor(null, DragDropEffects.None); _result.OnNext(DragDropEffects.None); } diff --git a/src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs b/src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs index 1ef03b49ce..cfd28106eb 100644 --- a/src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs +++ b/src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs @@ -57,6 +57,10 @@ namespace Avalonia.Controls.Remote.Server } } + private static RawInputModifiers GetAvaloniaRawInputModifiers( + Avalonia.Remote.Protocol.Input.InputModifiers[] modifiers) + => (RawInputModifiers)GetAvaloniaInputModifiers(modifiers); + private static InputModifiers GetAvaloniaInputModifiers (Avalonia.Remote.Protocol.Input.InputModifiers[] modifiers) { var result = InputModifiers.None; @@ -225,7 +229,7 @@ namespace Avalonia.Controls.Remote.Server 0, key.IsDown ? RawKeyEventType.KeyDown : RawKeyEventType.KeyUp, (Key)key.Key, - GetAvaloniaInputModifiers(key.Modifiers))); + GetAvaloniaRawInputModifiers(key.Modifiers))); }, DispatcherPriority.Input); } if(obj is TextInputEventMessage text) diff --git a/src/Avalonia.Diagnostics/DevTools.xaml.cs b/src/Avalonia.Diagnostics/DevTools.xaml.cs index ddd3e29e43..1fcfb525cb 100644 --- a/src/Avalonia.Diagnostics/DevTools.xaml.cs +++ b/src/Avalonia.Diagnostics/DevTools.xaml.cs @@ -116,9 +116,9 @@ namespace Avalonia.Diagnostics private void RawKeyDown(RawKeyEventArgs e) { - const InputModifiers modifiers = InputModifiers.Control | InputModifiers.Shift; + const RawInputModifiers modifiers = RawInputModifiers.Control | RawInputModifiers.Shift; - if ((e.Modifiers) == modifiers) + if (e.Modifiers == modifiers) { var point = (Root.VisualRoot as IInputRoot)?.MouseDevice?.GetPosition(Root) ?? default(Point); var control = Root.GetVisualsAt(point, x => (!(x is AdornerLayer) && x.IsVisible)) diff --git a/src/Avalonia.Input/IKeyboardDevice.cs b/src/Avalonia.Input/IKeyboardDevice.cs index 1410476267..6b3e8435d9 100644 --- a/src/Avalonia.Input/IKeyboardDevice.cs +++ b/src/Avalonia.Input/IKeyboardDevice.cs @@ -6,7 +6,7 @@ using System.ComponentModel; namespace Avalonia.Input { - [Flags] + [Flags, Obsolete("Use KeyModifiers and PointerPointProperties")] public enum InputModifiers { None = 0, @@ -19,6 +19,16 @@ namespace Avalonia.Input MiddleMouseButton = 64 } + [Flags] + public enum KeyModifiers + { + None = 0, + Alt = 1, + Control = 2, + Shift = 4, + Meta = 8, + } + [Flags] public enum KeyStates { @@ -27,6 +37,25 @@ namespace Avalonia.Input Toggled = 2, } + public enum RawInputModifiers + { + None = 0, + Alt = 1, + Control = 2, + Shift = 4, + Meta = 8, + LeftMouseButton = 16, + RightMouseButton = 32, + MiddleMouseButton = 64, + KeyboardMask = Alt | Control | Shift | Meta + } + + internal static class KeyModifiersUtils + { + public static KeyModifiers ConvertToKey(RawInputModifiers modifiers) => + (KeyModifiers)(modifiers & RawInputModifiers.KeyboardMask); + } + public interface IKeyboardDevice : IInputDevice, INotifyPropertyChanged { IInputElement FocusedElement { get; } diff --git a/src/Avalonia.Input/KeyEventArgs.cs b/src/Avalonia.Input/KeyEventArgs.cs index 89053c6f61..8aef81503f 100644 --- a/src/Avalonia.Input/KeyEventArgs.cs +++ b/src/Avalonia.Input/KeyEventArgs.cs @@ -1,6 +1,7 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System; using Avalonia.Interactivity; namespace Avalonia.Input @@ -11,6 +12,8 @@ namespace Avalonia.Input public Key Key { get; set; } - public InputModifiers Modifiers { get; set; } + [Obsolete("Use KeyModifiers")] + public InputModifiers Modifiers => (InputModifiers)KeyModifiers; + public KeyModifiers KeyModifiers { get; set; } } } diff --git a/src/Avalonia.Input/KeyGesture.cs b/src/Avalonia.Input/KeyGesture.cs index c945902def..2377edf640 100644 --- a/src/Avalonia.Input/KeyGesture.cs +++ b/src/Avalonia.Input/KeyGesture.cs @@ -51,7 +51,14 @@ namespace Avalonia.Input public Key Key { get; set; } - public InputModifiers Modifiers { get; set; } + [Obsolete("Use KeyModifiers")] + public InputModifiers Modifiers + { + get => (InputModifiers)KeyModifiers; + set => KeyModifiers = (KeyModifiers)(((int)value) & 0xf); + } + + public KeyModifiers KeyModifiers { get; set; } static readonly Dictionary KeySynonyms = new Dictionary diff --git a/src/Avalonia.Input/KeyboardDevice.cs b/src/Avalonia.Input/KeyboardDevice.cs index 00606bd9b1..a02c580ad2 100644 --- a/src/Avalonia.Input/KeyboardDevice.cs +++ b/src/Avalonia.Input/KeyboardDevice.cs @@ -91,7 +91,7 @@ namespace Avalonia.Input RoutedEvent = routedEvent, Device = this, Key = keyInput.Key, - Modifiers = keyInput.Modifiers, + KeyModifiers = KeyModifiersUtils.ConvertToKey(keyInput.Modifiers), Source = element, }; diff --git a/src/Avalonia.Input/Raw/RawKeyEventArgs.cs b/src/Avalonia.Input/Raw/RawKeyEventArgs.cs index 044f244138..cd8b2eacf7 100644 --- a/src/Avalonia.Input/Raw/RawKeyEventArgs.cs +++ b/src/Avalonia.Input/Raw/RawKeyEventArgs.cs @@ -15,7 +15,7 @@ namespace Avalonia.Input.Raw IKeyboardDevice device, ulong timestamp, RawKeyEventType type, - Key key, InputModifiers modifiers) + Key key, RawInputModifiers modifiers) : base(device, timestamp) { Key = key; @@ -25,7 +25,7 @@ namespace Avalonia.Input.Raw public Key Key { get; set; } - public InputModifiers Modifiers { 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 ae0a2f535b..dd03f7d81e 100644 --- a/src/Avalonia.Native/WindowImplBase.cs +++ b/src/Avalonia.Native/WindowImplBase.cs @@ -209,7 +209,7 @@ namespace Avalonia.Native { Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1); - var args = new RawKeyEventArgs(_keyboard, timeStamp, (RawKeyEventType)type, (Key)key, (InputModifiers)modifiers); + var args = new RawKeyEventArgs(_keyboard, timeStamp, (RawKeyEventType)type, (Key)key, (RawInputModifiers)modifiers); Input?.Invoke(args); diff --git a/src/Avalonia.X11/X11Window.cs b/src/Avalonia.X11/X11Window.cs index 5481862f23..95b3e40063 100644 --- a/src/Avalonia.X11/X11Window.cs +++ b/src/Avalonia.X11/X11Window.cs @@ -438,7 +438,7 @@ namespace Avalonia.X11 ScheduleInput(new RawKeyEventArgs(_keyboard, (ulong)ev.KeyEvent.time.ToInt64(), ev.type == XEventName.KeyPress ? RawKeyEventType.KeyDown : RawKeyEventType.KeyUp, - X11KeyTransform.ConvertKey(key), TranslateModifiers(ev.KeyEvent.state)), ref ev); + X11KeyTransform.ConvertKey(key), TranslateRawModifiers(ev.KeyEvent.state)), ref ev); if (ev.type == XEventName.KeyPress) { @@ -559,6 +559,7 @@ namespace Avalonia.X11 } + RawInputModifiers TranslateRawModifiers(XModifierMask state) => (RawInputModifiers)TranslateModifiers(state); InputModifiers TranslateModifiers(XModifierMask state) { var rv = default(InputModifiers); diff --git a/src/Windows/Avalonia.Win32/Input/WindowsKeyboardDevice.cs b/src/Windows/Avalonia.Win32/Input/WindowsKeyboardDevice.cs index fee1fe2ae6..93adf7bee3 100644 --- a/src/Windows/Avalonia.Win32/Input/WindowsKeyboardDevice.cs +++ b/src/Windows/Avalonia.Win32/Input/WindowsKeyboardDevice.cs @@ -14,6 +14,7 @@ namespace Avalonia.Win32.Input public new static WindowsKeyboardDevice Instance { get; } = new WindowsKeyboardDevice(); + public RawInputModifiers RawModifiers => (RawInputModifiers)Modifiers; public InputModifiers Modifiers { get diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index e33e1f11dc..65fb2e447e 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -510,7 +510,7 @@ namespace Avalonia.Win32 WindowsKeyboardDevice.Instance, timestamp, RawKeyEventType.KeyDown, - KeyInterop.KeyFromVirtualKey(ToInt32(wParam)), WindowsKeyboardDevice.Instance.Modifiers); + KeyInterop.KeyFromVirtualKey(ToInt32(wParam)), WindowsKeyboardDevice.Instance.RawModifiers); break; case UnmanagedMethods.WindowsMessage.WM_MENUCHAR: @@ -523,7 +523,7 @@ namespace Avalonia.Win32 WindowsKeyboardDevice.Instance, timestamp, RawKeyEventType.KeyUp, - KeyInterop.KeyFromVirtualKey(ToInt32(wParam)), WindowsKeyboardDevice.Instance.Modifiers); + KeyInterop.KeyFromVirtualKey(ToInt32(wParam)), WindowsKeyboardDevice.Instance.RawModifiers); break; case UnmanagedMethods.WindowsMessage.WM_CHAR: // Ignore control chars diff --git a/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs b/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs index 35f0b39210..febc1de5f9 100644 --- a/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs @@ -55,7 +55,7 @@ namespace Avalonia.Controls.UnitTests Text = "1234" }; - RaiseKeyEvent(target, Key.A, InputModifiers.Control); + RaiseKeyEvent(target, Key.A, KeyModifiers.Control); Assert.Equal(0, target.SelectionStart); Assert.Equal(4, target.SelectionEnd); @@ -72,7 +72,7 @@ namespace Avalonia.Controls.UnitTests Template = CreateTemplate() }; - RaiseKeyEvent(target, Key.A, InputModifiers.Control); + RaiseKeyEvent(target, Key.A, KeyModifiers.Control); Assert.Equal(0, target.SelectionStart); Assert.Equal(0, target.SelectionEnd); @@ -90,7 +90,7 @@ namespace Avalonia.Controls.UnitTests Text = "1234" }; - RaiseKeyEvent(target, Key.Z, InputModifiers.Control); + RaiseKeyEvent(target, Key.Z, KeyModifiers.Control); Assert.Equal("1234", target.Text); } @@ -136,29 +136,29 @@ namespace Avalonia.Controls.UnitTests }; // (First| Second Third Fourth) - RaiseKeyEvent(textBox, Key.Back, InputModifiers.Control); + RaiseKeyEvent(textBox, Key.Back, KeyModifiers.Control); Assert.Equal(" Second Third Fourth", textBox.Text); // ( Second |Third Fourth) textBox.CaretIndex = 8; - RaiseKeyEvent(textBox, Key.Back, InputModifiers.Control); + RaiseKeyEvent(textBox, Key.Back, KeyModifiers.Control); Assert.Equal(" Third Fourth", textBox.Text); // ( Thi|rd Fourth) textBox.CaretIndex = 4; - RaiseKeyEvent(textBox, Key.Back, InputModifiers.Control); + RaiseKeyEvent(textBox, Key.Back, KeyModifiers.Control); Assert.Equal(" rd Fourth", textBox.Text); // ( rd F[ou]rth) textBox.SelectionStart = 5; textBox.SelectionEnd = 7; - RaiseKeyEvent(textBox, Key.Back, InputModifiers.Control); + RaiseKeyEvent(textBox, Key.Back, KeyModifiers.Control); Assert.Equal(" rd Frth", textBox.Text); // ( |rd Frth) textBox.CaretIndex = 1; - RaiseKeyEvent(textBox, Key.Back, InputModifiers.Control); + RaiseKeyEvent(textBox, Key.Back, KeyModifiers.Control); Assert.Equal("rd Frth", textBox.Text); } } @@ -175,30 +175,30 @@ namespace Avalonia.Controls.UnitTests }; // (First Second Third |Fourth) - RaiseKeyEvent(textBox, Key.Delete, InputModifiers.Control); + RaiseKeyEvent(textBox, Key.Delete, KeyModifiers.Control); Assert.Equal("First Second Third ", textBox.Text); // (First Second |Third ) textBox.CaretIndex = 13; - RaiseKeyEvent(textBox, Key.Delete, InputModifiers.Control); + RaiseKeyEvent(textBox, Key.Delete, KeyModifiers.Control); Assert.Equal("First Second ", textBox.Text); // (First Sec|ond ) textBox.CaretIndex = 9; - RaiseKeyEvent(textBox, Key.Delete, InputModifiers.Control); + RaiseKeyEvent(textBox, Key.Delete, KeyModifiers.Control); Assert.Equal("First Sec", textBox.Text); // (Fi[rs]t Sec ) textBox.SelectionStart = 2; textBox.SelectionEnd = 4; - RaiseKeyEvent(textBox, Key.Delete, InputModifiers.Control); + RaiseKeyEvent(textBox, Key.Delete, KeyModifiers.Control); Assert.Equal("Fit Sec", textBox.Text); // (Fit Sec| ) textBox.Text += " "; textBox.CaretIndex = 7; - RaiseKeyEvent(textBox, Key.Delete, InputModifiers.Control); + RaiseKeyEvent(textBox, Key.Delete, KeyModifiers.Control); Assert.Equal("Fit Sec", textBox.Text); } } @@ -486,12 +486,12 @@ namespace Avalonia.Controls.UnitTests }.RegisterInNameScope(scope)); } - private void RaiseKeyEvent(TextBox textBox, Key key, InputModifiers inputModifiers) + private void RaiseKeyEvent(TextBox textBox, Key key, KeyModifiers inputModifiers) { textBox.RaiseEvent(new KeyEventArgs { RoutedEvent = InputElement.KeyDownEvent, - Modifiers = inputModifiers, + KeyModifiers = inputModifiers, Key = key }); } diff --git a/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs b/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs index 0ee772425b..c744543f99 100644 --- a/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs @@ -183,7 +183,7 @@ namespace Avalonia.Controls.UnitTests new Mock().Object, 0, RawKeyEventType.KeyDown, - Key.A, InputModifiers.None); + Key.A, RawInputModifiers.None); impl.Object.Input(input); inputManagerMock.Verify(x => x.ProcessInput(input)); diff --git a/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs b/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs index 5646e86f7a..f51a50c0d5 100644 --- a/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs @@ -619,7 +619,7 @@ namespace Avalonia.Controls.UnitTests { RoutedEvent = InputElement.KeyDownEvent, Key = selectAllGesture.Key, - Modifiers = selectAllGesture.Modifiers + KeyModifiers = selectAllGesture.KeyModifiers }; target.RaiseEvent(keyEvent); @@ -665,7 +665,7 @@ namespace Avalonia.Controls.UnitTests { RoutedEvent = InputElement.KeyDownEvent, Key = selectAllGesture.Key, - Modifiers = selectAllGesture.Modifiers + KeyModifiers = selectAllGesture.KeyModifiers }; target.RaiseEvent(keyEvent); @@ -711,7 +711,7 @@ namespace Avalonia.Controls.UnitTests { RoutedEvent = InputElement.KeyDownEvent, Key = selectAllGesture.Key, - Modifiers = selectAllGesture.Modifiers + KeyModifiers = selectAllGesture.KeyModifiers }; target.RaiseEvent(keyEvent);