mirror of
https://github.com/toeverything/AFFiNE.git
synced 2025-01-03 19:23:37 +03:00
fix(electron): optimize electron open/close on mac (#6224)
1. never close main window on mac to allow it to be quickly open 1. make the browser show a bit faster 2. brought up app window when clicking some menu items
This commit is contained in:
parent
4f5907766f
commit
65ab6c89bf
@ -2,6 +2,7 @@ import { app, Menu } from 'electron';
|
||||
|
||||
import { isMacOS } from '../../shared/utils';
|
||||
import { revealLogFile } from '../logger';
|
||||
import { initAndShowMainWindow } from '../main-window';
|
||||
import { checkForUpdates } from '../updater';
|
||||
import { applicationMenuSubjects } from './subject';
|
||||
|
||||
@ -42,7 +43,9 @@ export function createApplicationMenu() {
|
||||
id: MENUITEM_NEW_PAGE,
|
||||
label: 'New Doc',
|
||||
accelerator: isMac ? 'Cmd+N' : 'Ctrl+N',
|
||||
click: () => {
|
||||
click: async () => {
|
||||
await initAndShowMainWindow();
|
||||
// fixme: if the window is just created, the new page action will not be triggered
|
||||
applicationMenuSubjects.newPageAction.next();
|
||||
},
|
||||
},
|
||||
@ -100,7 +103,12 @@ export function createApplicationMenu() {
|
||||
{ type: 'separator' },
|
||||
{ role: 'front' },
|
||||
{ type: 'separator' },
|
||||
{ role: 'window' },
|
||||
{
|
||||
role: 'window',
|
||||
click: async () => {
|
||||
await initAndShowMainWindow();
|
||||
},
|
||||
},
|
||||
]
|
||||
: [{ role: 'close' }]),
|
||||
],
|
||||
@ -125,6 +133,7 @@ export function createApplicationMenu() {
|
||||
{
|
||||
label: 'Check for Updates',
|
||||
click: async () => {
|
||||
await initAndShowMainWindow();
|
||||
await checkForUpdates();
|
||||
},
|
||||
},
|
||||
|
@ -52,9 +52,7 @@ if (!isSingleInstance) {
|
||||
* Shout down background process if all windows was closed
|
||||
*/
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit();
|
||||
}
|
||||
app.quit();
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -27,6 +27,14 @@ const getWindowAdditionalArguments = async () => {
|
||||
];
|
||||
};
|
||||
|
||||
function closeAllWindows() {
|
||||
BrowserWindow.getAllWindows().forEach(w => {
|
||||
if (!w.isDestroyed()) {
|
||||
w.destroy();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function createWindow(additionalArguments: string[]) {
|
||||
logger.info('create window');
|
||||
const mainWindowState = electronWindowState({
|
||||
@ -82,12 +90,7 @@ async function createWindow(additionalArguments: string[]) {
|
||||
* @see https://github.com/electron/electron/issues/25012
|
||||
*/
|
||||
browserWindow.on('ready-to-show', () => {
|
||||
if (IS_DEV) {
|
||||
// do not gain focus in dev mode
|
||||
browserWindow.showInactive();
|
||||
} else {
|
||||
browserWindow.show();
|
||||
}
|
||||
helperConnectionUnsub?.();
|
||||
helperConnectionUnsub = helperProcessManager.connectRenderer(
|
||||
browserWindow.webContents
|
||||
);
|
||||
@ -96,15 +99,26 @@ async function createWindow(additionalArguments: string[]) {
|
||||
});
|
||||
|
||||
browserWindow.on('close', e => {
|
||||
e.preventDefault();
|
||||
// close and destroy all windows
|
||||
BrowserWindow.getAllWindows().forEach(w => {
|
||||
if (!w.isDestroyed()) {
|
||||
w.destroy();
|
||||
}
|
||||
});
|
||||
helperConnectionUnsub?.();
|
||||
// TODO: gracefully close the app, for example, ask user to save unsaved changes
|
||||
e.preventDefault();
|
||||
if (!isMacOS()) {
|
||||
closeAllWindows();
|
||||
} else {
|
||||
// hide window on macOS
|
||||
// application quit will be handled by closing the hidden window
|
||||
//
|
||||
// explanation:
|
||||
// - closing the top window (by clicking close button or CMD-w)
|
||||
// - will be captured in "close" event here
|
||||
// - hiding the app to make the app open faster when user click the app icon
|
||||
// - quit the app by "cmd+q" or right click on the dock icon and select "quit"
|
||||
// - all browser windows will capture the "close" event
|
||||
// - the hidden window will close all windows
|
||||
// - "window-all-closed" event will be emitted and eventually quit the app
|
||||
browserWindow.hide();
|
||||
}
|
||||
helperConnectionUnsub?.();
|
||||
helperConnectionUnsub = undefined;
|
||||
});
|
||||
|
||||
browserWindow.on('leave-full-screen', () => {
|
||||
@ -148,15 +162,37 @@ async function createWindow(additionalArguments: string[]) {
|
||||
// singleton
|
||||
let browserWindow$: Promise<BrowserWindow> | undefined;
|
||||
|
||||
// a hidden window that prevents the app from quitting on MacOS
|
||||
let hiddenMacWindow: BrowserWindow | undefined;
|
||||
|
||||
/**
|
||||
* Init main BrowserWindow. Will create a new window if it's not created yet.
|
||||
*/
|
||||
export async function initMainWindow() {
|
||||
export async function initAndShowMainWindow() {
|
||||
if (!browserWindow$ || (await browserWindow$.then(w => w.isDestroyed()))) {
|
||||
const additionalArguments = await getWindowAdditionalArguments();
|
||||
browserWindow$ = createWindow(additionalArguments);
|
||||
}
|
||||
const mainWindow = await browserWindow$;
|
||||
|
||||
if (IS_DEV) {
|
||||
// do not gain focus in dev mode
|
||||
mainWindow.showInactive();
|
||||
} else {
|
||||
mainWindow.show();
|
||||
}
|
||||
|
||||
if (!hiddenMacWindow && isMacOS()) {
|
||||
hiddenMacWindow = new BrowserWindow({
|
||||
show: false,
|
||||
width: 100,
|
||||
height: 100,
|
||||
});
|
||||
hiddenMacWindow.on('close', () => {
|
||||
closeAllWindows();
|
||||
});
|
||||
}
|
||||
|
||||
return mainWindow;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ import { getLinkPreview } from 'link-preview-js';
|
||||
import { isMacOS } from '../../shared/utils';
|
||||
import { persistentConfig } from '../config-storage/persist';
|
||||
import { logger } from '../logger';
|
||||
import { getMainWindow, initMainWindow } from '../main-window';
|
||||
import { getMainWindow, initAndShowMainWindow } from '../main-window';
|
||||
import { getOnboardingWindow } from '../onboarding';
|
||||
import type { NamespaceHandlers } from '../type';
|
||||
import { launchStage } from '../windows-manager/stage';
|
||||
@ -58,7 +58,7 @@ export const uiHandlers = {
|
||||
try {
|
||||
const onboarding = await getOnboardingWindow();
|
||||
onboarding?.hide();
|
||||
await initMainWindow();
|
||||
await initAndShowMainWindow();
|
||||
// need to destroy onboarding window after main window is ready
|
||||
// otherwise the main window will be closed as well
|
||||
onboarding?.destroy();
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { logger } from '../logger';
|
||||
import { initMainWindow } from '../main-window';
|
||||
import { initAndShowMainWindow } from '../main-window';
|
||||
import {
|
||||
getOnboardingWindow,
|
||||
getOrCreateOnboardingWindow,
|
||||
@ -12,7 +12,7 @@ import { launchStage } from './stage';
|
||||
export async function launch() {
|
||||
const stage = launchStage.value;
|
||||
if (stage === 'main') {
|
||||
initMainWindow().catch(e => {
|
||||
initAndShowMainWindow().catch(e => {
|
||||
logger.error('Failed to restore or create window:', e);
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user