Skip to content

Commit

Permalink
Adding support for Windows to use navigator.mediaDevices.getDisplayMedia
Browse files Browse the repository at this point in the history
  • Loading branch information
axeleriksson147 committed Jan 27, 2025
1 parent 599a2f3 commit 205c846
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 11 deletions.
94 changes: 84 additions & 10 deletions src/app/display-media-request-handler.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,94 @@
import { session } from 'electron';
import { desktopCapturer, ipcMain, session } from 'electron';
import {
ICustomBrowserWindowConstructorOpts,
windowHandler,
} from './window-handler';
import { createComponentWindow, windowExists } from './window-utils';
import { logger } from '../common/logger';
import { isDevEnv, isMac } from '../common/env';
import { NOTIFICATION_WINDOW_TITLE } from '../common/api-interface';

/**
* This is currently supported only on macOS 15+.
* setDisplayMediaRequestHandler injects into navigator.mediaDevices.getDisplayMedia().
* With the macOS-only option { useSystemPicker: true },
* everyting is handled natively by the OS.
* For MacOS 15+ the { useSystemPicker: true } overrides the code set in the handler,
* and uses the native implementation.
*
* For all other OSes and versions, the regular screen share flow will be used.
* But for other versions and OSes, the code is executed.
*/
export const setDisplayMediaRequestHandler = () => {
const { defaultSession } = session;

defaultSession.setDisplayMediaRequestHandler(
async (_request, _callback) => {
// TODO - Add support for Windows.
async (_request, callback) => {
logger.info('display-media-request-handler: getting sources');
const sources = await desktopCapturer.getSources({
types: ['screen', 'window'],
thumbnailSize: {
height: 150,
width: 150,
},
});

const updatedSources = sources
.filter((source) => source.name !== NOTIFICATION_WINDOW_TITLE)
.map((source) => {
return {
...source,
...{
thumbnail: source.thumbnail.toDataURL(),
},
};
});

const browserWindowOptions: ICustomBrowserWindowConstructorOpts =
windowHandler.getWindowOpts(
{
alwaysOnTop: true,
autoHideMenuBar: true,
frame: false,
modal: false,
height: isMac ? 519 : 523,
width: 580,
show: false,
fullscreenable: false,
},
{
devTools: isDevEnv,
},
);
const screenPickerWindow = createComponentWindow(
'screen-picker',
browserWindowOptions,
);

screenPickerWindow.webContents.once('did-finish-load', () => {
if (!screenPickerWindow || !windowExists(screenPickerWindow)) {
return;
}
screenPickerWindow.webContents.send('screen-picker-data', {
sources: updatedSources,
});
});

const mainWebContents = windowHandler.getMainWebContents();
if (!mainWebContents) {
return;
}
mainWebContents.send('screen-picker-data', updatedSources);
ipcMain.on('screen-source-select', (_event, selectedSource) => {
// Draw screen share indicator and bring to front
logger.info(
'display-media-request-handler: source selected',
selectedSource,
);
});
ipcMain.once('screen-source-selected', (_event, selectedSource) => {
screenPickerWindow.close();
logger.info(
'display-media-request-handler: source to be shared',
selectedSource,
);
callback({ video: selectedSource });
});
},
{ useSystemPicker: true },
{ useSystemPicker: false }, // TODO - Temporary, revert back to true.
);
};
2 changes: 1 addition & 1 deletion src/app/window-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2513,7 +2513,7 @@ export class WindowHandler {
* @param windowOpts {Electron.BrowserWindowConstructorOptions}
* @param webPreferences {Electron.WebPreferences}
*/
private getWindowOpts(
public getWindowOpts(
windowOpts: Electron.BrowserWindowConstructorOptions,
webPreferences: Electron.WebPreferences,
): ICustomBrowserWindowConstructorOpts {
Expand Down

0 comments on commit 205c846

Please sign in to comment.