메인 탭 전환 시의 키보드/포커스 UX 개선 - #5220
Conversation
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
How to use the Graphite Merge QueueAdd the label 🚀 to this PR to add it to the merge queue. You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
| activeKeyboardSession?.let { session -> | ||
| val interactionId = session.interactionId | ||
| session.updateHiddenProgress(1f) | ||
| session.finish(SoftwareKeyboardPresentationEndpoint.Hidden) | ||
| snapshotFlow { softwareKeyboardPresentationController.interactionState } | ||
| .first { it.activeInteractionId != interactionId } | ||
| } | ||
| focusManager.clearFocus(force = true) | ||
| state.enableFocusFor(settledTab) |
There was a problem hiding this comment.
The outer snapshotFlow { Triple(state.motion, state.bodyPosition, state.settledTab) }.collect { ... } (line 295) is conflated: while this block is suspended in .first { it.activeInteractionId != interactionId } waiting for the platform to accept the keyboard-hide, snapshotFlow only redelivers the latest state once the collector resumes. Since motion is already reset to null as soon as the pager transition settles (well before this async wait completes), and gesture admission only requires motion == null, a user can start and fully settle a second tab swipe while the first swipe's keyboard-hide acceptance is still pending.
When the collector resumes, it sees motion == null with the new settledTab, but origin was already cleared to null at line 311 for the first transition, so it hits val activeOrigin = origin ?: return@collect (line 309) and silently drops the second transition — enableFocusFor(settledTab) (line 324) is never called for it.
Since focusEnabledTab (used by MainShell.kt's foregroundFocusEnabled = tab == mainTabState.focusEnabledTab) is only ever written from this single call site, it stays stuck on the stale (previous) tab, and the actually-visible tab can never gain focus/keyboard until some later transition happens to be fully observed by this collector.
Consider decoupling focusEnabledTab updates from this conflated collector — e.g. launching the acceptance-wait separately so it can't block/skip subsequent settle events, or resyncing focusEnabledTab to settledTab whenever the pager is at rest regardless of whether the keyboard-hide wait for a prior transition completed.

변경사항
1f로 확정하고, Hidden 수락 이후에만 포커스를 해제합니다.개선점