fix: desktopCapturer breaks BrowserWindow resizable on macOS (#43044)

* fix: desktopCapturer breaks BrowserWindow resizable on macOS

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* test: oops fix showing

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
This commit is contained in:
trop[bot] 2024-07-25 15:35:23 +02:00 committed by GitHub
parent 097a3e9024
commit 139abe73a1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 34 additions and 1 deletions

View file

@ -1,3 +1,4 @@
import { BrowserWindow } from 'electron/main';
const { createDesktopCapturer } = process._linkedBinding('electron_browser_desktop_capturer');
const deepEqual = (a: ElectronInternal.GetSourcesOptions, b: ElectronInternal.GetSourcesOptions) => JSON.stringify(a) === JSON.stringify(b);
@ -15,6 +16,16 @@ function isValid (options: Electron.SourcesOptions) {
export async function getSources (args: Electron.SourcesOptions) {
if (!isValid(args)) throw new Error('Invalid options');
const resizableValues = new Map();
if (process.platform === 'darwin') {
// Fix for bug in ScreenCaptureKit that modifies a window's styleMask the first time
// it captures a non-resizable window. We record each non-resizable window's styleMask,
// and we restore modified styleMasks later, after the screen capture.
for (const win of BrowserWindow.getAllWindows()) {
resizableValues.set([win.id], win.resizable);
}
}
const captureWindow = args.types.includes('window');
const captureScreen = args.types.includes('screen');
@ -44,6 +55,14 @@ export async function getSources (args: Electron.SourcesOptions) {
delete capturer._onerror;
delete capturer._onfinished;
capturer = null;
if (process.platform === 'darwin') {
for (const win of BrowserWindow.getAllWindows()) {
if (resizableValues.has(win.id)) {
win.resizable = resizableValues.get(win.id);
}
};
}
}
// Remove from currentlyRunning once we resolve or reject
currentlyRunning = currentlyRunning.filter(running => running.options !== options);

View file

@ -22,7 +22,7 @@ std::string EnablePlatformSpecificFeatures() {
// kThumbnailCapturerMac,
// chrome/browser/media/webrtc/thumbnail_capturer_mac.mm
#if DCHECK_IS_ON()
return "";
return "ScreenCaptureKitPickerScreen,ScreenCaptureKitStreamPickerSonoma";
#else
return "ScreenCaptureKitPickerScreen,ScreenCaptureKitStreamPickerSonoma,"
"ThumbnailCapturerMac:capture_mode/sc_screenshot_manager";

View file

@ -148,6 +148,20 @@ ifdescribe(!process.arch.includes('arm') && process.platform !== 'win32')('deskt
}
});
// Regression test - see https://github.com/electron/electron/issues/43002
it('does not affect window resizable state', async () => {
w.resizable = false;
const wShown = once(w, 'show');
w.show();
await wShown;
const sources = await desktopCapturer.getSources({ types: ['window', 'screen'] });
expect(sources).to.be.an('array').that.is.not.empty();
expect(w.resizable).to.be.false();
});
it('moveAbove should move the window at the requested place', async () => {
// DesktopCapturer.getSources() is guaranteed to return in the correct
// z-order from foreground to background.