Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: eliminate DecrementCapturerCount patch #35710

Merged
merged 2 commits into from
Oct 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 5 additions & 2 deletions docs/api/browser-window.md
Original file line number Diff line number Diff line change
Expand Up @@ -1437,13 +1437,16 @@ Returns `boolean` - Whether the window's document has been edited.

#### `win.blurWebView()`

#### `win.capturePage([rect])`
#### `win.capturePage([rect, opts])`

* `rect` [Rectangle](structures/rectangle.md) (optional) - The bounds to capture
* `opts` Object (optional)
* `stayHidden` boolean (optional) - Keep the page hidden instead of visible. Default is `false`.
* `stayAwake` boolean (optional) - Keep the system awake instead of allowing it to sleep. Default is `false`.

Returns `Promise<NativeImage>` - Resolves with a [NativeImage](native-image.md)

Captures a snapshot of the page within `rect`. Omitting `rect` will capture the whole visible page. If the page is not visible, `rect` may be empty.
Captures a snapshot of the page within `rect`. Omitting `rect` will capture the whole visible page. If the page is not visible, `rect` may be empty. The page is considered visible when its browser window is hidden and the capturer count is non-zero. If you would like the page to stay hidden, you should ensure that `stayHidden` is set to true.

#### `win.loadURL(url[, options])`

Expand Down
16 changes: 13 additions & 3 deletions docs/api/web-contents.md
Original file line number Diff line number Diff line change
Expand Up @@ -1338,20 +1338,25 @@ const requestId = webContents.findInPage('api')
console.log(requestId)
```

#### `contents.capturePage([rect])`
#### `contents.capturePage([rect, opts])`

* `rect` [Rectangle](structures/rectangle.md) (optional) - The area of the page to be captured.
* `opts` Object (optional)
* `stayHidden` boolean (optional) - Keep the page hidden instead of visible. Default is `false`.
* `stayAwake` boolean (optional) - Keep the system awake instead of allowing it to sleep. Default is `false`.

Returns `Promise<NativeImage>` - Resolves with a [NativeImage](native-image.md)

Captures a snapshot of the page within `rect`. Omitting `rect` will capture the whole visible page.
The page is considered visible when its browser window is hidden and the capturer count is non-zero.
If you would like the page to stay hidden, you should ensure that `stayHidden` is set to true.

#### `contents.isBeingCaptured()`

Returns `boolean` - Whether this page is being captured. It returns true when the capturer count
is large then 0.

#### `contents.incrementCapturerCount([size, stayHidden, stayAwake])`
#### `contents.incrementCapturerCount([size, stayHidden, stayAwake])` _Deprecated_

* `size` [Size](structures/size.md) (optional) - The preferred size for the capturer.
* `stayHidden` boolean (optional) - Keep the page hidden instead of visible.
Expand All @@ -1362,7 +1367,9 @@ hidden and the capturer count is non-zero. If you would like the page to stay hi

This also affects the Page Visibility API.

#### `contents.decrementCapturerCount([stayHidden, stayAwake])`
**Deprecated:** This API's functionality is now handled automatically within `contents.capturePage()`. See [breaking changes](../breaking-changes.md).

#### `contents.decrementCapturerCount([stayHidden, stayAwake])` _Deprecated_

* `stayHidden` boolean (optional) - Keep the page in hidden state instead of visible.
* `stayAwake` boolean (optional) - Keep the system awake instead of allowing it to sleep.
Expand All @@ -1371,6 +1378,9 @@ Decrease the capturer count by one. The page will be set to hidden or occluded s
browser window is hidden or occluded and the capturer count reaches zero. If you want to
decrease the hidden capturer count instead you should set `stayHidden` to true.

**Deprecated:** This API's functionality is now handled automatically within `contents.capturePage()`.
codebytere marked this conversation as resolved.
Show resolved Hide resolved
See [breaking changes](../breaking-changes.md).

#### `contents.getPrinters()` _Deprecated_

Get the system printer list.
Expand Down
86 changes: 85 additions & 1 deletion docs/breaking-changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,98 @@ win.webContents.on('input-event', (_, event) => {
})
```

