'use strict' const {ipcMain} = require('electron') const {desktopCapturer} = process.atomBinding('desktop_capturer') const deepEqual = (a, b) => JSON.stringify(a) === JSON.stringify(b) // A queue for holding all requests from renderer process. let requestsQueue = [] const electronSources = 'ELECTRON_BROWSER_DESKTOP_CAPTURER_GET_SOURCES' const capturerResult = (id) => `ELECTRON_RENDERER_DESKTOP_CAPTURER_RESULT_${id}` ipcMain.on(electronSources, (event, captureWindow, captureScreen, thumbnailSize, id) => { const request = { id, options: { captureWindow, captureScreen, thumbnailSize }, webContents: event.sender } requestsQueue.push(request) if (requestsQueue.length === 1) { desktopCapturer.startHandling(captureWindow, captureScreen, thumbnailSize) } // If the WebContents is destroyed before receiving result, just remove the // reference from requestsQueue to make the module not send the result to it. event.sender.once('destroyed', () => { request.webContents = null }) }) desktopCapturer.emit = (event, name, sources) => { // Receiving sources result from main process, now send them back to renderer. const handledRequest = requestsQueue.shift() const handledWebContents = handledRequest.webContents const unhandledRequestsQueue = [] const result = sources.map(source => { return { id: source.id, name: source.name, thumbnail: source.thumbnail.toDataURL() } }) if (handledWebContents) { handledWebContents.send(capturerResult(handledRequest.id), result) } // Check the queue to see whether there is another identical request & handle requestsQueue.forEach(request => { const webContents = request.webContents if (deepEqual(handledRequest.options, request.options)) { if (webContents) webContents.send(capturerResult(request.id), result) } else { unhandledRequestsQueue.push(request) } }) requestsQueue = unhandledRequestsQueue // If the requestsQueue is not empty, start a new request handling. if (requestsQueue.length > 0) { const {captureWindow, captureScreen, thumbnailSize} = requestsQueue[0].options return desktopCapturer.startHandling(captureWindow, captureScreen, thumbnailSize) } }