Browse Source
Fix Toplevel not losing focus with native implementation deactivates. (#20768)
* add failing test
* query the toplevel of the currently focused control instead when losing focus
pull/20773/head
Emmanuel Hansen
4 weeks ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with
55 additions and
33 deletions
-
src/Avalonia.Controls/TopLevel.cs
-
tests/Avalonia.Controls.UnitTests/TopLevelTests.cs
|
|
@ -257,8 +257,6 @@ namespace Avalonia.Controls |
|
|
|
|
|
|
|
|
impl.LostFocus += PlatformImpl_LostFocus; |
|
|
impl.LostFocus += PlatformImpl_LostFocus; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (impl.TryGetFeature<ISystemNavigationManagerImpl>() is { } systemNavigationManager) |
|
|
if (impl.TryGetFeature<ISystemNavigationManagerImpl>() is { } systemNavigationManager) |
|
|
{ |
|
|
{ |
|
|
systemNavigationManager.BackRequested += (_, e) => |
|
|
systemNavigationManager.BackRequested += (_, e) => |
|
|
@ -803,11 +801,7 @@ namespace Avalonia.Controls |
|
|
|
|
|
|
|
|
void PlatformImpl_LostFocus() |
|
|
void PlatformImpl_LostFocus() |
|
|
{ |
|
|
{ |
|
|
var focused = (Visual?)FocusManager?.GetFocusedElement(); |
|
|
var focused = TopLevel.GetTopLevel((Visual?)FocusManager?.GetFocusedElement()); |
|
|
if (focused == null) |
|
|
|
|
|
return; |
|
|
|
|
|
while (focused.VisualParent != null) |
|
|
|
|
|
focused = focused.VisualParent; |
|
|
|
|
|
|
|
|
|
|
|
if (focused == this) |
|
|
if (focused == this) |
|
|
KeyboardDevice.Instance?.SetFocusedElement(null, NavigationMethod.Unspecified, KeyModifiers.None, false); |
|
|
KeyboardDevice.Instance?.SetFocusedElement(null, NavigationMethod.Unspecified, KeyModifiers.None, false); |
|
|
|
|
|
@ -253,6 +253,34 @@ namespace Avalonia.Controls.UnitTests |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[Fact] |
|
|
|
|
|
public void TopLevel_Should_Unfocus_When_Impl_Focus_Is_Lost() |
|
|
|
|
|
{ |
|
|
|
|
|
using (UnitTestApplication.Start(TestServices.RealFocus)) |
|
|
|
|
|
{ |
|
|
|
|
|
var impl = CreateMockTopLevelImpl(true); |
|
|
|
|
|
var content = new TextBox() |
|
|
|
|
|
{ |
|
|
|
|
|
Focusable = true |
|
|
|
|
|
}; |
|
|
|
|
|
var target = new TestTopLevel(impl.Object) |
|
|
|
|
|
{ |
|
|
|
|
|
Template = CreateTemplate(), |
|
|
|
|
|
Focusable = true, |
|
|
|
|
|
Content = content |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
target.LayoutManager.ExecuteInitialLayoutPass(); |
|
|
|
|
|
|
|
|
|
|
|
content.Focus(); |
|
|
|
|
|
Assert.True(content.IsFocused); |
|
|
|
|
|
|
|
|
|
|
|
impl.Object.LostFocus?.Invoke(); |
|
|
|
|
|
|
|
|
|
|
|
Assert.False(content.IsFocused); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
[Fact] |
|
|
[Fact] |
|
|
public void Reacts_To_Changes_In_Global_Styles() |
|
|
public void Reacts_To_Changes_In_Global_Styles() |
|
|
{ |
|
|
{ |
|
|
|