Skip to content

Fix iOS text field focus transfer across scenes#3203

Open
Kyle (Kyle-Ye) wants to merge 2 commits into
JetBrains:jb-mainfrom
Kyle-Ye:fix-ios-nested-compose-textfield-focus
Open

Fix iOS text field focus transfer across scenes#3203
Kyle (Kyle-Ye) wants to merge 2 commits into
JetBrains:jb-mainfrom
Kyle-Ye:fix-ios-nested-compose-textfield-focus

Conversation

@Kyle-Ye

@Kyle-Ye Kyle (Kyle-Ye) commented Jul 8, 2026

Copy link
Copy Markdown

This fixes iOS BasicTextField focus handoff when moving focus between separate Compose scenes, for example an outer ComposeUIViewController and a nested ComposeUIView.

The fix adds a shared UIKit text input focus coordinator that releases the previously focused Compose scene before a different scene starts text input.

Fixes https://youtrack.jetbrains.com/issue/CMP-10454/iOS-BasicTextField-focus-is-not-released-when-moving-between-nested-ComposeUIView-scenes

Testing

  • Added NestedComposeTextFieldFocusTest.focusMovesToTextFieldInNestedComposeUIView
  • Verified the regression test fails before the fix:
    Nested text field should take focus and release the outer text field
  • Verified the same test passes after the fix:
    Executed 1 test, with 0 failures

Release Notes

Fixes - iOS

  • Fix BasicTextField focus handoff between nested Compose iOS scenes.

Google CLA

Signed or will sign the Google Contributor License Agreement.

@Kyle-Ye Kyle (Kyle-Ye) marked this pull request as ready for review July 8, 2026 08:09
@Kyle-Ye

Copy link
Copy Markdown
Author

Could you help review this PR? cc Vladimir Mazunin (@mazunin-v-jb)

@ASalavei

Andrei Salavei (ASalavei) commented Jul 8, 2026

Copy link
Copy Markdown

Thank you for spotting the issue. Currently, we have onResignFocus handler that must prevent such cases. It seems like it does not handle all required cases, like youth. I would first try to reuse this approach instead of creating a new one to minimize duplicated logic. It would be great if you could modify the hasFocusedExternalInputViewInWindowHierarchy() to fix the problem.

@Kyle-Ye Kyle (Kyle-Ye) force-pushed the fix-ios-nested-compose-textfield-focus branch from bd8b73f to 0746c67 Compare July 8, 2026 14:10
@Kyle-Ye

Kyle (Kyle-Ye) commented Jul 8, 2026

Copy link
Copy Markdown
Author

It would be great if you could modify the hasFocusedExternalInputViewInWindowHierarchy() to fix the problem.

Got it. And I have verified the previous dialog test case failure in the last CI pipeline is also fixed now.

Could you help review and approval the CI again for me? Andrei Salavei (@ASalavei)

@Kyle-Ye Kyle (Kyle-Ye) force-pushed the fix-ios-nested-compose-textfield-focus branch from 0746c67 to 6de0aed Compare July 9, 2026 14:35

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks for this PR 👍🏻

@Kyle-Ye

Copy link
Copy Markdown
Author

Andrei Salavei (@ASalavei) Could you please approve and trigger the CI workflow again?

I fixed the iPad-only failure in NestedComposeTextFieldFocusTest in ec0d088. The tagged UIKitView was wider than its fixed-width nested ComposeUIView, so tapping the host center missed the nested field on iPad. The nested ComposeUIView now directly fills the tagged host bounds.

Local verification:

  • iPhone 17 Pro / iOS 26.2: passed
  • iPad Pro 11-inch (M5) / iOS 26.2: passed
  • Temporarily reverting the production focus fix makes the regression test fail; restoring it makes the test pass.

The two Web failures in the previous run were unrelated kotlinNpmInstall 504 errors while fetching Kotlin/karma.

Thank you!

@Kyle-Ye

Copy link
Copy Markdown
Author

The only remaining failure is Compose Desktop Tests, where two DialogWindowV2Test cases timed out after 30 seconds.

It looks unrelated to this PR, since the changes are limited to iosMain and uikitInstrumentedTest, and the same Desktop job passed in the previous run.

I think we should retry it. Thanks

@Kyle-Ye

Copy link
Copy Markdown
Author

The retried Compose Desktop Tests job failed again, but this time in a different test: ComposeContainerLifecycleOwnerTest.allEvents
java.lang.AssertionError: expected:<ON_RESUME> but was:<null>

Let's rerun the job once more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants