Skip to content

Commit

Permalink
fix: capturePage for hidden windows on Windows/Linux
Browse files Browse the repository at this point in the history
  • Loading branch information
codebytere committed Oct 10, 2023
1 parent 24bc0ee commit 8353209
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 25 deletions.
23 changes: 12 additions & 11 deletions shell/browser/api/electron_api_web_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -468,9 +468,16 @@ base::IDMap<WebContents*>& GetAllWebContents() {
void OnCapturePageDone(gin_helper::Promise<gfx::Image> promise,
base::ScopedClosureRunner capture_handle,
const SkBitmap& bitmap) {
auto ui_task_runner = content::GetUIThreadTaskRunner({});
if (!ui_task_runner->RunsTasksInCurrentSequence()) {
ui_task_runner->PostTask(
FROM_HERE, base::BindOnce(&OnCapturePageDone, std::move(promise),
std::move(capture_handle), bitmap));
return;
}

// Hack to enable transparency in captured image
promise.Resolve(gfx::Image::CreateFrom1xBitmap(bitmap));

capture_handle.RunAndReset();
}

Expand Down Expand Up @@ -3452,22 +3459,16 @@ v8::Local<v8::Promise> WebContents::CapturePage(gin::Arguments* args) {
}

auto* const view = web_contents()->GetRenderWidgetHostView();
if (!view) {
if (!view || view->GetViewBounds().size().IsEmpty()) {
promise.Resolve(gfx::Image());
return handle;
}

#if !BUILDFLAG(IS_MAC)
// If the view's renderer is suspended this may fail on Windows/Linux -
// bail if so. See CopyFromSurface in
// content/public/browser/render_widget_host_view.h.
auto* rfh = web_contents()->GetPrimaryMainFrame();
if (rfh &&
rfh->GetVisibilityState() == blink::mojom::PageVisibilityState::kHidden) {
promise.Resolve(gfx::Image());
if (!view->IsSurfaceAvailableForCopy()) {
promise.RejectWithErrorMessage(
"Current display surface not available for capture");
return handle;
}
#endif // BUILDFLAG(IS_MAC)

auto capture_handle = web_contents()->IncrementCapturerCount(
rect.size(), stay_hidden, stay_awake);
Expand Down
32 changes: 18 additions & 14 deletions spec/api-browser-window-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2224,7 +2224,22 @@ describe('BrowserWindow module', () => {
expect(visible).to.equal('hidden');
});

it('resolves after the window is hidden', async () => {
it('resolves when the window is occluded', async () => {
const w1 = new BrowserWindow({ show: false });
w1.loadFile(path.join(fixtures, 'pages', 'a.html'));
await once(w1, 'ready-to-show');
w1.show();

const w2 = new BrowserWindow({ show: false });
w2.loadFile(path.join(fixtures, 'pages', 'a.html'));
await once(w2, 'ready-to-show');
w2.show();

const visibleImage = await w1.capturePage();
expect(visibleImage.isEmpty()).to.equal(false);
});

it('resolves when the window is not visible', async () => {
const w = new BrowserWindow({ show: false });
w.loadFile(path.join(fixtures, 'pages', 'a.html'));
await once(w, 'ready-to-show');
Expand All @@ -2233,21 +2248,10 @@ describe('BrowserWindow module', () => {
const visibleImage = await w.capturePage();
expect(visibleImage.isEmpty()).to.equal(false);

w.hide();
w.minimize();

const hiddenImage = await w.capturePage();
const isEmpty = process.platform !== 'darwin';
expect(hiddenImage.isEmpty()).to.equal(isEmpty);
});

it('resolves after the window is hidden and capturer count is non-zero', async () => {
const w = new BrowserWindow({ show: false });
w.webContents.setBackgroundThrottling(false);
w.loadFile(path.join(fixtures, 'pages', 'a.html'));
await once(w, 'ready-to-show');

const image = await w.capturePage();
expect(image.isEmpty()).to.equal(false);
expect(hiddenImage.isEmpty()).to.equal(false);
});

it('preserves transparency', async () => {
Expand Down

0 comments on commit 8353209

Please sign in to comment.