fix: Do not activate app when calling focus on inactive panel window (#40465)

* fix: Do not activate app when calling focus on inactive panel window

Co-authored-by: Felix Rieseberg <fr@makenotion.com>

* Use activate

Co-authored-by: Felix Rieseberg <fr@makenotion.com>

* Use "activate" for all windows

Co-authored-by: Felix Rieseberg <fr@makenotion.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Felix Rieseberg <fr@makenotion.com>
This commit is contained in:
trop[bot]
2023-11-10 15:40:47 -05:00
committed by GitHub
parent bc07c3be54
commit b92b4c8fcf
2 changed files with 48 additions and 1 deletions

View File

@@ -469,7 +469,20 @@ void NativeWindowMac::Focus(bool focus) {
return;
if (focus) {
[[NSApplication sharedApplication] activateIgnoringOtherApps:NO];
// On macOS < Sonoma, "activateIgnoringOtherApps:NO" would not
// activate apps if focusing a window that is inActive. That
// changed with macOS Sonoma.
//
// There's a slim chance we should have never called
// activateIgnoringOtherApps, but we tried that many years ago
// and saw weird focus bugs on other macOS versions. So, to make
// this safe, we're gating by versions.
if (@available(macOS 14.0, *)) {
[[NSApplication sharedApplication] activate];
} else {
[[NSApplication sharedApplication] activateIgnoringOtherApps:NO];
}
[window_ makeKeyAndOrderFront:nil];
} else {
[window_ orderOut:nil];

View File

@@ -1196,6 +1196,40 @@ describe('BrowserWindow module', () => {
await isClosed3;
}
});
ifit(process.platform === 'darwin')('it does not activate the app if focusing an inactive panel', async () => {
// Show to focus app, then remove existing window
w.show();
w.destroy();
// We first need to resign app focus for this test to work
const isInactive = once(app, 'did-resign-active');
childProcess.execSync('osascript -e \'tell application "Finder" to activate\'');
await isInactive;
// Create new window
w = new BrowserWindow({
type: 'panel',
height: 200,
width: 200,
center: true,
show: false
});
const isShow = once(w, 'show');
const isFocus = once(w, 'focus');
w.showInactive();
w.focus();
await isShow;
await isFocus;
const getActiveAppOsa = 'tell application "System Events" to get the name of the first process whose frontmost is true';
const activeApp = childProcess.execSync(`osascript -e '${getActiveAppOsa}'`).toString().trim();
expect(activeApp).to.equal('Finder');
});
});
// TODO(RaisinTen): Make this work on Windows too.