95 lines
3.1 KiB
TypeScript
95 lines
3.1 KiB
TypeScript
import { EventEmitter } from 'node:events';
|
|
import { describe, expect, it, vi } from 'vitest';
|
|
import { registerMainWindowClose } from '@electron/main/main-window-close';
|
|
|
|
class WindowStub extends EventEmitter {
|
|
fullscreen = false;
|
|
destroyed = false;
|
|
hide = vi.fn();
|
|
setFullScreen = vi.fn();
|
|
isFullScreen = () => this.fullscreen;
|
|
isDestroyed = () => this.destroyed;
|
|
close = vi.fn(() => {
|
|
const event = { defaultPrevented: false, preventDefault() { this.defaultPrevented = true; } };
|
|
this.emit('close', event);
|
|
if (!event.defaultPrevented) {
|
|
this.destroyed = true;
|
|
this.emit('closed');
|
|
}
|
|
});
|
|
leaveFullscreen(): void {
|
|
this.fullscreen = false;
|
|
this.emit('leave-full-screen');
|
|
}
|
|
}
|
|
|
|
function setup(fullscreen = false) {
|
|
const window = new WindowStub();
|
|
window.fullscreen = fullscreen;
|
|
let quitting = false;
|
|
registerMainWindowClose(window as never, {
|
|
platform: 'darwin', isQuitting: () => quitting, hideOnClose: false,
|
|
});
|
|
return { window, quit: () => { quitting = true; window.close(); } };
|
|
}
|
|
|
|
describe('native main window close', () => {
|
|
it('really destroys a normal macOS window instead of hiding it', () => {
|
|
const { window } = setup();
|
|
window.close();
|
|
expect(window.destroyed).toBe(true);
|
|
expect(window.hide).not.toHaveBeenCalled();
|
|
expect(window.setFullScreen).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('waits for the fullscreen exit before closing, including repeated clicks', () => {
|
|
const { window } = setup(true);
|
|
const order: string[] = [];
|
|
window.prependListener('leave-full-screen', () => order.push('left fullscreen'));
|
|
window.on('closed', () => order.push('closed'));
|
|
window.close();
|
|
window.close();
|
|
expect(window.destroyed).toBe(false);
|
|
expect(window.hide).not.toHaveBeenCalled();
|
|
expect(window.setFullScreen).toHaveBeenCalledExactlyOnceWith(false);
|
|
window.leaveFullscreen();
|
|
expect(window.destroyed).toBe(true);
|
|
expect(order).toEqual(['left fullscreen', 'closed']);
|
|
});
|
|
|
|
it('does not delay a real app quit while fullscreen exit is pending', () => {
|
|
const { window, quit } = setup(true);
|
|
window.close();
|
|
quit();
|
|
expect(window.destroyed).toBe(true);
|
|
window.leaveFullscreen();
|
|
expect(window.close).toHaveBeenCalledTimes(2);
|
|
});
|
|
|
|
it('lets Cmd+Q close a fullscreen window without starting another transition', () => {
|
|
const { window, quit } = setup(true);
|
|
quit();
|
|
expect(window.destroyed).toBe(true);
|
|
expect(window.setFullScreen).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('cancels deferred closing if the window was destroyed externally', () => {
|
|
const { window } = setup(true);
|
|
window.close();
|
|
window.destroyed = true;
|
|
window.emit('closed');
|
|
window.leaveFullscreen();
|
|
expect(window.close).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('preserves existing close-to-tray behavior on other platforms', () => {
|
|
const window = new WindowStub();
|
|
registerMainWindowClose(window as never, {
|
|
platform: 'win32', isQuitting: () => false, hideOnClose: true,
|
|
});
|
|
window.close();
|
|
expect(window.destroyed).toBe(false);
|
|
expect(window.hide).toHaveBeenCalledOnce();
|
|
});
|
|
});
|