### Removed: `webContents.incrementCapturerCount(stayHidden, stayAwake)`
codebytere marked this conversation as resolved.
Show resolved Hide resolved

The `webContents.incrementCapturerCount(stayHidden, stayAwake)` function has been removed.
It is now automatically handled by `webContents.capturePage` when a page capture completes.

```js
const w = new BrowserWindow({ show: false })

// Removed in Electron 23
w.webContents.incrementCapturerCount()
w.capturePage().then(image => {
console.log(image.toDataURL())
w.webContents.decrementCapturerCount()
})

// Replace with
w.capturePage().then(image => {
console.log(image.toDataURL())
})
```

### Removed: `webContents.decrementCapturerCount(stayHidden, stayAwake)`
codebytere marked this conversation as resolved.
Show resolved Hide resolved

The `webContents.decrementCapturerCount(stayHidden, stayAwake)` function has been removed.
It is now automatically handled by `webContents.capturePage` when a page capture completes.

```js
const w = new BrowserWindow({ show: false })

// Removed in Electron 23
w.webContents.incrementCapturerCount()
w.capturePage().then(image => {
console.log(image.toDataURL())
w.webContents.decrementCapturerCount()
})

// Replace with
w.capturePage().then(image => {
console.log(image.toDataURL())
})
```

## Planned Breaking API Changes (22.0)

### Deprecated: `webContents.incrementCapturerCount(stayHidden, stayAwake)`

`webContents.incrementCapturerCount(stayHidden, stayAwake)` has been deprecated.
It is now automatically handled by `webContents.capturePage` when a page capture completes.

```js
const w = new BrowserWindow({ show: false })

// Removed in Electron 23
w.webContents.incrementCapturerCount()
codebytere marked this conversation as resolved.
Show resolved Hide resolved
w.capturePage().then(image => {
console.log(image.toDataURL())
w.webContents.decrementCapturerCount()
})

// Replace with
w.capturePage().then(image => {
console.log(image.toDataURL())
})
```

### Removed: `webContents.decrementCapturerCount(stayHidden, stayAwake)`

`webContents.decrementCapturerCount(stayHidden, stayAwake)` has been deprecated.
It is now automatically handled by `webContents.capturePage` when a page capture completes.

```js
const w = new BrowserWindow({ show: false })

// Removed in Electron 23
w.webContents.incrementCapturerCount()
w.capturePage().then(image => {
console.log(image.toDataURL())
w.webContents.decrementCapturerCount()
})

// Replace with
w.capturePage().then(image => {
console.log(image.toDataURL())
})
```

### Removed: WebContents `new-window` event

