Skip to content

feat: put the video back when the tab comes back, undoing auto-PiP - #4

Merged
artginzburg merged 1 commit into
mainfrom
claude/video-pip-restore-state-t14l12
Aug 5, 2026
Merged

artginzburg merged 1 commit into
mainfrom
claude/video-pip-restore-state-t14l12

Conversation

@artginzburg

@artginzburg artginzburg commented Aug 1, 2026 •

Copy link
Copy Markdown
Owner

New setting autoRestoreOnTabReturn ("Put it back when you return to the tab"): when the tab becomes visible again, a video that this extension floated on the last tab hide leaves PiP and goes back where it came from.

The two defaults, which disagree on purpose

autoRestoreOnTabReturn is on, autoPipOnTabHide stays off. That is coherent only because nothing is ever remembered while the parent is off, so the child can do nothing until the user switches the parent on — it is a shape rather than a behaviour: it says what auto-PiP means for whoever turns it on without reading further. The rule the two satisfy together is that no window moves before the user has asked for anything, and it holds: the return half is consulted only for a video this binding floated, and floating one requires the parent.

The control is disabled while the parent is off — in options.html as well as in render, since the markup is the page for the moment before the bundle runs. Not unchecked, which would misreport what is stored; not hidden, which would make the feature undiscoverable exactly where somebody is reading about it. Same principle as RRR §4.3's access read-out being a marker rather than a button.

Why this is a setting and not a behaviour

RRR §4.6 ruled restoring on return out, and its objection still stands — the user may have deliberately kept the window floating. What makes the option legitimate is that the objection is answered inside the option's own definition. Two conditions, each with its own test:

  1. the video must be one we floated (never one already in PiP when the tab hid);
  2. it must have been in PiP continuously since.

The second is judged by the browser's own presentation reports (PresentationController.onModeChange, BF02's fourth member), not by the mode read on return. Those differ exactly when the user takes the window out and puts it back by hand: same mode, opposite intent. Mutation check: deleting the subscription and keeping a live-mode check leaves 50 of 52 auto-PiP tests green, and the one it breaks is that case.

Notes worth a reviewer's attention

  • Exit is togglePiP, the call the hotkey makes — not setMode(INLINE). So "back where it came from" includes BF19's document fullscreen, from one existing function rather than a second answer that can drift. Symmetric with DECISIONS 174, which routed the entry the same way.
  • A fullscreen player usually comes back inline. requestFullscreen needs a user gesture and returning to a tab is not one, so that half of the restore is refused and swallowed. Documented in the options page and the README rather than suppressed — inline is where the user lands either way, and suppressing the request would exclude a future Safari that allows it.
  • The setting is read at the moment of return, not latched when the tab hid. Turning it on is a tab switch — you leave the video for the options page, which floats it — so latching would answer the very first try with nothing happening.
  • The child setting is never rewritten when the parent goes off; it is only greyed out. Clearing it would lose the answer every time the parent was off for an afternoon.
  • visibilityState === 'visible' / === 'hidden' as named states, so a prerendered document is neither.

Verification

  • 491 tests pass, up from 471 (20 new). tsc clean on both projects, prettier clean.
  • dist/content.js 8050 → 8259 B of 12288 (RRR §5.2), 67%.
  • Not run here: xcodebuild. This was a Linux cloud session, so the Xcode half of make check (project, app-build, entitlements) has not been executed — CI's macOS job covers it, and no new source files were added, so project.yml's inputFiles list is unchanged.
  • Not verified in Safari. The two-condition claim and the fullscreen refusal are the parts a real browser could still contradict; make app locally is the only instrument for that.

Records: RRR §3 and §4.6 amended, DECISIONS 318–325 (with 323a/323b for the defaults), PLAN T22, README, ARCHITECTURE module map.

New setting `autoRestoreOnTabReturn`: when the tab becomes visible again, a
video that *this extension* floated on the last tab hide leaves PiP and goes
back where it came from.

**On by default, while `autoPipOnTabHide` stays off** — coherent only because
nothing is ever remembered while the parent is off, so this can do nothing until
the user switches that on. It is a shape rather than a behaviour: it says what
auto-PiP means for whoever turns it on without reading further. The rule the two
defaults satisfy together is that no window moves before the user has asked for
anything. The control is `disabled` while the parent is off, in `options.html`
as well as in `render` — not unchecked, which would misreport what is stored,
and not hidden, which would make the feature undiscoverable exactly where
somebody is reading about it.

RRR §4.6 previously ruled restoring on return out, and its objection — the user
may have deliberately kept the window floating — is answered inside the
setting's own definition rather than waived. Two conditions, each with its own
test: the video must be one we floated, and it must have been in PiP
continuously since, judged by the browser's presentation reports
(`onModeChange`) and not by the mode read on return. Those differ exactly when
the user takes the window out and puts it back by hand: same mode, opposite
intent. Deleting the subscription leaves 50 of 52 auto-PiP tests green.

Exit is `togglePiP`, the call the hotkey makes, so "back where it came from"
includes BF19's document fullscreen — which Safari will usually refuse for want
of a user gesture. Accepted and documented in the options page and the README
rather than suppressed: inline is where the user lands either way.

491 tests (was 471); `dist/content.js` 8050 → 8259 B of 12288 (RRR §5.2).
Decisions 318–325.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MruXVD9WM1YTATWgftepZW
@artginzburg
artginzburg force-pushed the claude/video-pip-restore-state-t14l12 branch from 3723b16 to 80a87ef Compare August 5, 2026 01:51
@artginzburg artginzburg changed the title feat: an opt-in return half for auto-PiP — put the video back when the tab comes back feat: put the video back when the tab comes back, undoing auto-PiP Aug 5, 2026
@artginzburg
artginzburg merged commit d8b18b3 into main Aug 5, 2026
2 checks passed
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