Browse Source

Send keypresses to toplevel if no focused control.

- Added `IInputRoot Root` property to `RawInputEventArgs`
- Removed `InputRoot` and `Root` properties from `RawDragEvent` and `RawPointerEvent` as its now in the base class
- `InputRoot` in `RawDragEvent` was incorrectly using the type `IInputElement` instead of `IInputRoot`, fix callers that were using the wrong type
- Pass the input root to all raw input event constructors
- If no control is focused in `KeyboardDevice.ProcessRawEvent` then raise the event on the root
Steven Kirk 6 years ago
parent
commit
fb173b30e2

+ 3 - 3
src/Avalonia.Controls/Platform/InProcessDragSource.cs

@@ -21,7 +21,7 @@ namespace Avalonia.Platform
 
 
         private DragDropEffects _allowedEffects;
         private DragDropEffects _allowedEffects;
         private IDataObject _draggedData;
         private IDataObject _draggedData;
-        private IInputElement _lastRoot;
+        private IInputRoot _lastRoot;
         private Point _lastPosition;
         private Point _lastPosition;
         private StandardCursorType _lastCursorType;
         private StandardCursorType _lastCursorType;
         private object _originalCursor;
         private object _originalCursor;
@@ -56,7 +56,7 @@ namespace Avalonia.Platform
             return DragDropEffects.None;
             return DragDropEffects.None;
         }
         }
 
 
-        private DragDropEffects RaiseEventAndUpdateCursor(RawDragEventType type, IInputElement root, Point pt, RawInputModifiers modifiers)
+        private DragDropEffects RaiseEventAndUpdateCursor(RawDragEventType type, IInputRoot root, Point pt, RawInputModifiers modifiers)
         {
         {
             _lastPosition = pt;
             _lastPosition = pt;
 
 
@@ -91,7 +91,7 @@ namespace Avalonia.Platform
             return StandardCursorType.No;
             return StandardCursorType.No;
         }
         }
         
         
-        private void UpdateCursor(IInputElement root, DragDropEffects effect)
+        private void UpdateCursor(IInputRoot root, DragDropEffects effect)
         {
         {
             if (_lastRoot != root)
             if (_lastRoot != root)
             {
             {

+ 2 - 0
src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs

@@ -227,6 +227,7 @@ namespace Avalonia.Controls.Remote.Server
                         Input?.Invoke(new RawKeyEventArgs(
                         Input?.Invoke(new RawKeyEventArgs(
                             KeyboardDevice,
                             KeyboardDevice,
                             0,
                             0,
+                            InputRoot,
                             key.IsDown ? RawKeyEventType.KeyDown : RawKeyEventType.KeyUp,
                             key.IsDown ? RawKeyEventType.KeyDown : RawKeyEventType.KeyUp,
                             (Key)key.Key,
                             (Key)key.Key,
                             GetAvaloniaRawInputModifiers(key.Modifiers)));
                             GetAvaloniaRawInputModifiers(key.Modifiers)));
@@ -241,6 +242,7 @@ namespace Avalonia.Controls.Remote.Server
                         Input?.Invoke(new RawTextInputEventArgs(
                         Input?.Invoke(new RawTextInputEventArgs(
                             KeyboardDevice,
                             KeyboardDevice,
                             0,
                             0,
+                            InputRoot,
                             text.Text));
                             text.Text));
                     }, DispatcherPriority.Input);
                     }, DispatcherPriority.Input);
                 }
                 }

+ 9 - 9
src/Avalonia.Input/DragDropDevice.cs

@@ -11,7 +11,7 @@ namespace Avalonia.Input
         
         
         private Interactive _lastTarget = null;
         private Interactive _lastTarget = null;
         
         
-        private Interactive GetTarget(IInputElement root, Point local)
+        private Interactive GetTarget(IInputRoot root, Point local)
         {
         {
             var target = root.InputHitTest(local)?.GetSelfAndVisualAncestors()?.OfType<Interactive>()?.FirstOrDefault();
             var target = root.InputHitTest(local)?.GetSelfAndVisualAncestors()?.OfType<Interactive>()?.FirstOrDefault();
             if (target != null && DragDrop.GetAllowDrop(target))
             if (target != null && DragDrop.GetAllowDrop(target))
@@ -19,7 +19,7 @@ namespace Avalonia.Input
             return null;
             return null;
         }
         }
         
         
