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
parent
commit
d22683f4eb
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 18
      src/Avalonia.Controls/TopLevel.cs
  2. 28
      tests/Avalonia.Controls.UnitTests/TopLevelTests.cs

18
src/Avalonia.Controls/TopLevel.cs

@ -257,9 +257,7 @@ namespace Avalonia.Controls
impl.LostFocus += PlatformImpl_LostFocus;
if(impl.TryGetFeature<ISystemNavigationManagerImpl>() is {} systemNavigationManager)
if (impl.TryGetFeature<ISystemNavigationManagerImpl>() is { } systemNavigationManager)
{
systemNavigationManager.BackRequested += (_, e) =>
{
@ -286,14 +284,14 @@ namespace Avalonia.Controls
KeyModifiers = (KeyModifiers)rawKeyEventArgs.Modifiers,
Key = rawKeyEventArgs.Key,
PhysicalKey = rawKeyEventArgs.PhysicalKey,
KeyDeviceType= rawKeyEventArgs.KeyDeviceType,
KeyDeviceType = rawKeyEventArgs.KeyDeviceType,
KeySymbol = rawKeyEventArgs.KeySymbol
};
backRequested = keymap.Any( key => key.Matches(keyEvent));
backRequested = keymap.Any(key => key.Matches(keyEvent));
}
}
else if(e is RawPointerEventArgs pointerEventArgs)
else if (e is RawPointerEventArgs pointerEventArgs)
{
backRequested = pointerEventArgs.Type == RawPointerEventType.XButton1Down;
}
@ -602,7 +600,7 @@ namespace Avalonia.Controls
private void InvalidateChildInsetsPadding()
{
if (Content is Control child
&& InsetsManager is {} insetsManager)
&& InsetsManager is { } insetsManager)
{
insetsManager.SafeAreaChanged -= InsetsManagerOnSafeAreaChanged;
_insetsPaddings?.Dispose();
@ -803,11 +801,7 @@ namespace Avalonia.Controls
void PlatformImpl_LostFocus()
{
var focused = (Visual?)FocusManager?.GetFocusedElement();
if (focused == null)
return;
while (focused.VisualParent != null)
focused = focused.VisualParent;
var focused = TopLevel.GetTopLevel((Visual?)FocusManager?.GetFocusedElement());
if (focused == this)
KeyboardDevice.Instance?.SetFocusedElement(null, NavigationMethod.Unspecified, KeyModifiers.None, false);

28
tests/Avalonia.Controls.UnitTests/TopLevelTests.cs

@ -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]
public void Reacts_To_Changes_In_Global_Styles()
{

Loading…
Cancel
Save