diff --git a/src/Avalonia.Base/Input/FocusManager.cs b/src/Avalonia.Base/Input/FocusManager.cs index 2bf666af44..c8de7267ca 100644 --- a/src/Avalonia.Base/Input/FocusManager.cs +++ b/src/Avalonia.Base/Input/FocusManager.cs @@ -122,6 +122,11 @@ namespace Avalonia.Input { scope = scope ?? throw new ArgumentNullException(nameof(scope)); + if (element is not null && !CanFocus(element)) + { + return; + } + if (_focusScopes.TryGetValue(scope, out var existingElement)) { if (element != existingElement) @@ -242,6 +247,6 @@ namespace Avalonia.Input } } - private static bool IsVisible(IInputElement e) => (e as Visual)?.IsVisible ?? true; + private static bool IsVisible(IInputElement e) => (e as Visual)?.IsEffectivelyVisible ?? true; } } diff --git a/src/Avalonia.Base/Input/InputElement.cs b/src/Avalonia.Base/Input/InputElement.cs index 962c7aa334..33ddbaedf9 100644 --- a/src/Avalonia.Base/Input/InputElement.cs +++ b/src/Avalonia.Base/Input/InputElement.cs @@ -647,6 +647,10 @@ namespace Avalonia.Input { PseudoClasses.Set(":focus-within", change.GetNewValue()); } + else if (change.Property == IsVisibleProperty && !change.GetNewValue() && IsFocused) + { + FocusManager.Instance?.Focus(null); + } } /// diff --git a/tests/Avalonia.Controls.UnitTests/MaskedTextBoxTests.cs b/tests/Avalonia.Controls.UnitTests/MaskedTextBoxTests.cs index 9fd56dec4a..1d1065501f 100644 --- a/tests/Avalonia.Controls.UnitTests/MaskedTextBoxTests.cs +++ b/tests/Avalonia.Controls.UnitTests/MaskedTextBoxTests.cs @@ -657,7 +657,6 @@ namespace Avalonia.Controls.UnitTests { Template = CreateTemplate(), Text = "1234", - IsVisible = false }; var root = new TestRoot { Child = target1 }; diff --git a/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs b/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs index d71abe5a67..9c858a20e1 100644 --- a/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs @@ -594,7 +594,6 @@ namespace Avalonia.Controls.UnitTests { Template = CreateTemplate(), Text = "1234", - IsVisible = false }; var root = new TestRoot { Child = target1 }; diff --git a/tests/Avalonia.Controls.UnitTests/VirtualizingStackPanelTests.cs b/tests/Avalonia.Controls.UnitTests/VirtualizingStackPanelTests.cs index 61c21f46f4..f1a78a795b 100644 --- a/tests/Avalonia.Controls.UnitTests/VirtualizingStackPanelTests.cs +++ b/tests/Avalonia.Controls.UnitTests/VirtualizingStackPanelTests.cs @@ -298,7 +298,9 @@ namespace Avalonia.Controls.UnitTests using var app = App(); var (target, scroll, itemsControl) = CreateTarget(); - target.GetRealizedElements().First()!.Focus(); + var focused = target.GetRealizedElements().First()!; + focused.Focusable = true; + focused.Focus(); Assert.True(target.GetRealizedElements().First()!.IsKeyboardFocusWithin); scroll.Offset = new Vector(0, 200); @@ -314,6 +316,7 @@ namespace Avalonia.Controls.UnitTests var (target, scroll, itemsControl) = CreateTarget(); var focused = target.GetRealizedElements().First()!; + focused.Focusable = true; focused.Focus(); Assert.True(focused.IsKeyboardFocusWithin); @@ -331,6 +334,7 @@ namespace Avalonia.Controls.UnitTests var (target, scroll, itemsControl) = CreateTarget(); var focused = target.GetRealizedElements().First()!; + focused.Focusable = true; focused.Focus(); Assert.True(focused.IsKeyboardFocusWithin); @@ -350,12 +354,14 @@ namespace Avalonia.Controls.UnitTests var (target, scroll, itemsControl) = CreateTarget(); var originalFocused = target.GetRealizedElements().First()!; + originalFocused.Focusable = true; originalFocused.Focus(); scroll.Offset = new Vector(0, 500); Layout(target); var newFocused = target.GetRealizedElements().First()!; + newFocused.Focusable = true; newFocused.Focus(); Assert.False(originalFocused.IsVisible); diff --git a/tests/Avalonia.LeakTests/ControlTests.cs b/tests/Avalonia.LeakTests/ControlTests.cs index 55825561af..d6318bba0b 100644 --- a/tests/Avalonia.LeakTests/ControlTests.cs +++ b/tests/Avalonia.LeakTests/ControlTests.cs @@ -558,7 +558,7 @@ namespace Avalonia.LeakTests control.ContextMenu = null; } - var window = new Window(); + var window = new Window { Focusable = true }; window.Show(); Assert.Same(window, FocusManager.Instance.Current); @@ -605,7 +605,7 @@ namespace Avalonia.LeakTests contextMenu.Close(); } - var window = new Window(); + var window = new Window { Focusable = true }; window.Show(); Assert.Same(window, FocusManager.Instance.Current);