Skip to content

fix(shell): stop double-dispatching post-play/playback footer keybinds#13

Closed
KitsuneKode wants to merge 9 commits into
mainfrom
cursor/shell-keybind-first-press-ad11
Closed

fix(shell): stop double-dispatching post-play/playback footer keybinds#13
KitsuneKode wants to merge 9 commits into
mainfrom
cursor/shell-keybind-first-press-ad11

Conversation

@KitsuneKode

Copy link
Copy Markdown
Owner

Summary

Post-play (and any ShellFrame surface that wires both footer actions and onUnhandledInput) was double-firing footer accelerators on the first press. That made o / r / n / m feel like they “don’t trigger in one go” — the first press opened tracks (or replayed / continued) twice, so the UI often looked unchanged until a second press.

Root cause

ShellFrame has two input owners:

  1. useShellInput — resolves footer letter shortcuts via onResolve
  2. A second useInput — always forwarded the same key to onUnhandledInput

Post-play mounts both: footer actions and onUnhandledInputresolvePostPlayUnhandledInput. So pressing o both resolved source and re-entered the unhandled path (open tracks again).

Loading/playback already opted out of footer resolution with letterKeysHandledExternally and owns letters in its own useInput — that path is unchanged.

Fix

In ShellFrame, skip footer-owned (enabled) letters in the unhandled path unless letterKeysHandledExternally is set. Unbound keys (j/k/13, arrows) still reach onUnhandledInput.

Tests

  • Extended shell-frame-input-bridge.test.tsx with a no-double-delivery assertion
  • Added post-play-keybind-once.useinput.test.tsx covering o/r/n once + j/k/1 still unhandled

Merge notes

Based on #12 (shared CI green tip). Independent of product PRs #6/#7/#9/#10.

Test plan

  • Local focused input bridge + post-play once tests
  • Full pre-push suite green
  • CI Format / Typecheck / Test
  • Manual: after episode EOF, first o opens tracks once; first r replays once; first n continues once
Open in Web Open in Cursor 

cursoragent and others added 9 commits July 9, 2026 20:23
…assets

GitHub resolves local composite actions from the workspace before any step
runs, so nesting checkout inside setup-bun-monorepo made every CI/release/
build-binaries job fail instantly since that action landed. Callers now
checkout first; the composite only sets up Bun/caches/install.

Also: native smoke matrix for host binaries, fail_on_unmatched_files +
asset-count assert on release upload, clearer empty-release installer
errors, and fix install.ps1 returning early after mpv so yt-dlp is offered.

Co-authored-by: Manash Pratim Bhuyan <bhuyanmanash2002@gmail.com>
v0.2.6.json has an empty sections array (changelog body has no ###
headings). The docs test required sections and failed once CI actually
ran again after the checkout fix.

Co-authored-by: Manash Pratim Bhuyan <bhuyanmanash2002@gmail.com>
These failures only surfaced once CI started executing the full suite again
(#8). Fix the durable diagnostics retention time bomb, make install.ps1
dry-run succeed without LOCALAPPDATA/network, stop mock.module leaking from
palette tests into history/overlay tests, and gate live Miruro network checks.
Typecheck failed because openSetupWizardFromShell was mocked as Promise<void>
instead of Promise<SetupWizardResult>, which also broke Format (turbo depends
on typecheck for fmt:check).
…rship

Make the deprecated preferred-source unit test mock network instead of live
fetch, and harden Videasy so deprecated preferred ids never bias cycle order
or probe Sanji/1movies. Document that resolveEscTransition stays unused at
runtime because root-overlay-shell + resolveOverlayBackStack already own Esc.
Replace mock.module in watch-genre-stats with a restored spy so later
tmdb-proxy/title-detail/recommendation tests see the real module, and use
relative timestamps in stats-service so windowed averages stay valid.
ShellFrame resolved footer letters via useShellInput and then forwarded
the same key to onUnhandledInput. Post-play wires both paths, so o/r/n
opened tracks / replayed / continued twice — first press looked dead.
Skip footer-owned keys in the unhandled path unless the surface opts
into letterKeysHandledExternally (LoadingShell).
@KitsuneKode

Copy link
Copy Markdown
Owner Author

Superseded: footer key double-dispatch fixed on main in d6ed4b3 with coverage in shell-frame-input-bridge.test.tsx. Closing to keep the queue honest — reopen if any behaviour here is missing from main.

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.

2 participants