The `new-window` event of WebContents has been removed. It is replaced by [`webContents.setWindowOpenHandler()`](api/web-contents.md#contentssetwindowopenhandlerhandler).

```js
// Removed in Electron 21
// Removed in Electron 22
webContents.on('new-window', (event) => {
event.preventDefault()
})
Expand Down
35 changes: 31 additions & 4 deletions shell/browser/api/electron_api_web_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -386,11 +386,13 @@ base::IDMap<WebContents*>& GetAllWebContents() {
return *s_all_web_contents;
}

// Called when CapturePage is done.
void OnCapturePageDone(gin_helper::Promise<gfx::Image> promise,
base::ScopedClosureRunner capture_handle,
const SkBitmap& bitmap) {
// Hack to enable transparency in captured image
promise.Resolve(gfx::Image::CreateFrom1xBitmap(bitmap));

capture_handle.RunAndReset();
}

absl::optional<base::TimeDelta> GetCursorBlinkInterval() {
Expand Down Expand Up @@ -3174,13 +3176,22 @@ void WebContents::StartDrag(const gin_helper::Dictionary& item,
}

v8::Local<v8::Promise> WebContents::CapturePage(gin::Arguments* args) {
gfx::Rect rect;
gin_helper::Promise<gfx::Image> promise(args->isolate());
v8::Local<v8::Promise> handle = promise.GetHandle();

// get rect arguments if they exist
gfx::Rect rect;
args->GetNext(&rect);

bool stay_hidden = false;
bool stay_awake = false;
if (args && args->Length() == 2) {
gin_helper::Dictionary options;
if (args->GetNext(&options)) {
options.Get("stayHidden", &stay_hidden);
options.Get("stayAwake", &stay_awake);
}
}

auto* const view = web_contents()->GetRenderWidgetHostView();
if (!view) {
promise.Resolve(gfx::Image());
Expand All @@ -3199,6 +3210,9 @@ v8::Local<v8::Promise> WebContents::CapturePage(gin::Arguments* args) {
}
#endif // BUILDFLAG(IS_MAC)

auto capture_handle = web_contents()->IncrementCapturerCount(
rect.size(), stay_hidden, stay_awake);

// Capture full page if user doesn't specify a |rect|.
const gfx::Size view_size =
rect.IsEmpty() ? view->GetViewBounds().size() : rect.size();
Expand All @@ -3215,11 +3229,18 @@ v8::Local<v8::Promise> WebContents::CapturePage(gin::Arguments* args) {
bitmap_size = gfx::ScaleToCeiledSize(view_size, scale);

view->CopyFromSurface(gfx::Rect(rect.origin(), view_size), bitmap_size,
base::BindOnce(&OnCapturePageDone, std::move(promise)));
base::BindOnce(&OnCapturePageDone, std::move(promise),
std::move(capture_handle)));
codebytere marked this conversation as resolved.
Show resolved Hide resolved
return handle;
}

// TODO(codebytere): remove in Electron v23.
void WebContents::IncrementCapturerCount(gin::Arguments* args) {
EmitWarning(node::Environment::GetCurrent(args->isolate()),
"webContents.incrementCapturerCount() is deprecated and will be "
"removed in v23",
"electron");

gfx::Size size;
bool stay_hidden = false;
bool stay_awake = false;
Expand All @@ -3236,7 +3257,13 @@ void WebContents::IncrementCapturerCount(gin::Arguments* args) {
.Release();
}

// TODO(codebytere): remove in Electron v23.
void WebContents::DecrementCapturerCount(gin::Arguments* args) {
codebytere marked this conversation as resolved.
Show resolved Hide resolved
EmitWarning(node::Environment::GetCurrent(args->isolate()),
"webContents.decrementCapturerCount() is deprecated and will be "
"removed in v23",
"electron");

bool stay_hidden = false;
bool stay_awake = false;

Expand Down
30 changes: 30 additions & 0 deletions spec/api-browser-window-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1737,6 +1737,36 @@ describe('BrowserWindow module', () => {
expect(image.isEmpty()).to.equal(true);
});

ifit(process.platform === 'darwin')('honors the stayHidden argument', async () => {
const w = new BrowserWindow({
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
});

w.loadFile(path.join(fixtures, 'pages', 'visibilitychange.html'));

{
const [, visibilityState, hidden] = await emittedOnce(ipcMain, 'pong');
expect(visibilityState).to.equal('visible');
expect(hidden).to.be.false('hidden');
}

w.hide();

{
const [, visibilityState, hidden] = await emittedOnce(ipcMain, 'pong');
expect(visibilityState).to.equal('hidden');
expect(hidden).to.be.true('hidden');
}

await w.capturePage({ x: 0, y: 0, width: 0, height: 0 }, { stayHidden: true });

const visible = await w.webContents.executeJavaScript('document.visibilityState');
expect(visible).to.equal('hidden');
});

it('resolves after the window is hidden', async () => {
const w = new BrowserWindow({ show: false });
w.loadFile(path.join(fixtures, 'pages', 'a.html'));
Expand Down