Skip to content

Commit 6ef6bcd

Browse files
authored
refactor(main): move window-all-closed listener to main class (podman-desktop#11468)
Signed-off-by: axel7083 <42176370+axel7083@users.noreply.github.com>
1 parent 4913454 commit 6ef6bcd

File tree

3 files changed

+80
-12
lines changed

3 files changed

+80
-12
lines changed

packages/main/src/index.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,6 @@ app.on('second-instance', (_event, _args, _workingDirectory, additionalData: unk
5656
});
5757
});
5858

59-
/**
60-
* Shout down background process if all windows was closed
61-
*/
62-
app.on('window-all-closed', () => {
63-
if (!isMac()) {
64-
app.quit();
65-
}
66-
});
67-
6859
app.once('before-quit', event => {
6960
if (!extensionLoader) {
7061
stoppedExtensions.val = true;

packages/main/src/main.spec.ts

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
* SPDX-License-Identifier: Apache-2.0
1717
***********************************************************************/
1818
import type { App as ElectronApp } from 'electron';
19-
import { afterEach, beforeEach, expect, test, vi } from 'vitest';
19+
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
2020

2121
import { SecurityRestrictions } from '/@/security-restrictions.js';
22-
import { isWindows } from '/@/util.js';
22+
import { isLinux, isMac, isWindows } from '/@/util.js';
2323

2424
import { Main } from './main.js';
2525

@@ -34,6 +34,7 @@ const ELECTRON_APP_MOCK: ElectronApp = {
3434
requestSingleInstanceLock: vi.fn(),
3535
setAppUserModelId: vi.fn(),
3636
quit: vi.fn(),
37+
on: vi.fn(),
3738
} as unknown as ElectronApp;
3839

3940
let PROCESS_EXIT_ORIGINAL: typeof process.exit;
@@ -87,3 +88,64 @@ test('on windows setAppUserModelId should be called', async () => {
8788

8889
expect(ELECTRON_APP_MOCK.setAppUserModelId).toHaveBeenCalledWith(ELECTRON_APP_MOCK.name);
8990
});
91+
92+
// Utility type definition for {@link ElectronApp.on} and {@link WebContents.on}
93+
type Listener = (...args: unknown[]) => void;
94+
95+
/**
96+
* Utility function to get listener register in {@link ELECTRON_APP_MOCK.on}
97+
* @remarks cannot found any way to properly infer type based on event value (see https://github.com/microsoft/TypeScript/issues/53439)
98+
* @param event
99+
*/
100+
function findElectronAppListener(event: string): Listener | undefined {
101+
expect(ELECTRON_APP_MOCK.on).toHaveBeenCalledWith(event, expect.any(Function));
102+
return vi.mocked(ELECTRON_APP_MOCK.on).mock.calls.find(([mEvent]) => mEvent === event)?.[1];
103+
}
104+
105+
/**
106+
* Based on {@link findElectronAppListener}, throw an error if the result is undefined
107+
* @param event
108+
*/
109+
function getElectronAppListener(event: string): Listener {
110+
const listener = findElectronAppListener(event);
111+
if (!listener) throw new Error(`cannot found listener for event ${event}`);
112+
return listener;
113+
}
114+
115+
describe('ElectronApp#on window-all-closed', () => {
116+
let code: Main;
117+
beforeEach(() => {
118+
code = new Main(ELECTRON_APP_MOCK);
119+
code.main([]);
120+
});
121+
122+
test('listener should be registered on init', () => {
123+
expect(ELECTRON_APP_MOCK.on).toHaveBeenCalledWith('window-all-closed', expect.any(Function));
124+
});
125+
126+
test('listener should be a valid function', () => {
127+
const listener = findElectronAppListener('window-all-closed');
128+
expect(listener).toBeDefined();
129+
expect(listener).toBeInstanceOf(Function);
130+
});
131+
132+
test('listener should not call ElectronApp#quit on mac', () => {
133+
vi.mocked(isMac).mockReturnValue(true);
134+
135+
const listener = getElectronAppListener('window-all-closed');
136+
listener();
137+
138+
expect(ELECTRON_APP_MOCK.quit).not.toHaveBeenCalled();
139+
});
140+
141+
test.each(['windows', 'linux'])('listener should not call ElectronApp#quit on %s', platform => {
142+
vi.mocked(isMac).mockReturnValue(false);
143+
vi.mocked(isWindows).mockReturnValue(platform === 'windows');
144+
vi.mocked(isLinux).mockReturnValue(platform === 'linux');
145+
146+
const listener = getElectronAppListener('window-all-closed');
147+
listener();
148+
149+
expect(ELECTRON_APP_MOCK.quit).toHaveBeenCalledOnce();
150+
});
151+
});

packages/main/src/main.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import type { App as ElectronApp, BrowserWindow } from 'electron';
1919

2020
import { SecurityRestrictions } from '/@/security-restrictions.js';
21-
import { isWindows } from '/@/util.js';
21+
import { isMac, isWindows } from '/@/util.js';
2222

2323
import { Deferred } from './plugin/util/deferred.js';
2424
import { ProtocolLauncher } from './protocol-launcher.js';
@@ -86,5 +86,20 @@ export class Main {
8686
if (isWindows()) {
8787
this.app.setAppUserModelId(this.app.name);
8888
}
89+
90+
/**
91+
* Setup {@link ElectronApp.on} listeners
92+
*/
93+
this.app.on('window-all-closed', this.onWindowAllClosed.bind(this));
94+
}
95+
96+
/**
97+
* Listener for {@link ElectronApp.on('window-all-closed')} event
98+
* Shout down background process if all windows was closed
99+
*/
100+
protected onWindowAllClosed(): void {
101+
if (!isMac()) {
102+
this.app.quit();
103+
}
89104
}
90105
}

0 commit comments

Comments
 (0)