-        private DragDropEffects RaiseDragEvent(Interactive target, IInputElement inputRoot, Point point, RoutedEvent<DragEventArgs> routedEvent, DragDropEffects operation, IDataObject data, InputModifiers modifiers)
+        private DragDropEffects RaiseDragEvent(Interactive target, IInputRoot inputRoot, Point point, RoutedEvent<DragEventArgs> routedEvent, DragDropEffects operation, IDataObject data, InputModifiers modifiers)
         {
         {
             if (target == null)
             if (target == null)
                 return DragDropEffects.None;
                 return DragDropEffects.None;
@@ -38,13 +38,13 @@ namespace Avalonia.Input
             return args.DragEffects;
             return args.DragEffects;
         }
         }
         
         
-        private DragDropEffects DragEnter(IInputElement inputRoot, Point point, IDataObject data, DragDropEffects effects, InputModifiers modifiers)
+        private DragDropEffects DragEnter(IInputRoot inputRoot, Point point, IDataObject data, DragDropEffects effects, InputModifiers modifiers)
         {
         {
             _lastTarget = GetTarget(inputRoot, point);
             _lastTarget = GetTarget(inputRoot, point);
             return RaiseDragEvent(_lastTarget, inputRoot, point, DragDrop.DragEnterEvent, effects, data, modifiers);
             return RaiseDragEvent(_lastTarget, inputRoot, point, DragDrop.DragEnterEvent, effects, data, modifiers);
         }
         }
 
 
-        private DragDropEffects DragOver(IInputElement inputRoot, Point point, IDataObject data, DragDropEffects effects, InputModifiers modifiers)
+        private DragDropEffects DragOver(IInputRoot inputRoot, Point point, IDataObject data, DragDropEffects effects, InputModifiers modifiers)
         {
         {
             var target = GetTarget(inputRoot, point);
             var target = GetTarget(inputRoot, point);
 
 
@@ -77,7 +77,7 @@ namespace Avalonia.Input
             }
             }
         }
         }
 
 
