-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix some issues with focus scopes #13409
Conversation
- Store focused element within a scope using an attached property (like WPF) - Store current focus root so that focus can be restored to that root when a focused control or active focus scope is removed Fixes #13325
@@ -77,7 +77,7 @@ public PopupRoot(TopLevel parent, IPopupImpl impl, IAvaloniaDependencyResolver? | |||
/// <summary> | |||
/// Gets the control that is hosting the popup root. | |||
/// </summary> | |||
Visual? IHostedVisualTreeRoot.Host => VisualParent; | |||
Visual? IHostedVisualTreeRoot.Host => Parent as Visual ?? ParentTopLevel; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Gillibald this fixes what I think was an incorrect change in one of your commits. I think the change in that commit was wrong because VisualParent
should always be null
for PopupRoot
considering that it's a visual root.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice😃 This is going t help a lot!
} | ||
else if (Current != null) | ||
else if (_focusRoot?.GetValue(FocusedElementProperty) is { } restore && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find the _focusRoot concept a bit confusing. Wouldn't it be better to just stick to focus scopes like in the old implementation?
At least in theory there could be another focus scope between the cleared scope and the VisualRoot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just following WPF's behavior of focusing the outermost focus scope when a focused control is removed. The reason we need to store the focus root is that at the time the focused control is removed we may not have all the information we need to find that outermost scope.
This was being produced for a compiler-generated enumerable class that was erroneously being included in the reference assembly for `FocusManager`.
And add failing test now that the hack is removed.
Fixes failing test from previous comment where focus wasn't restored when closing a context menu.
I think this PR should be ready for review now. |
* Remove focus hack from Popup. * Added failing focus scope tests. * Refactor focus scopes in FocusManager. - Store focused element within a scope using an attached property (like WPF) - Store current focus root so that focus can be restored to that root when a focused control or active focus scope is removed Fixes #13325 * Suppress API compat error. This was being produced for a compiler-generated enumerable class that was erroneously being included in the reference assembly for `FocusManager`. * Remove focus hack from ContextMenu. And add failing test now that the hack is removed. * Try to return a rooted host visual. Fixes failing test from previous comment where focus wasn't restored when closing a context menu. #Conflicts: # src/Avalonia.Controls/Primitives/Popup.cs
What does the pull request do?
As part of the fix for #13325 I needed to do some basic refactoring to
FocusManager
to fix our broken 2015-era focus scope handling.FocusManager
really needs a rewrite like the one started in #8392 - this PR however doesn't even attempt that, it just aims to fix the existing focus scope handling.Breaking Changes
Previously the reference assembly for
FocusManager
was exporting a compiler-generated enumerable class:This class wasn't exposed by the API so couldn't be used, but is no longer being generated after this PR. Added a suppression for it,
Fixed issues
Fixes #13325