fix(studio): a focused video or audio player keeps its arrow and play keys - #4854
Merged
Merged
Conversation
Edit accuracy: 846 passing here, 846 on the base branchThe gate passes. Quarantined, measured but not gated (2)
|
miguel-heygen
force-pushed
the
fix/studio-media-focus-keys
branch
5 times, most recently
from
October 1, 2026 20:01
01fd658 to
75cd15c
Compare
miguel-heygen
force-pushed
the
fix/studio-media-focus-keys
branch
from
October 1, 2026 21:05
75cd15c to
13d9b2d
Compare
miguel-heygen
marked this pull request as ready for review
October 1, 2026 21:48
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changes
With a video or audio player focused (the asset preview's native controls), the keys Studio's shortcuts used to take from it now go to that player only: the arrow keys and Space, plus the playback letters (J, K, L and the rest) and the canvas, caption and snap keys. Before, the playback shortcuts claimed the arrows first: the timeline playhead stepped, the key never reached the player, and the playhead move closed the asset preview.
Why it was broken
Every Studio key handler asks "does the focused element own this key?" before acting. The shared answer (
isTypingTarget) covers text fields, editors, switches and comboboxes, but not a native media player, which seeks and plays with these keys itself. The playback shortcuts and the canvas nudge both relied on it.What this does
ownsPlainKeysinutils/typingTarget.ts(added by feat(studio): fade handles ride the fade's end and the waveform shows the fade #4844 for sliders) now has one list of controls that own their plain keys:[role='slider'],video[controls]andaudio[controls], on top of anythingisTypingTargetclaims. There is no second predicate.shouldIgnorePlaybackShortcutTarget, which the timeline player's key handler also goes through), the canvas arrow nudge, the caption-word arrow nudge and the preview's S/G snap keys use it, and so does the app's plain-key dispatcher (feat(studio): fade handles ride the fade's end and the waveform shows the fade #4844), so Delete on a focused player no longer deletes the selected clip.isTypingTarget, so a focused picker such as the font combobox keeps its keys there too.INPUTandTEXTAREA, so Cmd+Z in a contenteditable or a select undid the panel instead of the text. It now callsisTypingTarget(a Cmd shortcut belongs to a text field, not to a slider).ownsPlainKeysruns first and already claims them.shouldHandleTimelineDeleteKeywas dead code (re-exported fromTimeline.tsx, called only by its own test) with its own copy of the typing check. Deleted with its tests.Handlers checked
usePlaybackKeyboard)ownsPlainKeys(changed)useTimelinePlayer)shouldIgnorePlaybackShortcutTargetownsPlainKeys(inherited)useDomEditNudge)ownsPlainKeys(changed)captions/keyboard.ts)ownsPlainKeys(changed)SnapToolbar)ownsPlainKeys(was its own tag check)TimelineToolbar)isTypingTarget(was its own tag check)useKeyframeKeyboard)isTypingTarget(was its own copy)useAutomationSelectionKeyboard)isTypingTarget(was its own copy)SlideshowPanel)isTypingTarget(was anINPUT/TEXTAREAtag check)dispatchPlainKey)ownsPlainKeys(from #4844; now also covers players)dispatchModifierKey,useAppHotkeys)isTypingTarget, unchanged: a slider or player does not own Cmd+Z, copy or groupshouldIgnoreHistoryShortcut)isTypingTarget, unchanged, same reasontimelineKeyboardNavigation)Tests that fail without the fix
usePlaybackKeyboard.test.ts: "leaves the timeline alone while auseDomEditNudge.test.tsx: "does not nudge the selection while acaptions/keyboard.test.ts: "leaves the arrows to a focusedSnapToolbar.test.tsx: "leaves S and G alone while a combobox / select / switch / video player has focus" (four rows).typingTarget.test.ts: "is true for a native player with controls and for anything typing claims".useAppHotkeys.test.ts: "leaves Delete to a focusedTimelineToolbar.test.tsx: "N toggles snapping, but not while a picker that owns typing has focus".useKeyframeKeyboard.test.tsx: "leaves K to a focused picker that owns typing, like a font combobox".useAutomationSelectionKeyboard.test.tsx: "is inert while a picker that owns typing has focus".SlideshowPanel.test.ts: "leaves Cmd+Z to a text field, contenteditable and select included".A video without
controlsstill lets the playback keys step the timeline (tested).Before
A small fixture project with one 20 s video asset not yet on the timeline. The asset preview is open with its video paused at 0:02 and focused:
ArrowRight: the timeline playhead steps from frame 0 to frame 1, the video never sees the key, and the preview closes because the playhead moved.
After
The same steps: the playhead stays on frame 0, the video seeks from 2.00 s to 2.20 s, and the preview stays open.