docs: fix setDisplayMediaRequestHandler migration examples

Address review feedback on the desktopCapturer deprecation docs:

- Fix broken anchor link in the deprecation banner (was pointing at
  #sessetdisplaymediarequesthandleropts, now correctly points at
  #sessetdisplaymediarequesthandlerhandler-opts).
- Rewrite the "After (recommended)" migration example to gate
  useSystemPicker on desktopCapturer.isDisplayMediaSystemPickerAvailable()
  so the snippet works on Windows, Linux, and macOS < 15 (the previous
  version called callback({}) unconditionally and rejected
  getDisplayMedia on every non-macOS-15 platform).
- Document desktopCapturer.isDisplayMediaSystemPickerAvailable(), which
  has been a runtime export since #43581 but was never added to the
  reference docs.
- Update the top-level quickstart comment and prose to match what the
  example actually does (tab self-capture, not "first screen found").
- Mirror the platform-aware pattern in session.md.
- Fill in the real PR URL (#51235) in the getSources deprecated YAML
  block, drop the unused navigator.mediaDevices.getUserMedia link
  definition, and normalize migration-guide list markers to asterisks
  so lint:docs passes after the anchor fix exposes the pre-existing
  lint failures.

Notes: none
This commit is contained in:
George Xu
2026-04-30 22:37:02 -07:00
parent 4f84efa1ea
commit 8165fd0571
2 changed files with 38 additions and 27 deletions

View File

@@ -7,13 +7,13 @@ Process: [Main](../glossary.md#main-process)
> [!WARNING]
> The `desktopCapturer` module is deprecated. Use
> [`session.setDisplayMediaRequestHandler`](session.md#sessetdisplaymediarequesthandleropts)
> [`session.setDisplayMediaRequestHandler`](session.md#sessetdisplaymediarequesthandlerhandler-opts)
> instead, which aligns with the web-standard
> [`navigator.mediaDevices.getDisplayMedia`](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia)
> API. See the [migration guide](#migrating-from-getsources-to-setdisplaymediarequesthandler) below.
The following example shows how to capture video from a desktop window whose
title is `Electron`:
The following example shows how to respond to a `getDisplayMedia` request by
letting the requesting tab capture itself:
```js
// main.js
@@ -23,7 +23,7 @@ app.whenReady().then(() => {
const mainWindow = new BrowserWindow()
session.defaultSession.setDisplayMediaRequestHandler((request, callback) => {
// Grant access to the first screen found.
// Allow the requesting tab to capture itself.
callback({ video: request.frame })
})
@@ -90,7 +90,7 @@ changes:
description: "This method now returns a Promise instead of using a callback function."
breaking-changes-header: api-changed-callback-based-versions-of-promisified-apis
deprecated:
- pr-url: https://github.com/electron/electron/pull/XXXXX
- pr-url: https://github.com/electron/electron/pull/51235
```
-->
@@ -114,8 +114,20 @@ Returns `Promise<DesktopCapturerSource[]>` - Resolves with an array of [`Desktop
> * Capturing audio requires `NSAudioCaptureUsageDescription` Info.plist key on macOS 14.2 Sonoma and higher - [read more](#macos-versions-142-or-higher).
> * Capturing the screen contents requires user consent on macOS 10.15 Catalina or higher, which can detected by [`systemPreferences.getMediaAccessStatus`][].
### `desktopCapturer.isDisplayMediaSystemPickerAvailable()` _macOS_ _Experimental_
<!--
```YAML history
added:
- pr-url: https://github.com/electron/electron/pull/43581
```
-->
Returns `boolean` - Whether the native macOS [`SCContentSharingPicker`](https://developer.apple.com/documentation/screencapturekit/sccontentsharingpicker) is available. Returns `true` on macOS 15 and later, `false` on earlier macOS versions and all non-macOS platforms.
Use this to decide whether to pass `useSystemPicker: true` to [`session.setDisplayMediaRequestHandler`](session.md#sessetdisplaymediarequesthandlerhandler-opts) — see the [migration guide](#migrating-from-getsources-to-setdisplaymediarequesthandler) below for an example.
[`navigator.mediaDevices.getDisplayMedia`]: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia
[`navigator.mediaDevices.getUserMedia`]: https://developer.mozilla.org/en/docs/Web/API/MediaDevices/getUserMedia
[`systemPreferences.getMediaAccessStatus`]: system-preferences.md#systempreferencesgetmediaaccessstatusmediatype-windows-macos
## Caveats
@@ -173,12 +185,12 @@ which aligns with the web-standard [`navigator.mediaDevices.getDisplayMedia`][]
### Why migrate?
- **Web standards alignment** — `getDisplayMedia()` is the web-standard API for screen
* **Web standards alignment** — `getDisplayMedia()` is the web-standard API for screen
capture. Using `setDisplayMediaRequestHandler` lets you integrate with it directly.
- **Platform integration** — On macOS 15+, setting `useSystemPicker: true` invokes the
* **Platform integration** — On macOS 15+, setting `useSystemPicker: true` invokes the
native OS screen picker (SCContentSharingPicker), providing a familiar UX and
correct permissions handling.
- **Simpler architecture** — The handler receives the request when the renderer calls
* **Simpler architecture** — The handler receives the request when the renderer calls
`getDisplayMedia()` and you respond with the chosen source. No need to pre-enumerate
sources.
@@ -202,29 +214,28 @@ app.whenReady().then(() => {
### After (recommended)
For most apps, using the system picker is the simplest approach:
On macOS 15+, the native OS picker (SCContentSharingPicker) is available. On
other platforms you must provide your own picker UI. A cross-platform handler
typically branches on `desktopCapturer.isDisplayMediaSystemPickerAvailable()`:
```js
const { app, BrowserWindow, session } = require('electron')
const { app, BrowserWindow, desktopCapturer, session } = require('electron')
app.whenReady().then(() => {
const mainWindow = new BrowserWindow()
// The OS presents its own picker; the handler is not invoked.
session.defaultSession.setDisplayMediaRequestHandler((request, callback) => {
// On macOS 15+, useSystemPicker: true causes the OS to present its own
// picker and the handler is not invoked. This branch runs everywhere else
// (Windows, Linux, and macOS < 15) — show your own picker UI here and
// call callback with the selected source, e.g. via desktopCapturer.getSources().
callback({})
}, { useSystemPicker: true })
}, { useSystemPicker: desktopCapturer.isDisplayMediaSystemPickerAvailable() })
mainWindow.loadFile('index.html')
})
```
If you need a custom picker UI, handle the request directly:
```js
session.defaultSession.setDisplayMediaRequestHandler((request, callback) => {
// request.preferredDisplaySurface is 'monitor', 'window', 'browser', or 'none'
// Show your custom picker UI, then call callback with the selected source.
// For tab capture, pass a WebFrameMain:
callback({ video: request.frame })
})
`request.preferredDisplaySurface` (`'monitor'`, `'window'`, `'browser'`, or
`'none'`) indicates what kind of surface the caller asked for, and can be used
to drive the filtering in your custom picker UI.

View File

@@ -1063,14 +1063,14 @@ This option is experimental, and currently available for MacOS 15+ only. If the
is set to `true`, the handler will not be invoked.
```js
const { session } = require('electron')
const { desktopCapturer, session } = require('electron')
session.defaultSession.setDisplayMediaRequestHandler((request, callback) => {
// Allow the tab to capture itself.
// Runs on Windows, Linux, and macOS < 15. On macOS 15+ (where
// useSystemPicker is effective) the OS presents its own picker and this
// handler is not invoked.
callback({ video: request.frame })
// On macOS 15+, use the native system picker if available.
// When the system picker is used, the handler will not be invoked.
}, { useSystemPicker: true })
}, { useSystemPicker: desktopCapturer.isDisplayMediaSystemPickerAvailable() })
```
Passing a [WebFrameMain](web-frame-main.md) object as a video or audio stream