fix(subtitles): keep the second subtitle visible under HDR passthrough - #1092
Open
Jazzmedo wants to merge 2 commits into
Open
fix(subtitles): keep the second subtitle visible under HDR passthrough#1092Jazzmedo wants to merge 2 commits into
Jazzmedo wants to merge 2 commits into
Conversation
On a Windows HDR passthrough surface nothing can be composited over the video. That is why suppressHtmlSubs folds hdrNativeSurface in and the primary subtitle is handed to mpv through setSubVisible(subNativeRender). The second subtitle had no equivalent. `secondary-sub-visibility` is set to "no" at startup and never turned back on, so on that one surface the second subtitle was simply invisible, with nothing reporting why. Mirrors the primary's arrangement. applySecondarySubNative sits beside applySubStyle, the module that already owns mpv's subtitle properties, and drives `secondary-sub-visibility` plus `secondary-sub-pos`. useSecondarySub makes the call, keeping the whole secondary lifecycle in the hook that owns it. `secondary-sub-pos` is measured from the top, matching how `sub-pos` positions the primary. "Top of the screen" maps to 0; "Above the main line" offsets from the configured margin by a fixed slice of the frame, since mpv exposes no line-height metric to be exact with. The overlay is deliberately left alone. It cannot draw on that surface, and the HDR chrome window renders ShellLayer only, not StageOverlays, so there is no second renderer that could double up.
`vp fmt --check` in the Frontend job runs over changed files, and both were already unformatted on beta-branch, so touching them at all turns CI red. Kept separate from the fix so the two-line change in use-player-media stays visible.
Jazzmedo
force-pushed
the
fix/secondary-sub-hdr-passthrough
branch
from
July 29, 2026 21:24
e6122be to
0725b61
Compare
Collaborator
|
Hey @Jazzmedo Thanks for your awesome contributions! Just wondering if you have Discord so we could chat about some work on Harbor 👀 |
Collaborator
Author
I'm already following you on X and I'm interested, Here is my email |
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.
Summary
On a Windows HDR passthrough surface nothing can be composited over the video. That is why
suppressHtmlSubsfoldshdrNativeSurfacein (use-player-media.ts:161) and the primary subtitle is handed to mpv throughsetSubVisible(subNativeRender).The second subtitle had no equivalent.
secondary-sub-visibilityis set to"no"at startup (src-tauri/src/mpv.rs:717) and never turned back on, so on that one surface the second subtitle is simply invisible, with nothing indicating why. Every other configuration is unaffected.Change
Mirrors the arrangement the primary already has.
applySecondarySubNativesits next toapplySubStyleinsub-style.ts— the module that already owns mpv's subtitle properties — and drivessecondary-sub-visibilityplussecondary-sub-pos.useSecondarySubmakes the call, so the whole secondary lifecycle stays in the one hook that owns it.secondary-sub-posis measured from the top, matching howsub-pospositions the primary. Top of the screen maps to0; Above the main line offsets from the configured margin by a fixed slice of the frame, because mpv exposes no line-height metric to be exact with.The overlay is deliberately left untouched. It cannot draw on that surface, and the HDR chrome window renders
ShellLayeronly — notStageOverlays— so there is no second renderer that could double up. An earlier draft threaded a flag throughplayer.tsxto blanksecondarySubText; I dropped it once that turned out to guard against nothing, which also keepsplayer.tsxout of the diff entirely.Commits
fix(subtitles):the change itself — 3 files, +35/−0.style:formatting.vp fmt --checkin the Frontend job runs over changed files, andsub-style.tsanduse-player-media.tswere both already unformatted onbeta-branch, so touching them at all turns CI red. Split out so the two-line change inuse-player-media.tsstays visible.Testing
tsc -bclean.vp fmt --checkclean on all three files.I could not verify this on hardware — it needs a Windows machine with an HDR display and a PQ/HLG source, which I don't have. The change mirrors the primary's existing path and the
hdrNativeSurfaceguard means nothing else can reach it, but the on-screen result on that surface is unconfirmed. Happy to adjust thesecondary-sub-posoffset if it sits wrong against the primary line.