dependabot/github_actions/actions/setup-java-6.0.0
2
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
f357be4077 |
fix(tvos): match Siri Remote navigation to measured native focus-engine physics
Siri Remote navigation felt sluggish and then over-sensitive next to native tvOS apps (issue #2006): swipes were priced at a fixed travel per step, a single flick could glide into a second focus step, hard lifts coasted several extrapolated steps, and rail scrolls snapped in 65-250ms where native glides. Retuned the whole path against two hardware instrumentation passes on an Apple TV 4K: committed-move telemetry through an experimental UIFocusItem bridge (branch feat/tvos-native-focus-bridge), then a dedicated native probe app logging every touch sample, pan velocity, engine hint, focus step, and scroll tick across 101 swipe sessions on 160/230/300pt tiles. What the data showed, now encoded: - step pricing follows geometry: one step costs the focused item's extent along the swipe axis plus ~155pt (measured 314/391/410pt on 160/230/300pt tiles), not a fixed distance. Thresholds derive per axis from the primary focus rect, normalized so a wide-flat control steps vertically once the finger covers its height. Locked-focus rows (hub rows, the TV browse rail) vend their selected card's rect through the new LockedFocusRowNode so the row-wide focus node's screen-sized rect never prices the step. Scopes, the player's catch-all surfaces, and unbuilt cards fall back to a fixed 400pt. - a lift never coasts more than one step: sessions with lift velocities up to ~11400pt/s never produced a second coast step. The glide is gated on a sustained drag (two consecutive same-direction steps), cancelled by reversal pivots and new touches, so a discrete flick moves exactly one item. - the native 'inertia' feel is the scroll animation, not focus physics: the engine's scrollable containers settle over ~450-900ms of ease-out. TV rail and hub-row navigation scrolls now retarget a 500ms easeOutCubic animation per step, so drags and hold-repeats chain into one continuous glide that catches up on release. |
||
|
|
e3703892b3 |
fix(player): keep a keyboard Enter out of focus navigation
Pressing Enter over the player put the whole app into keyboard mode and dropped focus onto Play/Pause, even with Video Player Navigation off. Two independent paths did it. InputModeTracker promoted on any key satisfying isNavigationKey, a set that unioned activation, dismissal and the menu key with the arrows and consulted no setting at all; separately the surface's Select handler always asked the chrome for focus. Escape had the same effect, which on desktop reads as the mouse cursor vanishing mid-playback. Both now ask one predicate. eventRequestsFocusNavigation decides whether the app switches to keyboard mode and whether a key may hand focus to the chrome, so the two cannot disagree and focus can never land on a control while focus chrome is still suppressed. Activation and dismissal act on what already has focus, so they answer no; Tab, the menu key, a remote's OK or BACK, and an arrow that will really traverse answer yes. The one input the predicate cannot read off the event, whether the focused feature owns arrow keys, rides on the node as DirectionalShortcutFocusNode instead of on a subtree, so every sheet, prompt and OSD button stays an ordinary traversal target with nothing to re-enable. playerDirectionalNavigationEnabled and videoPlayerNavigationPreference replace five hand-copied pref-or-isTV expressions and a screen-level cache that disagreed with the live getter after a toggle. Services whose input is synthesized past HardwareKeyboard announce themselves through InputModeTracker.reportNonPointerInput rather than two static callbacks and three copies of a highlight-strategy write. That registration is now identity-guarded: the bootstrap-to-app tree swap disposed the outgoing tracker after the incoming one initialised and cleared both callbacks, so gamepad and companion remote input had stopped switching to keyboard mode entirely. Falling out of the same rule: a companion heartbeat no longer flips an idle desktop host into keyboard mode, analog-stick drift promotes only past the deadzone that actually navigates, Enter keeps toggling playback once the chrome is up, Tab both reaches and traverses the OSD, and the player surface claims the remote from mount rather than only when the chrome starts hidden, so the first key on a desktop route is a playback shortcut instead of the screen node's chrome-raising self-heal. isNavigationKey becomes isReservedControlKey, since its real meaning is a shell key rather than a text character and the old name is what invited the conflation. The unreachable PlayerChromeFocusTarget.timeline goes with it. |