fix(browser): wait for panel surface before capture
This commit is contained in:
@@ -339,6 +339,25 @@ const WebviewBrowser: React.FC<BrowserPaneProps> = ({ initialUrl, directory, tab
|
||||
}
|
||||
|
||||
if (action === 'browser.capture') {
|
||||
// A user may close the panel after browser.open. Chromium then removes
|
||||
// the zero-width webview's composited surface and capturePage() fails
|
||||
// with UnknownVizError. Reveal this existing browser tab again and let
|
||||
// the layout paint before asking Electron for the image.
|
||||
useUIStore.getState().openContextBrowser(directory, webview.getURL());
|
||||
const surfaceDeadline = Date.now() + 1_200;
|
||||
let previousWidth = 0;
|
||||
let stableSamples = 0;
|
||||
while (stableSamples < 2 && Date.now() < surfaceDeadline) {
|
||||
const width = webview.getBoundingClientRect().width;
|
||||
stableSamples = width >= 2 && Math.abs(width - previousWidth) < 0.5
|
||||
? stableSamples + 1
|
||||
: 0;
|
||||
previousWidth = width;
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
}
|
||||
await new Promise<void>((resolve) => {
|
||||
requestAnimationFrame(() => requestAnimationFrame(() => resolve()));
|
||||
});
|
||||
// Wait for a settled page first: a screenshot of a half-painted layout is
|
||||
// worse than none, because it looks like a finished one.
|
||||
await waitForIdle();
|
||||
@@ -450,7 +469,7 @@ const WebviewBrowser: React.FC<BrowserPaneProps> = ({ initialUrl, directory, tab
|
||||
await waitForIdle();
|
||||
}
|
||||
return result;
|
||||
}, [annotationHost, loadUrl, waitForIdle]);
|
||||
}, [annotationHost, directory, loadUrl, waitForIdle]);
|
||||
|
||||
React.useEffect(
|
||||
() => registerBrowserController({ run: runControlAction }),
|
||||
|
||||
Reference in New Issue
Block a user