-        private DragDropEffects Drop(IInputElement inputRoot, Point point, IDataObject data, DragDropEffects effects, InputModifiers modifiers)
+        private DragDropEffects Drop(IInputRoot inputRoot, Point point, IDataObject data, DragDropEffects effects, InputModifiers modifiers)
         {
         {
             try
             try
             {
             {
@@ -100,16 +100,16 @@ namespace Avalonia.Input
             switch (e.Type)
             switch (e.Type)
             {
             {
                 case RawDragEventType.DragEnter:
                 case RawDragEventType.DragEnter:
-                    e.Effects = DragEnter(e.InputRoot, e.Location, e.Data, e.Effects, e.Modifiers);
+                    e.Effects = DragEnter(e.Root, e.Location, e.Data, e.Effects, e.Modifiers);
                     break;
                     break;
                 case RawDragEventType.DragOver:
                 case RawDragEventType.DragOver:
-                    e.Effects = DragOver(e.InputRoot, e.Location, e.Data, e.Effects, e.Modifiers);
+                    e.Effects = DragOver(e.Root, e.Location, e.Data, e.Effects, e.Modifiers);
                     break;
                     break;
                 case RawDragEventType.DragLeave:
                 case RawDragEventType.DragLeave:
-                    DragLeave(e.InputRoot);
+                    DragLeave(e.Root);
                     break;
                     break;
                 case RawDragEventType.Drop:
                 case RawDragEventType.Drop:
-                    e.Effects = Drop(e.InputRoot, e.Location, e.Data, e.Effects, e.Modifiers);
+                    e.Effects = Drop(e.Root, e.Location, e.Data, e.Effects, e.Modifiers);
                     break;
                     break;
             }
             }
         }
         }

+ 48 - 54
src/Avalonia.Input/KeyboardDevice.cs

@@ -70,66 +70,60 @@ namespace Avalonia.Input
         {
         {
             if(e.Handled)
             if(e.Handled)
                 return;
                 return;
-            IInputElement element = FocusedElement;
 
 
-            if (element != null)
-            {
-                var keyInput = e as RawKeyEventArgs;
+            var element = FocusedElement ?? e.Root;
 
 
-                if (keyInput != null)
+            if (e is RawKeyEventArgs keyInput)
+            {
+                switch (keyInput.Type)
                 {
                 {
-                    switch (keyInput.Type)
-                    {
-                        case RawKeyEventType.KeyDown:
-                        case RawKeyEventType.KeyUp:
-                            var routedEvent = keyInput.Type == RawKeyEventType.KeyDown
-                                ? InputElement.KeyDownEvent
-                                : InputElement.KeyUpEvent;
-
-                            KeyEventArgs ev = new KeyEventArgs
-                            {
-                                RoutedEvent = routedEvent,
-                                Device = this,
-                                Key = keyInput.Key,
-                                KeyModifiers = KeyModifiersUtils.ConvertToKey(keyInput.Modifiers),
-                                Source = element,
-                            };
-
-                            IVisual currentHandler = element;
-                            while (currentHandler != null && !ev.Handled && keyInput.Type == RawKeyEventType.KeyDown)
-                            {
-                                var bindings = (currentHandler as IInputElement)?.KeyBindings;
-                                if(bindings!=null)
-                                    foreach (var binding in bindings)
-                                    {
-                                        if(ev.Handled)
-                                            break;
-                                        binding.TryHandle(ev);
-                                    }
-                                currentHandler = currentHandler.VisualParent;
-                            }
-
-                            element.RaiseEvent(ev);
-                            e.Handled = ev.Handled;
-                            break;
-                    }
+                    case RawKeyEventType.KeyDown:
+                    case RawKeyEventType.KeyUp:
+                        var routedEvent = keyInput.Type == RawKeyEventType.KeyDown
+                            ? InputElement.KeyDownEvent
+                            : InputElement.KeyUpEvent;
+
+                        KeyEventArgs ev = new KeyEventArgs
+                        {
+                            RoutedEvent = routedEvent,
+                            Device = this,
+                            Key = keyInput.Key,
+                            KeyModifiers = KeyModifiersUtils.ConvertToKey(keyInput.Modifiers),
+                            Source = element,
+                        };
+
+                        IVisual currentHandler = element;
+                        while (currentHandler != null && !ev.Handled && keyInput.Type == RawKeyEventType.KeyDown)
+                        {
+                            var bindings = (currentHandler as IInputElement)?.KeyBindings;
+                            if (bindings != null)
+                                foreach (var binding in bindings)
+                                {
+                                    if (ev.Handled)
+                                        break;
+                                    binding.TryHandle(ev);
+                                }
+                            currentHandler = currentHandler.VisualParent;
+                        }
+
+                        element.RaiseEvent(ev);
+                        e.Handled = ev.Handled;
+                        break;
                 }
                 }
+            }
 
 
-                var text = e as RawTextInputEventArgs;
-
-                if (text != null)
+            if (e is RawTextInputEventArgs text)
+            {
+                var ev = new TextInputEventArgs()
                 {
                 {
-                    var ev = new TextInputEventArgs()
-                    {
-                        Device = this,
-                        Text = text.Text,
-                        Source = element,
-                        RoutedEvent = InputElement.TextInputEvent
-                    };
-
-                    element.RaiseEvent(ev);
-                    e.Handled = ev.Handled;
-                }
+                    Device = this,
+                    Text = text.Text,
+                    Source = element,
+                    RoutedEvent = InputElement.TextInputEvent
+                };
+
+                element.RaiseEvent(ev);
+                e.Handled = ev.Handled;
             }
             }
         }
         }
     }
     }

+ 2 - 4
src/Avalonia.Input/Raw/RawDragEvent.cs

