scenes: document picture-in-picture + pseudo-fullscreen fallback - #24
Merged
Conversation
- GestureLayer is pip-aware: while pip is active a single click exits pip immediately instead of the deferred play/pause toggle, and double-click fullscreen is unreachable. The gesture layer sits over the inline placeholder (z-index 1 over the z-index 0 video host), so without this the placeholder's own click handler never fired inside kino chrome. - enterPiP sets 100% height on the pip document's html and body so a standards-mode auto-height body cannot collapse the percentage-height iframe to 150px. - Docs: replace "lesson" wording in the pip/fullscreen spec with sequence/embedder phrasing. - Host guards the kino:play command's play() promise like the init path. - Pip overlay cue div announces via aria-live=polite; play/pause glyphs carry U+FE0E so they render as text, not emoji.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
kino | cc8c7ee | Commit Preview URL Branch Preview URL |
Jul 21 2026, 01:00 PM |
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.
Adds two capabilities to the scenes entry (audio-driven React scene sequences):
Document picture-in-picture (Chromium desktop)
canPiPis capability-gated ondocumentPictureInPicturepresence; the existingPipButtonpicks it up with zero UI changes. Safari/Firefox/mobile see no button.enterPiPopens adocumentPictureInPicturewindow and mounts a second, muted mirror iframe (same src) whose only job is visuals: it initializes at the master's position via the new optionalstartTimefield onkino:init(additive, protocol version stays 1), plays muted (always allowed by autoplay policy, no user-activation dependence), and gets drift-corrected via seek whenever it strays more than 0.3s from the master. play/pause/seek/rate fan out to both. Enter and exit are both seamless: audible playback is never interrupted in either direction.playsinlinemuted-capable<video>(Chrome's muted-autoplay exemption does not cover<audio>).aria-live, auto-hide while playing); the inline placeholder is clickable and, while pip is active, the gesture layer routes a single click toexitPiPinstead of play/pause.pagehidehandler owns every exit path (button, placeholder, browser close,destroy());enterPiPis guarded against double-invoke and mid-request teardown.Pseudo-fullscreen fallback
iPhone-class WebKit (Safari and iOS Chrome) has no
Element.requestFullscreen. The scenes provider now falls back to a pseudo-fullscreen presentation: fixed-position wrapper at100dvhwith safe-area padding and scroll lock, custom kino chrome stays on screen. Native fullscreen is still preferred wherever it exists; restore is guaranteed on exit anddestroy().Security note
The host accepts commands sourced from
window.parent.opener(the pip mirror's parent is the pip window while commands originate from the main tab, the pip window's opener). WithparentOriginlocked down (production) the origin check runs first on every message, so no new principal is admitted. With the"*"dev default this extends playback-command trust (play/pause/seek only) to whatever window opened the embedding tab.Embedder note
While pip is active the mirror fetches the sequence a second time (same tokened src). Playback tokens must remain reusable within their TTL for pip to work.
Verification
Changeset included (minor, releases as 0.7.0).