refactor: eliminate DecrementCapturerCount patch (#35710)

This commit is contained in:
Shelley Vohr 2022-10-05 10:51:33 -07:00 committed by GitHub
parent a6b6816bec
commit faafcc7f87
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 164 additions and 10 deletions

View file

@ -1437,13 +1437,16 @@ Returns `boolean` - Whether the window's document has been edited.
#### `win.blurWebView()` #### `win.blurWebView()`
#### `win.capturePage([rect])` #### `win.capturePage([rect, opts])`
* `rect` [Rectangle](structures/rectangle.md) (optional) - The bounds to capture * `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) 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])` #### `win.loadURL(url[, options])`

View file

@ -1338,20 +1338,25 @@ const requestId = webContents.findInPage('api')
console.log(requestId) console.log(requestId)
``` ```
#### `contents.capturePage([rect])` #### `contents.capturePage([rect, opts])`
* `rect` [Rectangle](structures/rectangle.md) (optional) - The area of the page to be captured. * `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) 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. 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()` #### `contents.isBeingCaptured()`
Returns `boolean` - Whether this page is being captured. It returns true when the capturer count Returns `boolean` - Whether this page is being captured. It returns true when the capturer count
is large then 0. 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. * `size` [Size](structures/size.md) (optional) - The preferred size for the capturer.
* `stayHidden` boolean (optional) - Keep the page hidden instead of visible. * `stayHidden` boolean (optional) - Keep the page hidden instead of visible.
@ -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. 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. * `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. * `stayAwake` boolean (optional) - Keep the system awake instead of allowing it to sleep.
@ -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 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. decrease the hidden capturer count instead you should set `stayHidden` to true.
**Deprecated:** This API's functionality is now handled automatically within `contents.capturePage()`.
See [breaking changes](../breaking-changes.md).
#### `contents.getPrinters()` _Deprecated_ #### `contents.getPrinters()` _Deprecated_
Get the system printer list. Get the system printer list.

View file

@ -38,14 +38,98 @@ win.webContents.on('input-event', (_, event) => {
}) })
``` ```
### Removed: `webContents.incrementCapturerCount(stayHidden, stayAwake)`
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)`
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) ## 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()
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 ### 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). The `new-window` event of WebContents has been removed. It is replaced by [`webContents.setWindowOpenHandler()`](api/web-contents.md#contentssetwindowopenhandlerhandler).
```js ```js
// Removed in Electron 21 // Removed in Electron 22
webContents.on('new-window', (event) => { webContents.on('new-window', (event) => {
event.preventDefault() event.preventDefault()
}) })

View file

@ -386,11 +386,13 @@ base::IDMap<WebContents*>& GetAllWebContents() {
return *s_all_web_contents; return *s_all_web_contents;
} }
// Called when CapturePage is done.
void OnCapturePageDone(gin_helper::Promise<gfx::Image> promise, void OnCapturePageDone(gin_helper::Promise<gfx::Image> promise,
base::ScopedClosureRunner capture_handle,
const SkBitmap& bitmap) { const SkBitmap& bitmap) {
// Hack to enable transparency in captured image // Hack to enable transparency in captured image
promise.Resolve(gfx::Image::CreateFrom1xBitmap(bitmap)); promise.Resolve(gfx::Image::CreateFrom1xBitmap(bitmap));
capture_handle.RunAndReset();
} }
absl::optional<base::TimeDelta> GetCursorBlinkInterval() { absl::optional<base::TimeDelta> GetCursorBlinkInterval() {
@ -3174,13 +3176,22 @@ void WebContents::StartDrag(const gin_helper::Dictionary& item,
} }
v8::Local<v8::Promise> WebContents::CapturePage(gin::Arguments* args) { v8::Local<v8::Promise> WebContents::CapturePage(gin::Arguments* args) {
gfx::Rect rect;
gin_helper::Promise<gfx::Image> promise(args->isolate()); gin_helper::Promise<gfx::Image> promise(args->isolate());
v8::Local<v8::Promise> handle = promise.GetHandle(); v8::Local<v8::Promise> handle = promise.GetHandle();
// get rect arguments if they exist gfx::Rect rect;
args->GetNext(&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(); auto* const view = web_contents()->GetRenderWidgetHostView();
if (!view) { if (!view) {
promise.Resolve(gfx::Image()); promise.Resolve(gfx::Image());
@ -3199,6 +3210,9 @@ v8::Local<v8::Promise> WebContents::CapturePage(gin::Arguments* args) {
} }
#endif // BUILDFLAG(IS_MAC) #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|. // Capture full page if user doesn't specify a |rect|.
const gfx::Size view_size = const gfx::Size view_size =
rect.IsEmpty() ? view->GetViewBounds().size() : rect.size(); rect.IsEmpty() ? view->GetViewBounds().size() : rect.size();
@ -3215,11 +3229,18 @@ v8::Local<v8::Promise> WebContents::CapturePage(gin::Arguments* args) {
bitmap_size = gfx::ScaleToCeiledSize(view_size, scale); bitmap_size = gfx::ScaleToCeiledSize(view_size, scale);
view->CopyFromSurface(gfx::Rect(rect.origin(), view_size), bitmap_size, 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)));
return handle; return handle;
} }
// TODO(codebytere): remove in Electron v23.
void WebContents::IncrementCapturerCount(gin::Arguments* args) { 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; gfx::Size size;
bool stay_hidden = false; bool stay_hidden = false;
bool stay_awake = false; bool stay_awake = false;
@ -3236,7 +3257,13 @@ void WebContents::IncrementCapturerCount(gin::Arguments* args) {
.Release(); .Release();
} }
// TODO(codebytere): remove in Electron v23.
void WebContents::DecrementCapturerCount(gin::Arguments* args) { void WebContents::DecrementCapturerCount(gin::Arguments* args) {
EmitWarning(node::Environment::GetCurrent(args->isolate()),
"webContents.decrementCapturerCount() is deprecated and will be "
"removed in v23",
"electron");
bool stay_hidden = false; bool stay_hidden = false;
bool stay_awake = false; bool stay_awake = false;

View file

@ -1737,6 +1737,36 @@ describe('BrowserWindow module', () => {
expect(image.isEmpty()).to.equal(true); 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 () => { it('resolves after the window is hidden', async () => {
const w = new BrowserWindow({ show: false }); const w = new BrowserWindow({ show: false });
w.loadFile(path.join(fixtures, 'pages', 'a.html')); w.loadFile(path.join(fixtures, 'pages', 'a.html'));