Browse Source
Fix FocusManager.SetFocusScope not doing anything (#21261)
* Add failing test for SetFocusScope
* Fix FocusManager.SetFocusScope not doing anything
pull/21272/head
Julien Lebosquain
4 months ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with
45 additions and
0 deletions
-
src/Avalonia.Base/Input/FocusManager.cs
-
tests/Avalonia.Base.UnitTests/Input/InputElement_Focus.cs
|
|
|
@ -142,6 +142,9 @@ namespace Avalonia.Input |
|
|
|
[PrivateApi] |
|
|
|
public void SetFocusScope(IFocusScope scope) |
|
|
|
{ |
|
|
|
if (KeyboardDevice.Instance is not { } keyboardDevice) |
|
|
|
return; |
|
|
|
|
|
|
|
if (GetFocusedElement(scope) is { } focused) |
|
|
|
{ |
|
|
|
Focus(focused); |
|
|
|
@ -153,6 +156,13 @@ namespace Avalonia.Input |
|
|
|
// focus etc.
|
|
|
|
Focus(scopeElement); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
// If the scope isn't focusable, make sure we still set it as the current focus root,
|
|
|
|
// otherwise it will be completely ignored
|
|
|
|
_focusRoot = scope as StyledElement; |
|
|
|
keyboardDevice.SetFocusedElement(null, NavigationMethod.Unspecified, KeyModifiers.None, false); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
[PrivateApi] |
|
|
|
|
|
|
|
@ -703,6 +703,41 @@ namespace Avalonia.Base.UnitTests.Input |
|
|
|
Assert.Same(innerButton, focusManager.GetFocusedElement()); |
|
|
|
} |
|
|
|
|
|
|
|
// https://github.com/AvaloniaUI/Avalonia/issues/13134
|
|
|
|
[Fact] |
|
|
|
public void SetFocusScope_On_Non_Focusable_Scope_Changes_Scope() |
|
|
|
{ |
|
|
|
using var app = UnitTestApplication.Start(TestServices.RealFocus); |
|
|
|
|
|
|
|
Button outerButton; |
|
|
|
TestFocusScope innerScope; |
|
|
|
var root = new TestRoot |
|
|
|
{ |
|
|
|
Child = new StackPanel |
|
|
|
{ |
|
|
|
Focusable = false, |
|
|
|
Children = |
|
|
|
{ |
|
|
|
(innerScope = new TestFocusScope()), |
|
|
|
(outerButton = new Button()) |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
outerButton.Focus(); |
|
|
|
|
|
|
|
var focusManager = Assert.IsType<FocusManager>(root.FocusManager); |
|
|
|
Assert.Same(outerButton, focusManager.GetFocusedElement()); |
|
|
|
|
|
|
|
// Switch to a scope that has no previously focused element and isn't focusable itself.
|
|
|
|
// TestFocusScope is a Panel (Focusable = false) + IFocusScope.
|
|
|
|
focusManager.SetFocusScope(innerScope); |
|
|
|
|
|
|
|
// Focus must be cleared: the scope is not focusable and has no prior focused element.
|
|
|
|
// Before the fix this was a no-op and outerButton would still be reported as focused.
|
|
|
|
Assert.Null(focusManager.GetFocusedElement()); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public void Can_Get_First_Focusable_Element() |
|
|
|
{ |
|
|
|
|