diff --git a/docs/api/app.md b/docs/api/app.md index 884616740dae..485e693d2159 100755 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -500,16 +500,6 @@ gets emitted. **Note:** Extra command line arguments might be added by Chromium, such as `--original-process-start-time`. -### Event: 'desktop-capturer-get-sources' - -Returns: - -* `event` Event -* `webContents` [WebContents](web-contents.md) - -Emitted when `desktopCapturer.getSources()` is called in the renderer process of `webContents`. -Calling `event.preventDefault()` will make it return empty sources. - ## Methods The `app` object has the following methods: diff --git a/docs/api/command-line-switches.md b/docs/api/command-line-switches.md index 353abf12e0cb..f395379c063f 100644 --- a/docs/api/command-line-switches.md +++ b/docs/api/command-line-switches.md @@ -61,12 +61,6 @@ throttling in one window, you can take the hack of Forces the maximum disk space to be used by the disk cache, in bytes. -### --enable-api-filtering-logging - -Enables caller stack logging for the following APIs (filtering events): - -* `desktopCapturer.getSources()` / `desktop-capturer-get-sources` - ### --enable-logging[=file] Prints Chromium's logging to stderr (or a log file). diff --git a/docs/api/desktop-capturer.md b/docs/api/desktop-capturer.md index 236ae73666ca..97d74fb461d9 100644 --- a/docs/api/desktop-capturer.md +++ b/docs/api/desktop-capturer.md @@ -3,40 +3,49 @@ > Access information about media sources that can be used to capture audio and > video from the desktop using the [`navigator.mediaDevices.getUserMedia`] API. -Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process) +Process: [Main](../glossary.md#main-process) The following example shows how to capture video from a desktop window whose title is `Electron`: ```javascript -// In the renderer process. +// In the main process. const { desktopCapturer } = require('electron') desktopCapturer.getSources({ types: ['window', 'screen'] }).then(async sources => { for (const source of sources) { if (source.name === 'Electron') { - try { - const stream = await navigator.mediaDevices.getUserMedia({ - audio: false, - video: { - mandatory: { - chromeMediaSource: 'desktop', - chromeMediaSourceId: source.id, - minWidth: 1280, - maxWidth: 1280, - minHeight: 720, - maxHeight: 720 - } - } - }) - handleStream(stream) - } catch (e) { - handleError(e) - } + mainWindow.webContents.send('SET_SOURCE', source.id) return } } }) +``` + +```javascript +// In the preload script. +const { ipcRenderer } = require('electron') + +ipcRenderer.on('SET_SOURCE', async (event, sourceId) => { + try { + const stream = await navigator.mediaDevices.getUserMedia({ + audio: false, + video: { + mandatory: { + chromeMediaSource: 'desktop', + chromeMediaSourceId: sourceId, + minWidth: 1280, + maxWidth: 1280, + minHeight: 720, + maxHeight: 720 + } + } + }) + handleStream(stream) + } catch (e) { + handleError(e) + } +}) function handleStream (stream) { const video = document.querySelector('video') diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 2dcb370911f5..0e7927c7c734 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -856,15 +856,6 @@ Returns: Emitted when the renderer process sends a synchronous message via `ipcRenderer.sendSync()`. -#### Event: 'desktop-capturer-get-sources' - -Returns: - -* `event` Event - -Emitted when `desktopCapturer.getSources()` is called in the renderer process. -Calling `event.preventDefault()` will make it return empty sources. - #### Event: 'preferred-size-changed' Returns: diff --git a/filenames.auto.gni b/filenames.auto.gni index a705d306245f..297468d0c165 100644 --- a/filenames.auto.gni +++ b/filenames.auto.gni @@ -142,7 +142,6 @@ auto_filenames = { "lib/common/web-view-methods.ts", "lib/renderer/api/context-bridge.ts", "lib/renderer/api/crash-reporter.ts", - "lib/renderer/api/desktop-capturer.ts", "lib/renderer/api/ipc-renderer.ts", "lib/renderer/api/web-frame.ts", "lib/renderer/inspector.ts", @@ -224,7 +223,6 @@ auto_filenames = { "lib/browser/api/web-contents.ts", "lib/browser/api/web-frame-main.ts", "lib/browser/default-menu.ts", - "lib/browser/desktop-capturer.ts", "lib/browser/devtools.ts", "lib/browser/guest-view-manager.ts", "lib/browser/guest-window-manager.ts", @@ -271,7 +269,6 @@ auto_filenames = { "lib/common/webpack-provider.ts", "lib/renderer/api/context-bridge.ts", "lib/renderer/api/crash-reporter.ts", - "lib/renderer/api/desktop-capturer.ts", "lib/renderer/api/exports/electron.ts", "lib/renderer/api/ipc-renderer.ts", "lib/renderer/api/module-list.ts", @@ -309,7 +306,6 @@ auto_filenames = { "lib/common/webpack-provider.ts", "lib/renderer/api/context-bridge.ts", "lib/renderer/api/crash-reporter.ts", - "lib/renderer/api/desktop-capturer.ts", "lib/renderer/api/exports/electron.ts", "lib/renderer/api/ipc-renderer.ts", "lib/renderer/api/module-list.ts", diff --git a/lib/browser/api/desktop-capturer.ts b/lib/browser/api/desktop-capturer.ts index 2a958210e5f2..81af3a1eeb5f 100644 --- a/lib/browser/api/desktop-capturer.ts +++ b/lib/browser/api/desktop-capturer.ts @@ -1,5 +1,72 @@ -import { getSourcesImpl } from '@electron/internal/browser/desktop-capturer'; +const { createDesktopCapturer } = process._linkedBinding('electron_browser_desktop_capturer'); -export async function getSources (options: Electron.SourcesOptions) { - return getSourcesImpl(null, options); +const deepEqual = (a: ElectronInternal.GetSourcesOptions, b: ElectronInternal.GetSourcesOptions) => JSON.stringify(a) === JSON.stringify(b); + +let currentlyRunning: { + options: ElectronInternal.GetSourcesOptions; + getSources: Promise; +}[] = []; + +// |options.types| can't be empty and must be an array +function isValid (options: Electron.SourcesOptions) { + const types = options ? options.types : undefined; + return Array.isArray(types); +} + +export async function getSources (args: Electron.SourcesOptions) { + if (!isValid(args)) throw new Error('Invalid options'); + + const captureWindow = args.types.includes('window'); + const captureScreen = args.types.includes('screen'); + + const { thumbnailSize = { width: 150, height: 150 } } = args; + const { fetchWindowIcons = false } = args; + + const options = { + captureWindow, + captureScreen, + thumbnailSize, + fetchWindowIcons + }; + + for (const running of currentlyRunning) { + if (deepEqual(running.options, options)) { + // If a request is currently running for the same options + // return that promise + return running.getSources; + } + } + + const getSources = new Promise((resolve, reject) => { + let capturer: ElectronInternal.DesktopCapturer | null = createDesktopCapturer(); + + const stopRunning = () => { + if (capturer) { + delete capturer._onerror; + delete capturer._onfinished; + capturer = null; + } + // Remove from currentlyRunning once we resolve or reject + currentlyRunning = currentlyRunning.filter(running => running.options !== options); + }; + + capturer._onerror = (error: string) => { + stopRunning(); + reject(error); + }; + + capturer._onfinished = (sources: Electron.DesktopCapturerSource[]) => { + stopRunning(); + resolve(sources); + }; + + capturer.startHandling(captureWindow, captureScreen, thumbnailSize, fetchWindowIcons); + }); + + currentlyRunning.push({ + options, + getSources + }); + + return getSources; } diff --git a/lib/browser/desktop-capturer.ts b/lib/browser/desktop-capturer.ts deleted file mode 100644 index 397f2ca51c2b..000000000000 --- a/lib/browser/desktop-capturer.ts +++ /dev/null @@ -1,82 +0,0 @@ -const { createDesktopCapturer } = process._linkedBinding('electron_browser_desktop_capturer'); - -const deepEqual = (a: ElectronInternal.GetSourcesOptions, b: ElectronInternal.GetSourcesOptions) => JSON.stringify(a) === JSON.stringify(b); - -let currentlyRunning: { - options: ElectronInternal.GetSourcesOptions; - getSources: Promise; -}[] = []; - -// |options.types| can't be empty and must be an array -function isValid (options: Electron.SourcesOptions) { - const types = options ? options.types : undefined; - return Array.isArray(types); -} - -export const getSourcesImpl = (sender: Electron.WebContents | null, args: Electron.SourcesOptions) => { - if (!isValid(args)) throw new Error('Invalid options'); - - const captureWindow = args.types.includes('window'); - const captureScreen = args.types.includes('screen'); - - const { thumbnailSize = { width: 150, height: 150 } } = args; - const { fetchWindowIcons = false } = args; - - const options = { - captureWindow, - captureScreen, - thumbnailSize, - fetchWindowIcons - }; - - for (const running of currentlyRunning) { - if (deepEqual(running.options, options)) { - // If a request is currently running for the same options - // return that promise - return running.getSources; - } - } - - const getSources = new Promise((resolve, reject) => { - let capturer: ElectronInternal.DesktopCapturer | null = createDesktopCapturer(); - - const stopRunning = () => { - if (capturer) { - delete capturer._onerror; - delete capturer._onfinished; - capturer = null; - } - // Remove from currentlyRunning once we resolve or reject - currentlyRunning = currentlyRunning.filter(running => running.options !== options); - if (sender) { - sender.removeListener('destroyed', stopRunning); - } - }; - - capturer._onerror = (error: string) => { - stopRunning(); - reject(error); - }; - - capturer._onfinished = (sources: Electron.DesktopCapturerSource[]) => { - stopRunning(); - resolve(sources); - }; - - capturer.startHandling(captureWindow, captureScreen, thumbnailSize, fetchWindowIcons); - - // If the WebContents is destroyed before receiving result, just remove the - // reference to emit and the capturer itself so that it never dispatches - // back to the renderer - if (sender) { - sender.once('destroyed', stopRunning); - } - }); - - currentlyRunning.push({ - options, - getSources - }); - - return getSources; -}; diff --git a/lib/browser/rpc-server.ts b/lib/browser/rpc-server.ts index e67b76b3c99c..affa21a19d64 100644 --- a/lib/browser/rpc-server.ts +++ b/lib/browser/rpc-server.ts @@ -1,30 +1,9 @@ -import { app } from 'electron/main'; -import type { WebContents } from 'electron/main'; import { clipboard } from 'electron/common'; import * as fs from 'fs'; import { ipcMainInternal } from '@electron/internal/browser/ipc-main-internal'; import * as ipcMainUtils from '@electron/internal/browser/ipc-main-internal-utils'; import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages'; -import type * as desktopCapturerModule from '@electron/internal/browser/desktop-capturer'; - -const eventBinding = process._linkedBinding('electron_browser_event'); - -const emitCustomEvent = function (contents: WebContents, eventName: string, ...args: any[]) { - const event = eventBinding.createWithSender(contents); - - app.emit(eventName, event, contents, ...args); - contents.emit(eventName, event, ...args); - - return event; -}; - -const logStack = function (contents: WebContents, code: string, stack: string) { - if (stack) { - console.warn(`WebContents (${contents.id}): ${code}`, stack); - } -}; - // Implements window.close() ipcMainInternal.on(IPC_MESSAGES.BROWSER_WINDOW_CLOSE, function (event) { const window = event.sender.getOwnerBrowserWindow(); @@ -58,22 +37,6 @@ ipcMainUtils.handleSync(IPC_MESSAGES.BROWSER_CLIPBOARD_SYNC, function (event, me return (clipboard as any)[method](...args); }); -if (BUILDFLAG(ENABLE_DESKTOP_CAPTURER)) { - const desktopCapturer = require('@electron/internal/browser/desktop-capturer') as typeof desktopCapturerModule; - - ipcMainInternal.handle(IPC_MESSAGES.DESKTOP_CAPTURER_GET_SOURCES, async function (event, options: Electron.SourcesOptions, stack: string) { - logStack(event.sender, 'desktopCapturer.getSources()', stack); - const customEvent = emitCustomEvent(event.sender, 'desktop-capturer-get-sources'); - - if (customEvent.defaultPrevented) { - console.error('Blocked desktopCapturer.getSources()'); - return []; - } - - return await desktopCapturer.getSourcesImpl(event.sender, options); - }); -} - const getPreloadScript = async function (preloadPath: string) { let preloadSrc = null; let preloadError = null; diff --git a/lib/common/ipc-messages.ts b/lib/common/ipc-messages.ts index 48432d129876..5e626a3dfdf8 100644 --- a/lib/common/ipc-messages.ts +++ b/lib/common/ipc-messages.ts @@ -28,6 +28,4 @@ export const enum IPC_MESSAGES { INSPECTOR_CONFIRM = 'INSPECTOR_CONFIRM', INSPECTOR_CONTEXT_MENU = 'INSPECTOR_CONTEXT_MENU', INSPECTOR_SELECT_FILE = 'INSPECTOR_SELECT_FILE', - - DESKTOP_CAPTURER_GET_SOURCES = 'DESKTOP_CAPTURER_GET_SOURCES', } diff --git a/lib/renderer/api/desktop-capturer.ts b/lib/renderer/api/desktop-capturer.ts deleted file mode 100644 index 15a02e792d84..000000000000 --- a/lib/renderer/api/desktop-capturer.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal'; -import deprecate from '@electron/internal/common/api/deprecate'; -import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages'; - -const { hasSwitch } = process._linkedBinding('electron_common_command_line'); - -const enableStacks = hasSwitch('enable-api-filtering-logging'); - -function getCurrentStack () { - const target = {}; - if (enableStacks) { - Error.captureStackTrace(target, getCurrentStack); - } - return (target as any).stack; -} - -let warned = process.noDeprecation; -export async function getSources (options: Electron.SourcesOptions) { - if (!warned) { - deprecate.log('The use of \'desktopCapturer.getSources\' in the renderer process is deprecated and will be removed. See https://www.electronjs.org/docs/breaking-changes#removed-desktopcapturergetsources-in-the-renderer for more details.'); - warned = true; - } - return await ipcRendererInternal.invoke(IPC_MESSAGES.DESKTOP_CAPTURER_GET_SOURCES, options, getCurrentStack()); -} diff --git a/lib/renderer/api/module-list.ts b/lib/renderer/api/module-list.ts index e4612c3f41d9..5f9d2154c5c6 100644 --- a/lib/renderer/api/module-list.ts +++ b/lib/renderer/api/module-list.ts @@ -5,10 +5,3 @@ export const rendererModuleList: ElectronInternal.ModuleEntry[] = [ { name: 'ipcRenderer', loader: () => require('./ipc-renderer') }, { name: 'webFrame', loader: () => require('./web-frame') } ]; - -if (BUILDFLAG(ENABLE_DESKTOP_CAPTURER)) { - rendererModuleList.push({ - name: 'desktopCapturer', - loader: () => require('@electron/internal/renderer/api/desktop-capturer') - }); -} diff --git a/lib/sandboxed_renderer/api/module-list.ts b/lib/sandboxed_renderer/api/module-list.ts index dafa6c578736..91d075eebc1c 100644 --- a/lib/sandboxed_renderer/api/module-list.ts +++ b/lib/sandboxed_renderer/api/module-list.ts @@ -26,10 +26,3 @@ export const moduleList: ElectronInternal.ModuleEntry[] = [ private: true } ]; - -if (BUILDFLAG(ENABLE_DESKTOP_CAPTURER)) { - moduleList.push({ - name: 'desktopCapturer', - loader: () => require('@electron/internal/renderer/api/desktop-capturer') - }); -} diff --git a/shell/browser/electron_browser_client.cc b/shell/browser/electron_browser_client.cc index 105d8d3ded2e..4267d2f308cd 100644 --- a/shell/browser/electron_browser_client.cc +++ b/shell/browser/electron_browser_client.cc @@ -592,8 +592,7 @@ void ElectronBrowserClient::AppendExtraCommandLineSwitches( switches::kStandardSchemes, switches::kEnableSandbox, switches::kSecureSchemes, switches::kBypassCSPSchemes, switches::kCORSSchemes, switches::kFetchSchemes, - switches::kServiceWorkerSchemes, switches::kEnableApiFilteringLogging, - switches::kStreamingSchemes}; + switches::kServiceWorkerSchemes, switches::kStreamingSchemes}; command_line->CopySwitchesFrom(*base::CommandLine::ForCurrentProcess(), kCommonSwitchNames, base::size(kCommonSwitchNames)); diff --git a/shell/common/options_switches.cc b/shell/common/options_switches.cc index 3738126a297c..15d854d19912 100644 --- a/shell/common/options_switches.cc +++ b/shell/common/options_switches.cc @@ -241,8 +241,6 @@ const char kAppUserModelId[] = "app-user-model-id"; // The application path const char kAppPath[] = "app-path"; -const char kEnableApiFilteringLogging[] = "enable-api-filtering-logging"; - // The command line switch versions of the options. const char kScrollBounce[] = "scroll-bounce"; diff --git a/shell/common/options_switches.h b/shell/common/options_switches.h index d69912e5db64..bf800586853a 100644 --- a/shell/common/options_switches.h +++ b/shell/common/options_switches.h @@ -118,7 +118,6 @@ extern const char kCORSSchemes[]; extern const char kStreamingSchemes[]; extern const char kAppUserModelId[]; extern const char kAppPath[]; -extern const char kEnableApiFilteringLogging[]; extern const char kScrollBounce[]; extern const char kNodeIntegrationInWorker[]; diff --git a/spec-main/api-app-spec.ts b/spec-main/api-app-spec.ts index 7144d96dfe23..97bc0688ea63 100644 --- a/spec-main/api-app-spec.ts +++ b/spec-main/api-app-spec.ts @@ -12,8 +12,6 @@ import { closeWindow, closeAllWindows } from './window-helpers'; import { ifdescribe, ifit } from './spec-helpers'; import split = require('split') -const features = process._linkedBinding('electron_common_features'); - const fixturesPath = path.resolve(__dirname, '../spec/fixtures'); describe('electron module', () => { @@ -462,25 +460,6 @@ describe('app module', () => { expect(webContents).to.equal(w.webContents); expect(details.reason).to.be.oneOf(['crashed', 'abnormal-exit']); }); - - ifdescribe(features.isDesktopCapturerEnabled())('desktopCapturer module filtering', () => { - it('should emit desktop-capturer-get-sources event when desktopCapturer.getSources() is invoked', async () => { - w = new BrowserWindow({ - show: false, - webPreferences: { - nodeIntegration: true, - contextIsolation: false - } - }); - await w.loadURL('about:blank'); - - const promise = emittedOnce(app, 'desktop-capturer-get-sources'); - w.webContents.executeJavaScript('require(\'electron\').desktopCapturer.getSources({ types: [\'screen\'] })'); - - const [, webContents] = await promise; - expect(webContents).to.equal(w.webContents); - }); - }); }); describe('app.badgeCount', () => { diff --git a/spec-main/api-desktop-capturer-spec.ts b/spec-main/api-desktop-capturer-spec.ts index cfcc1e6c4dfc..74e2bc73722a 100644 --- a/spec-main/api-desktop-capturer-spec.ts +++ b/spec-main/api-desktop-capturer-spec.ts @@ -1,6 +1,5 @@ import { expect } from 'chai'; -import { screen, BrowserWindow, SourcesOptions } from 'electron/main'; -import { desktopCapturer } from 'electron/common'; +import { screen, desktopCapturer, BrowserWindow } from 'electron/main'; import { emittedOnce } from './events-helpers'; import { ifdescribe, ifit } from './spec-helpers'; import { closeAllWindows } from './window-helpers'; @@ -23,76 +22,55 @@ ifdescribe(!process.arch.includes('arm') && process.platform !== 'win32')('deskt after(closeAllWindows); - const getSources: typeof desktopCapturer.getSources = (options: SourcesOptions) => { - return w.webContents.executeJavaScript(` - require('electron').desktopCapturer.getSources(${JSON.stringify(options)}).then(m => JSON.parse(JSON.stringify(m))) - `); - }; + // TODO(nornagon): figure out why this test is failing on Linux and re-enable it. + ifit(process.platform !== 'linux')('should return a non-empty array of sources', async () => { + const sources = await desktopCapturer.getSources({ types: ['window', 'screen'] }); + expect(sources).to.be.an('array').that.is.not.empty(); + }); - const generateSpecs = (description: string, getSources: typeof desktopCapturer.getSources) => { - describe(description, () => { - // TODO(nornagon): figure out why this test is failing on Linux and re-enable it. - ifit(process.platform !== 'linux')('should return a non-empty array of sources', async () => { - const sources = await getSources({ types: ['window', 'screen'] }); - expect(sources).to.be.an('array').that.is.not.empty(); - }); + it('throws an error for invalid options', async () => { + const promise = desktopCapturer.getSources(['window', 'screen'] as any); + await expect(promise).to.be.eventually.rejectedWith(Error, 'Invalid options'); + }); - it('throws an error for invalid options', async () => { - const promise = getSources(['window', 'screen'] as any); - await expect(promise).to.be.eventually.rejectedWith(Error, 'Invalid options'); - }); + // TODO(nornagon): figure out why this test is failing on Linux and re-enable it. + ifit(process.platform !== 'linux')('does not throw an error when called more than once (regression)', async () => { + const sources1 = await desktopCapturer.getSources({ types: ['window', 'screen'] }); + expect(sources1).to.be.an('array').that.is.not.empty(); - // TODO(nornagon): figure out why this test is failing on Linux and re-enable it. - ifit(process.platform !== 'linux')('does not throw an error when called more than once (regression)', async () => { - const sources1 = await getSources({ types: ['window', 'screen'] }); - expect(sources1).to.be.an('array').that.is.not.empty(); + const sources2 = await desktopCapturer.getSources({ types: ['window', 'screen'] }); + expect(sources2).to.be.an('array').that.is.not.empty(); + }); - const sources2 = await getSources({ types: ['window', 'screen'] }); - expect(sources2).to.be.an('array').that.is.not.empty(); - }); + ifit(process.platform !== 'linux')('responds to subsequent calls of different options', async () => { + const promise1 = desktopCapturer.getSources({ types: ['window'] }); + await expect(promise1).to.eventually.be.fulfilled(); - ifit(process.platform !== 'linux')('responds to subsequent calls of different options', async () => { - const promise1 = getSources({ types: ['window'] }); - await expect(promise1).to.eventually.be.fulfilled(); + const promise2 = desktopCapturer.getSources({ types: ['screen'] }); + await expect(promise2).to.eventually.be.fulfilled(); + }); - const promise2 = getSources({ types: ['screen'] }); - await expect(promise2).to.eventually.be.fulfilled(); - }); + // Linux doesn't return any window sources. + ifit(process.platform !== 'linux')('returns an empty display_id for window sources on Windows and Mac', async () => { + const w = new BrowserWindow({ width: 200, height: 200 }); + await w.loadURL('about:blank'); - // Linux doesn't return any window sources. - ifit(process.platform !== 'linux')('returns an empty display_id for window sources on Windows and Mac', async () => { - const w = new BrowserWindow({ width: 200, height: 200 }); - await w.loadURL('about:blank'); + const sources = await desktopCapturer.getSources({ types: ['window'] }); + w.destroy(); + expect(sources).to.be.an('array').that.is.not.empty(); + for (const { display_id: displayId } of sources) { + expect(displayId).to.be.a('string').and.be.empty(); + } + }); - const sources = await getSources({ types: ['window'] }); - w.destroy(); - expect(sources).to.be.an('array').that.is.not.empty(); - for (const { display_id: displayId } of sources) { - expect(displayId).to.be.a('string').and.be.empty(); - } - }); + ifit(process.platform !== 'linux')('returns display_ids matching the Screen API on Windows and Mac', async () => { + const displays = screen.getAllDisplays(); + const sources = await desktopCapturer.getSources({ types: ['screen'] }); + expect(sources).to.be.an('array').of.length(displays.length); - ifit(process.platform !== 'linux')('returns display_ids matching the Screen API on Windows and Mac', async () => { - const displays = screen.getAllDisplays(); - const sources = await getSources({ types: ['screen'] }); - expect(sources).to.be.an('array').of.length(displays.length); - - for (let i = 0; i < sources.length; i++) { - expect(sources[i].display_id).to.equal(displays[i].id.toString()); - } - }); - }); - }; - - generateSpecs('in renderer process', getSources); - generateSpecs('in main process', desktopCapturer.getSources); - - ifit(process.platform !== 'linux')('returns an empty source list if blocked by the main process', async () => { - w.webContents.once('desktop-capturer-get-sources', (event) => { - event.preventDefault(); - }); - const sources = await getSources({ types: ['screen'] }); - expect(sources).to.be.empty(); + for (let i = 0; i < sources.length; i++) { + expect(sources[i].display_id).to.equal(displays[i].id.toString()); + } }); it('disabling thumbnail should return empty images', async () => { @@ -101,14 +79,10 @@ ifdescribe(!process.arch.includes('arm') && process.platform !== 'win32')('deskt w2.show(); await wShown; - const isEmpties: boolean[] = await w.webContents.executeJavaScript(` - require('electron').desktopCapturer.getSources({ - types: ['window', 'screen'], - thumbnailSize: { width: 0, height: 0 } - }).then((sources) => { - return sources.map(s => s.thumbnail.constructor.name === 'NativeImage' && s.thumbnail.isEmpty()) - }) - `); + const isEmpties: boolean[] = (await desktopCapturer.getSources({ + types: ['window', 'screen'], + thumbnailSize: { width: 0, height: 0 } + })).map(s => s.thumbnail.constructor.name === 'NativeImage' && s.thumbnail.isEmpty()); w2.destroy(); expect(isEmpties).to.be.an('array').that.is.not.empty(); @@ -125,7 +99,7 @@ ifdescribe(!process.arch.includes('arm') && process.platform !== 'win32')('deskt await wFocused; const mediaSourceId = w.getMediaSourceId(); - const sources = await getSources({ + const sources = await desktopCapturer.getSources({ types: ['window'], thumbnailSize: { width: 0, height: 0 } }); @@ -161,7 +135,7 @@ ifdescribe(!process.arch.includes('arm') && process.platform !== 'win32')('deskt const ids = mediaSourceId.split(':'); expect(ids[1]).to.not.equal(ids[2]); - const sources = await getSources({ + const sources = await desktopCapturer.getSources({ types: ['window'], thumbnailSize: { width: 0, height: 0 } }); @@ -206,7 +180,7 @@ ifdescribe(!process.arch.includes('arm') && process.platform !== 'win32')('deskt // DesktopCapturer.getSources() returns sources sorted from foreground to // background, i.e. top to bottom. - let sources = await getSources({ + let sources = await desktopCapturer.getSources({ types: ['window'], thumbnailSize: { width: 0, height: 0 } }); @@ -252,7 +226,7 @@ ifdescribe(!process.arch.includes('arm') && process.platform !== 'win32')('deskt } }); - sources = await getSources({ + sources = await desktopCapturer.getSources({ types: ['window'], thumbnailSize: { width: 0, height: 0 } });