Skip to content

메인 탭 전환 시의 키보드/포커스 UX 개선 - #5220

Open
dolsup wants to merge 1 commit into
fix/ios-imefrom
fix/tab-transition-with-keyboard
Open

메인 탭 전환 시의 키보드/포커스 UX 개선#5220
dolsup wants to merge 1 commit into
fix/ios-imefrom
fix/tab-transition-with-keyboard

Conversation

@dolsup

@dolsup dolsup commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

변경사항

  • 탭 전환 완료 시 키보드 진행률을 1f로 확정하고, Hidden 수락 이후에만 포커스를 해제합니다.
  • 그동안 이전 탭의 기존 포커스만 유지하고 새 탭의 신규 포커스는 차단합니다.
  • 새 노트 autofocus는 최초 presentation에서 소비해, Notes로 돌아올 때 키보드가 다시 뜨지 않습니다.

개선점

  • 탭 전환으로 키보드를 닫을 때 간헐적으로 키보드가 full size로 보였다가 줄어드는 문제를 해결
  • 포커스가 풀렸던 탭으로 되돌아가는 중에 다시 포커스가 되고 키보드가 뜨는 문제를 해결
  • 그런데 그럴 때 전환이 완료되면 다시 포커스가 해제되고 키보드가 내려가는 문제를 해결

dolsup commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

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.
Learn more


How to use the Graphite Merge Queue

Add 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.

@dolsup dolsup mentioned this pull request Aug 7, 2026
@dolsup
dolsup marked this pull request as ready for review August 7, 2026 13:12
@dolsup
dolsup requested a review from devunt as a code owner August 7, 2026 13:12
Comment on lines +316 to +324
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)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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.

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.

1 participant