@@ -2,7 +2,6 @@
 {
 {
     public class RawDragEvent : RawInputEventArgs
     public class RawDragEvent : RawInputEventArgs
     {
     {
-        public IInputElement InputRoot { get; }
         public Point Location { get; set; }
         public Point Location { get; set; }
         public IDataObject Data { get; }
         public IDataObject Data { get; }
         public DragDropEffects Effects { get; set; }
         public DragDropEffects Effects { get; set; }
@@ -10,11 +9,10 @@
         public InputModifiers Modifiers { get; }
         public InputModifiers Modifiers { get; }
 
 
         public RawDragEvent(IDragDropDevice inputDevice, RawDragEventType type, 
         public RawDragEvent(IDragDropDevice inputDevice, RawDragEventType type, 
-            IInputElement inputRoot, Point location, IDataObject data, DragDropEffects effects, RawInputModifiers modifiers)
-            :base(inputDevice, 0)
+            IInputRoot root, Point location, IDataObject data, DragDropEffects effects, RawInputModifiers modifiers)
+            :base(inputDevice, 0, root)
         {
         {
             Type = type;
             Type = type;
-            InputRoot = inputRoot;
             Location = location;
             Location = location;
             Data = data;
             Data = data;
             Effects = effects;
             Effects = effects;

+ 8 - 1
src/Avalonia.Input/Raw/RawInputEventArgs.cs

@@ -21,12 +21,14 @@ namespace Avalonia.Input.Raw
         /// </summary>
         /// </summary>
         /// <param name="device">The associated device.</param>
         /// <param name="device">The associated device.</param>
         /// <param name="timestamp">The event timestamp.</param>
         /// <param name="timestamp">The event timestamp.</param>
-        public RawInputEventArgs(IInputDevice device, ulong timestamp)
+        /// <param name="root">The root from which the event originates.</param>
+        public RawInputEventArgs(IInputDevice device, ulong timestamp, IInputRoot root)
         {
         {
             Contract.Requires<ArgumentNullException>(device != null);
             Contract.Requires<ArgumentNullException>(device != null);
 
 
             Device = device;
             Device = device;
             Timestamp = timestamp;
             Timestamp = timestamp;
+            Root = root;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -34,6 +36,11 @@ namespace Avalonia.Input.Raw
         /// </summary>
         /// </summary>
         public IInputDevice Device { get; }
         public IInputDevice Device { get; }
 
 
+        /// <summary>
+        /// Gets the root from which the event originates.
+        /// </summary>
+        public IInputRoot Root { get; }
+
         /// <summary>
         /// <summary>
         /// Gets or sets a value indicating whether the event was handled.
         /// Gets or sets a value indicating whether the event was handled.
         /// </summary>
         /// </summary>

+ 2 - 1
src/Avalonia.Input/Raw/RawKeyEventArgs.cs

@@ -14,9 +14,10 @@ namespace Avalonia.Input.Raw
         public RawKeyEventArgs(
         public RawKeyEventArgs(
             IKeyboardDevice device,
             IKeyboardDevice device,
             ulong timestamp,
             ulong timestamp,
+            IInputRoot root,
             RawKeyEventType type,
             RawKeyEventType type,
             Key key, RawInputModifiers modifiers)
             Key key, RawInputModifiers modifiers)
-            : base(device, timestamp)
+            : base(device, timestamp, root)
         {
         {
             Key = key;
             Key = key;
             Type = type;
             Type = type;

+ 1 - 7
src/Avalonia.Input/Raw/RawPointerEventArgs.cs

@@ -44,22 +44,16 @@ namespace Avalonia.Input.Raw
             RawPointerEventType type,
             RawPointerEventType type,
             Point position, 
             Point position, 
             RawInputModifiers inputModifiers)
             RawInputModifiers inputModifiers)
-            : base(device, timestamp)
+            : base(device, timestamp, root)
         {
         {
             Contract.Requires<ArgumentNullException>(device != null);
             Contract.Requires<ArgumentNullException>(device != null);
             Contract.Requires<ArgumentNullException>(root != null);
             Contract.Requires<ArgumentNullException>(root != null);
 
 
-            Root = root;
             Position = position;
             Position = position;
             Type = type;
             Type = type;
             InputModifiers = inputModifiers;
             InputModifiers = inputModifiers;
         }
         }
 
 
-        /// <summary>
-        /// Gets the root from which the event originates.
-        /// </summary>
-        public IInputRoot Root { get; }
-
         /// <summary>
         /// <summary>
         /// Gets the mouse position, in client DIPs.
         /// Gets the mouse position, in client DIPs.
         /// </summary>
         /// </summary>

+ 8 - 3
src/Avalonia.Input/Raw/RawTextInputEventArgs.cs

@@ -5,11 +5,16 @@ namespace Avalonia.Input.Raw
 {
 {
     public class RawTextInputEventArgs : RawInputEventArgs
     public class RawTextInputEventArgs : RawInputEventArgs
     {
     {
-        public string Text { get; set; }
-
-        public RawTextInputEventArgs(IKeyboardDevice device, ulong timestamp, string text) : base(device, timestamp)
+        public RawTextInputEventArgs(
+            IKeyboardDevice device,
+            ulong timestamp,
+            IInputRoot root,
+            string text)
+            : base(device, timestamp, root)
         {
         {
             Text = text;
             Text = text;
         }
         }
+
+        public string Text { get; set; }
     }
     }
 }
 }

+ 2 - 2
src/Avalonia.Native/WindowImplBase.cs

@@ -204,7 +204,7 @@ namespace Avalonia.Native
         {
         {
             Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1);
             Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1);
 
 
-            var args = new RawTextInputEventArgs(_keyboard, timeStamp, text);
+            var args = new RawTextInputEventArgs(_keyboard, timeStamp, _inputRoot, text);
 
 
             Input?.Invoke(args);
             Input?.Invoke(args);
 
 
@@ -215,7 +215,7 @@ namespace Avalonia.Native
         {
         {
             Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1);
             Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1);
 
 
-            var args = new RawKeyEventArgs(_keyboard, timeStamp, (RawKeyEventType)type, (Key)key, (RawInputModifiers)modifiers);
+            var args = new RawKeyEventArgs(_keyboard, timeStamp, _inputRoot, (RawKeyEventType)type, (Key)key, (RawInputModifiers)modifiers);
 
 
             Input?.Invoke(args);
             Input?.Invoke(args);
 
 

+ 2 - 2
src/Avalonia.X11/X11Window.cs

@@ -455,7 +455,7 @@ namespace Avalonia.X11
                     key = (X11Key)XKeycodeToKeysym(_x11.Display, ev.KeyEvent.keycode, index ? 0 : 1).ToInt32();
                     key = (X11Key)XKeycodeToKeysym(_x11.Display, ev.KeyEvent.keycode, index ? 0 : 1).ToInt32();
                 
                 
                 
                 
-                ScheduleInput(new RawKeyEventArgs(_keyboard, (ulong)ev.KeyEvent.time.ToInt64(),
+                ScheduleInput(new RawKeyEventArgs(_keyboard, (ulong)ev.KeyEvent.time.ToInt64(), _inputRoot,
                     ev.type == XEventName.KeyPress ? RawKeyEventType.KeyDown : RawKeyEventType.KeyUp,
                     ev.type == XEventName.KeyPress ? RawKeyEventType.KeyDown : RawKeyEventType.KeyUp,
                     X11KeyTransform.ConvertKey(key), TranslateModifiers(ev.KeyEvent.state)), ref ev);
                     X11KeyTransform.ConvertKey(key), TranslateModifiers(ev.KeyEvent.state)), ref ev);
 
 
@@ -470,7 +470,7 @@ namespace Avalonia.X11
                             if (text[0] < ' ' || text[0] == 0x7f) //Control codes or DEL
                             if (text[0] < ' ' || text[0] == 0x7f) //Control codes or DEL
                                 return;
                                 return;
                         }
                         }
-                        ScheduleInput(new RawTextInputEventArgs(_keyboard, (ulong)ev.KeyEvent.time.ToInt64(), text),
+                        ScheduleInput(new RawTextInputEventArgs(_keyboard, (ulong)ev.KeyEvent.time.ToInt64(), _inputRoot, text),
                             ref ev);
                             ref ev);
                     }
                     }
                 }
                 }

+ 3 - 3
src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs

@@ -212,17 +212,17 @@ namespace Avalonia.Win32.Interop.Wpf
         protected override void OnMouseLeave(MouseEventArgs e) => MouseEvent(RawPointerEventType.LeaveWindow, e);
         protected override void OnMouseLeave(MouseEventArgs e) => MouseEvent(RawPointerEventType.LeaveWindow, e);
 
 
         protected override void OnKeyDown(KeyEventArgs e)
         protected override void OnKeyDown(KeyEventArgs e)
-            => _ttl.Input?.Invoke(new RawKeyEventArgs(_keyboard, (uint) e.Timestamp, RawKeyEventType.KeyDown,
+            => _ttl.Input?.Invoke(new RawKeyEventArgs(_keyboard, (uint) e.Timestamp, _inputRoot, RawKeyEventType.KeyDown,
                 (Key) e.Key,
                 (Key) e.Key,
                 GetModifiers(null)));
                 GetModifiers(null)));
 
 
         protected override void OnKeyUp(KeyEventArgs e)
         protected override void OnKeyUp(KeyEventArgs e)
-            => _ttl.Input?.Invoke(new RawKeyEventArgs(_keyboard, (uint)e.Timestamp, RawKeyEventType.KeyUp,
+            => _ttl.Input?.Invoke(new RawKeyEventArgs(_keyboard, (uint)e.Timestamp, _inputRoot, RawKeyEventType.KeyUp,
                 (Key)e.Key,
                 (Key)e.Key,
                 GetModifiers(null)));
                 GetModifiers(null)));
 
 
         protected override void OnTextInput(TextCompositionEventArgs e) 
         protected override void OnTextInput(TextCompositionEventArgs e) 
-            => _ttl.Input?.Invoke(new RawTextInputEventArgs(_keyboard, (uint) e.Timestamp, e.Text));
+            => _ttl.Input?.Invoke(new RawTextInputEventArgs(_keyboard, (uint) e.Timestamp, _inputRoot, e.Text));
 
 
         void ITopLevelImpl.SetCursor(IPlatformHandle cursor)
         void ITopLevelImpl.SetCursor(IPlatformHandle cursor)
         {
         {

+ 2 - 2
src/Windows/Avalonia.Win32/OleDropTarget.cs

@@ -8,13 +8,13 @@ namespace Avalonia.Win32
 {
 {
     class OleDropTarget : IDropTarget
     class OleDropTarget : IDropTarget
     {
     {
-        private readonly IInputElement _target;
+        private readonly IInputRoot _target;
         private readonly ITopLevelImpl _tl;
         private readonly ITopLevelImpl _tl;
         private readonly IDragDropDevice _dragDevice;
         private readonly IDragDropDevice _dragDevice;
         
         
         private IDataObject _currentDrag = null;
         private IDataObject _currentDrag = null;
 
 
-        public OleDropTarget(ITopLevelImpl tl, IInputElement target)
+        public OleDropTarget(ITopLevelImpl tl, IInputRoot target)
         {
         {
             _dragDevice = AvaloniaLocator.Current.GetService<IDragDropDevice>();
             _dragDevice = AvaloniaLocator.Current.GetService<IDragDropDevice>();
             _tl = tl;
             _tl = tl;

+ 3 - 1
src/Windows/Avalonia.Win32/WindowImpl.cs

@@ -508,6 +508,7 @@ namespace Avalonia.Win32
                     e = new RawKeyEventArgs(
                     e = new RawKeyEventArgs(
                             WindowsKeyboardDevice.Instance,
                             WindowsKeyboardDevice.Instance,
                             timestamp,
                             timestamp,
+                            _owner,
                             RawKeyEventType.KeyDown,
                             RawKeyEventType.KeyDown,
                             KeyInterop.KeyFromVirtualKey(ToInt32(wParam)), WindowsKeyboardDevice.Instance.Modifiers);
                             KeyInterop.KeyFromVirtualKey(ToInt32(wParam)), WindowsKeyboardDevice.Instance.Modifiers);
                     break;
                     break;
@@ -521,6 +522,7 @@ namespace Avalonia.Win32
                     e = new RawKeyEventArgs(
                     e = new RawKeyEventArgs(
                             WindowsKeyboardDevice.Instance,
                             WindowsKeyboardDevice.Instance,
                             timestamp,
                             timestamp,
+                            _owner,
                             RawKeyEventType.KeyUp,
                             RawKeyEventType.KeyUp,
                             KeyInterop.KeyFromVirtualKey(ToInt32(wParam)), WindowsKeyboardDevice.Instance.Modifiers);
                             KeyInterop.KeyFromVirtualKey(ToInt32(wParam)), WindowsKeyboardDevice.Instance.Modifiers);
                     break;
                     break;
@@ -528,7 +530,7 @@ namespace Avalonia.Win32
                     // Ignore control chars
                     // Ignore control chars
                     if (ToInt32(wParam) >= 32)
                     if (ToInt32(wParam) >= 32)
                     {
                     {
-                        e = new RawTextInputEventArgs(WindowsKeyboardDevice.Instance, timestamp,
+                        e = new RawTextInputEventArgs(WindowsKeyboardDevice.Instance, timestamp, _owner,
                             new string((char)ToInt32(wParam), 1));
                             new string((char)ToInt32(wParam), 1));
                     }
                     }
 
 

+ 1 - 0
tests/Avalonia.Controls.UnitTests/TopLevelTests.cs

@@ -182,6 +182,7 @@ namespace Avalonia.Controls.UnitTests
                 var input = new RawKeyEventArgs(
                 var input = new RawKeyEventArgs(
                     new Mock<IKeyboardDevice>().Object,
                     new Mock<IKeyboardDevice>().Object,
                     0,
                     0,
+                    target,
                     RawKeyEventType.KeyDown,
                     RawKeyEventType.KeyDown,
                     Key.A, RawInputModifiers.None);
                     Key.A, RawInputModifiers.None);
                 impl.Object.Input(input);
                 impl.Object.Input(input);