From ac936ce13024e2d0b2ff98e7164e89e7284fe804 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sun, 21 May 2023 14:56:00 +0200 Subject: [PATCH 1/2] Added failing test for #11290. --- .../Input/KeyboardNavigationTests_Tab.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/Avalonia.Base.UnitTests/Input/KeyboardNavigationTests_Tab.cs b/tests/Avalonia.Base.UnitTests/Input/KeyboardNavigationTests_Tab.cs index 34a9947d28..0b3d1a275b 100644 --- a/tests/Avalonia.Base.UnitTests/Input/KeyboardNavigationTests_Tab.cs +++ b/tests/Avalonia.Base.UnitTests/Input/KeyboardNavigationTests_Tab.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using Avalonia.Controls; using Avalonia.Input; +using Avalonia.UnitTests; using Xunit; namespace Avalonia.Base.UnitTests.Input @@ -1253,5 +1254,24 @@ namespace Avalonia.Base.UnitTests.Input Assert.Same(expected, result); } + + [Fact] + public void Focuses_First_Child_From_No_Focus() + { + using var app = UnitTestApplication.Start(TestServices.RealFocus); + var button = new Button(); + var root = new TestRoot(button); + var target = new KeyboardNavigationHandler(); + + target.SetOwner(root); + + root.RaiseEvent(new KeyEventArgs + { + RoutedEvent = InputElement.KeyDownEvent, + Key = Key.Tab, + }); + + Assert.True(button.IsFocused); + } } } From 94b9c36e31a63959f7f83e6806d0db8c5da6b6ff Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sun, 21 May 2023 14:57:01 +0200 Subject: [PATCH 2/2] Focus first child from no focus. If there is no currently focused element when tab navigation occurs, move the focus from the root. Fixes #11290. --- .../Input/KeyboardNavigationHandler.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Avalonia.Base/Input/KeyboardNavigationHandler.cs b/src/Avalonia.Base/Input/KeyboardNavigationHandler.cs index 7b6da62e2d..7a83501ce4 100644 --- a/src/Avalonia.Base/Input/KeyboardNavigationHandler.cs +++ b/src/Avalonia.Base/Input/KeyboardNavigationHandler.cs @@ -77,13 +77,16 @@ namespace Avalonia.Input /// The direction to move. /// Any key modifiers active at the time of focus. public void Move( - IInputElement element, + IInputElement? element, NavigationDirection direction, KeyModifiers keyModifiers = KeyModifiers.None) { - element = element ?? throw new ArgumentNullException(nameof(element)); + if (element is null && _owner is null) + { + return; + } - var next = GetNext(element, direction); + var next = GetNext(element ?? _owner!, direction); if (next != null) { @@ -101,10 +104,9 @@ namespace Avalonia.Input /// The event args. protected virtual void OnKeyDown(object? sender, KeyEventArgs e) { - var current = FocusManager.GetFocusManager(e.Source as IInputElement)?.GetFocusedElement(); - - if (current != null && e.Key == Key.Tab) + if (e.Key == Key.Tab) { + var current = FocusManager.GetFocusManager(e.Source as IInputElement)?.GetFocusedElement(); var direction = (e.KeyModifiers & KeyModifiers.Shift) == 0 ? NavigationDirection.Next : NavigationDirection.Previous; Move(current, direction, e.KeyModifiers);