fix(browser): scope background page mount admission

This commit is contained in:
Merge Sim
2026-09-08 14:34:04 -07:00
parent 3f315dacd3
commit 7c1728c58b
3 changed files with 21 additions and 6 deletions
@@ -22,7 +22,10 @@ import { WorkspaceDocPagePane } from '../workspace-doc/workspace-doc-page-pane'
import { DeferredBrowserContent } from './DeferredBrowserContent'
import { isBrowserPagePanePaintable } from '../host-guest/browser-page-paintability'
import { SshRoutedBrowserPageGate } from './ssh-routed-browser-page-gate'
import { useAnyBrowserPageMountAdmission } from '../host-guest/browser-page-mount-admission'
import {
isBrowserPageMountAdmitted,
useAnyBrowserPageMountAdmission
} from '../host-guest/browser-page-mount-admission'
export default function BrowserPane({
browserTab,
@@ -168,7 +171,9 @@ export default function BrowserPane({
key={page.id}
retainMounted={isWorktreeActive}
mountEligible={isBrowserPagePanePaintable({
isActive: (isActive && page.id === activeBrowserPageId) || hasAdmittedPage,
isActive:
(isActive && page.id === activeBrowserPageId) ||
(hasAdmittedPage && isBrowserPageMountAdmitted(page.id)),
isAutomationVisible: automationVisiblePageIds.has(page.id),
isMobileDriven: mobileDrivenPageIds.has(page.id),
hasRemoteViewer: remotelyViewedPageIds.has(page.id)
@@ -6,6 +6,10 @@ const admittedPageIds = new Set<string>()
const listeners = new Set<() => void>()
let version = 0
export function isBrowserPageMountAdmitted(pageId: string): boolean {
return admittedPageIds.has(pageId)
}
function emit(): void {
version += 1
for (const listener of listeners) {
@@ -36,11 +40,11 @@ export function useBrowserPageMountAdmission(pageId: string): boolean {
},
() => {
void version
return admittedPageIds.has(pageId)
return isBrowserPageMountAdmitted(pageId)
},
() => false
)
return admittedPageIds.has(pageId)
return isBrowserPageMountAdmitted(pageId)
}
export function useAnyBrowserPageMountAdmission(pageIds: readonly string[]): boolean {
@@ -51,9 +55,9 @@ export function useAnyBrowserPageMountAdmission(pageIds: readonly string[]): boo
},
() => {
void version
return pageIds.some((pageId) => admittedPageIds.has(pageId))
return pageIds.some(isBrowserPageMountAdmitted)
},
() => false
)
return pageIds.some((pageId) => admittedPageIds.has(pageId))
return pageIds.some(isBrowserPageMountAdmitted)
}
@@ -13,6 +13,7 @@ import { closeRemoteBrowserPageInOwningEnvironment } from './browser-remote-clos
import { releaseDocPreviewGrant } from '@/lib/doc-preview-grants'
import { destroyWorkspaceWebviews } from '../browser-webview-cleanup'
import { omitRecordKeys } from '../worktrees/teardown/record-key-omission'
import { releaseBrowserPageMount } from '@/components/browser-pane/host-guest/browser-page-mount-admission'
export function createBrowserCloseActions(
set: BrowserSliceSet,
@@ -28,6 +29,7 @@ export function createBrowserCloseActions(
// grant is the only authority the preview scheme honors — a closed document must stop being
// readable, and it must stop being readable even if the reducer bails out below.
let docPageIdsToRelease: string[] = []
let closedPagesForMountRelease: string[] = []
let activeBrowserWorktreeIdToNotify: string | null = null
set((s) => {
let owningWorktreeId: string | null = null
@@ -49,6 +51,7 @@ export function createBrowserCloseActions(
}
const closedPages = s.browserPagesByWorkspace[tabId] ?? []
closedPagesForMountRelease = closedPages.map((page) => page.id)
const nextBrowserPagesByWorkspace = { ...s.browserPagesByWorkspace }
delete nextBrowserPagesByWorkspace[tabId]
const nextBrowserAnnotationsByPageId = { ...s.browserAnnotationsByPageId }
@@ -179,6 +182,9 @@ export function createBrowserCloseActions(
for (const docPageId of docPageIdsToRelease) {
releaseDocPreviewGrant(docPageId)
}
for (const pageId of closedPagesForMountRelease) {
releaseBrowserPageMount(pageId)
}
for (const tabs of Object.values(get().unifiedTabsByWorktree)) {
const workspaceItem = tabs.find(