-
Notifications
You must be signed in to change notification settings - Fork 81
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
Adapt focus interop code to Compose 1.7 changes #1398
Conversation
FocusEvent.Cause.UNKNOWN, FocusEvent.Cause.ACTIVATION -> { | ||
focusManager.moveFocus(FocusDirection.Enter) | ||
if (!focusManager.hasFocus) { |
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 particular check fixes JetBrains/compose-multiplatform#4919
private val backwardRequester = FocusRequester() | ||
private val forwardRequester = FocusRequester() | ||
private var isRequesting = false | ||
private val backwardTracker = FocusTracker { |
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.
New features of FocusSwitcher
:
- simple refactoring
- avoiding recursive calls (can happen with empty panels with the new code from the upstream)
6c6f035
to
f003a4a
Compare
when (e.cause) { | ||
FocusEvent.Cause.TRAVERSAL_FORWARD -> { |
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 moved to ComposeSceneMediator
, as it is valid for all containers using it
@@ -462,59 +467,4 @@ class ComposePanelTest { | |||
window.dispose() | |||
} | |||
} | |||
|
|||
@Test | |||
fun `requestFocus assigns focus to first focusable element`() = runApplicationTest { |
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 moved this test to another test, and adapted to common logic there
f003a4a
to
bd67fde
Compare
FocusEvent.Cause.UNKNOWN, FocusEvent.Cause.ACTIVATION -> { | ||
focusManager.moveFocus(FocusDirection.Enter) | ||
if (!focusManager.hasFocus) { | ||
focusManager.takeFocus(FocusDirection.Next) |
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.
FocusDirection.Enter
doesn't work anymore (probably a commonMain bug), but there is no semantic difference with Next
here
Fixes JetBrains/compose-multiplatform#2944 Fixes JetBrains/compose-multiplatform#4919 Fixes https://youtrack.jetbrains.com/issue/COMPOSE-1212/Integration.-Check-changes-in-FocusOwnerImpl After https://android-review.googlesource.com/c/platform/frameworks/support/+/2813125, there are some changes that affected our code for focus interop with ComposePanel/SwingPanel: - the root node no longer focusable - FocusOwnerImpl now has iterop callbacks and our own modification of this file (in jb-main, integration was reset) doesn't work anymore ## Testing - added new tests - ComposeFocusTest now pass ## Release notes ### Fixes - Multiple platforms - Fix "ComposePanel. Focus moves to child after focusing/unfocusing the main window"
bd67fde
to
942bbfc
Compare
@@ -194,67 +207,77 @@ private class FocusSwitcher<T : Component>( | |||
private val interopComponent: SwingInteropComponent<T>, | |||
private val focusManager: FocusManager, | |||
) { |
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'd like to extract this class into separate file (with name something like SwingInteropFocusSwitcher
) at some point. Not a blocker
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 wouldn't move it out of this file, until the file size is manageable (<1000 lines). Because this logic is strictly bound to SwingPanel
.
A thing I would extract is FocusTracker
- it might be useful for other platforms. But only when it is needed - there is a chance that other implementations should use the Android way.
compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/node/RootNodeOwner.skiko.kt
Outdated
Show resolved
Hide resolved
…gor.demin/integration-fix-focus
@@ -156,6 +156,19 @@ public fun <T : Component> SwingPanel( | |||
} | |||
} | |||
|
|||
/** | |||
* true, if the event is handled by SwingPanel. |
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.
"Returns whether the event is handled by SwingPanel"
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.
Done
// In that case, SwingPanel will take care of it. | ||
if (!isParentOf(e.oppositeComponent)) { | ||
focusManager.requestFocus() | ||
if (!e.isTemporary && !e.isFocusGainedHandledBySwingPanel(this@ComposePanel)) { |
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.
A bit confusing that this is called from ComposePanel
(the function is about "SwingPanel"). Is this correct?
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.
Yes, this is ugly, but this was the fastest way to implement SwingPanel back in the days. I didn't change the logic, just added a name. There is no other purpose besides using for SwingPanel
.
A good alternative exists, but it needs investigation. I described it in the KDoc of this function.
private val rootModifier = EmptySemanticsElement(rootSemanticsNode) | ||
.then(Modifier.focusProperties { |
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.
The then
here could be omitted.
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.
Done
Fixes Investigate new features in the focus system and apply them to ComposePanel/SwingPanel interop compose-multiplatform#2944
Fixes ComposePanel. Focus moves to child after focusing/unfocusing the main window compose-multiplatform#4919
Fixes https://youtrack.jetbrains.com/issue/COMPOSE-1212/Integration.-Check-changes-in-FocusOwnerImpl
After https://android-review.googlesource.com/c/platform/frameworks/support/+/2813125, there are some changes that affected our code for focus interop with ComposePanel/SwingPanel:
Testing
Release notes
Fixes - Multiple platforms