Atom 应用程序事件处理函数 handleEvents() 解释
这个函数是 Atom 应用程序的事件处理程序,它用于处理各种应用程序事件,例如退出、打开文件、打开文档等。它还包括与窗口管理相关的事件处理程序,例如最小化、最大化、关闭窗口等。此函数还通过 IPC 与渲染进程通信,以响应来自渲染进程的命令和事件。
handleEvents() {
const createOpenSettings = ({ event, sameWindow }) => {
const targetWindow = event
? this.atomWindowForEvent(event)
: this.focusedWindow();
return {
devMode: targetWindow ? targetWindow.devMode : false,
safeMode: targetWindow ? targetWindow.safeMode : false,
window: sameWindow && targetWindow ? targetWindow : null
};
};
this.on('application:quit', () => app.quit());
this.on('application:new-window', () =>
this.openPath(createOpenSettings({}))
);
this.on('application:new-file', () =>
(this.focusedWindow() || this).openPath()
);
this.on('application:open-dev', () =>
this.promptForPathToOpen('all', { devMode: true })
);
this.on('application:open-safe', () =>
this.promptForPathToOpen('all', { safeMode: true })
);
this.on('application:inspect', ({ x, y, atomWindow }) => {
if (!atomWindow) atomWindow = this.focusedWindow();
if (atomWindow) atomWindow.browserWindow.inspectElement(x, y);
});
this.on('application:open-documentation', () =>
shell.openExternal('http://flight-manual.atom.io')
);
this.on('application:open-discussions', () =>
shell.openExternal('https://github.com/atom/atom/discussions')
);
this.on('application:open-faq', () =>
shell.openExternal('https://atom.io/faq')
);
this.on('application:open-terms-of-use', () =>
shell.openExternal('https://atom.io/terms')
);
this.on('application:report-issue', () =>
shell.openExternal(
'https://github.com/atom/atom/blob/master/CONTRIBUTING.md#reporting-bugs'
)
);
this.on('application:search-issues', () =>
shell.openExternal('https://github.com/search?q=+is%3Aissue+user%3Aatom')
);
this.on('application:install-update', () => {
this.quitting = true;
this.quittingForUpdate = true;
this.autoUpdateManager.install();
});
this.on('application:check-for-update', () =>
this.autoUpdateManager.check()
);
if (process.platform === 'darwin') {
this.on('application:reopen-project', ({ paths }) => {
const focusedWindow = this.focusedWindow();
if (focusedWindow) {
const { safeMode, devMode } = focusedWindow;
this.openPaths({ pathsToOpen: paths, safeMode, devMode });
return;
}
this.openPaths({ pathsToOpen: paths });
});
this.on('application:open', () => {
this.promptForPathToOpen(
'all',
createOpenSettings({ sameWindow: true }),
getDefaultPath()
);
});
this.on('application:open-file', () => {
this.promptForPathToOpen(
'file',
createOpenSettings({ sameWindow: true }),
getDefaultPath()
);
});
this.on('application:open-folder', () => {
this.promptForPathToOpen(
'folder',
createOpenSettings({ sameWindow: true }),
getDefaultPath()
);
});
this.on('application:bring-all-windows-to-front', () =>
Menu.sendActionToFirstResponder('arrangeInFront:')
);
this.on('application:hide', () =>
Menu.sendActionToFirstResponder('hide:')
);
this.on('application:hide-other-applications', () =>
Menu.sendActionToFirstResponder('hideOtherApplications:')
);
this.on('application:minimize', () =>
Menu.sendActionToFirstResponder('performMiniaturize:')
);
this.on('application:unhide-all-applications', () =>
Menu.sendActionToFirstResponder('unhideAllApplications:')
);
this.on('application:zoom', () =>
Menu.sendActionToFirstResponder('zoom:')
);
} else {
this.on('application:minimize', () => {
const window = this.focusedWindow();
if (window) window.minimize();
});
this.on('application:zoom', function() {
const window = this.focusedWindow();
if (window) window.maximize();
});
}
this.openPathOnEvent('application:about', 'atom://about');
this.openPathOnEvent('application:show-settings', 'atom://config');
this.openPathOnEvent('application:open-your-config', 'atom://.atom/config');
this.openPathOnEvent(
'application:open-your-init-script',
'atom://.atom/init-script'
);
this.openPathOnEvent('application:open-your-keymap', 'atom://.atom/keymap');
this.openPathOnEvent(
'application:open-your-snippets',
'atom://.atom/snippets'
);
this.openPathOnEvent(
'application:open-your-stylesheet',
'atom://.atom/stylesheet'
);
this.openPathOnEvent(
'application:open-license',
path.join(process.resourcesPath, 'LICENSE.md')
);
this.configFile.onDidChange(settings => {
for (let window of this.getAllWindows()) {
window.didChangeUserSettings(settings);
}
this.config.resetUserSettings(settings);
});
this.configFile.onDidError(message => {
const window = this.focusedWindow() || this.getLastFocusedWindow();
if (window) {
window.didFailToReadUserSettings(message);
} else {
console.error(message);
}
});
this.disposable.add(
ipcHelpers.on(app, 'before-quit', async event => {
let resolveBeforeQuitPromise;
this.lastBeforeQuitPromise = new Promise(resolve => {
resolveBeforeQuitPromise = resolve;
});
if (!this.quitting) {
this.quitting = true;
event.preventDefault();
const windowUnloadPromises = this.getAllWindows().map(
async window => {
const unloaded = await window.prepareToUnload();
if (unloaded) {
window.close();
await window.closedPromise;
}
return unloaded;
}
);
const windowUnloadedResults = await Promise.all(windowUnloadPromises);
if (windowUnloadedResults.every(Boolean)) {
app.quit();
} else {
this.quitting = false;
}
}
resolveBeforeQuitPromise();
})
);
this.disposable.add(
ipcHelpers.on(app, 'will-quit', () => {
this.killAllProcesses();
return Promise.all([
this.deleteSocketFile(),
this.deleteSocketSecretFile()
]);
})
);
// See: https://www.electronjs.org/docs/api/app#event-window-all-closed
this.disposable.add(
ipcHelpers.on(app, 'window-all-closed', () => {
if (this.applicationMenu != null) {
this.applicationMenu.enableWindowSpecificItems(false);
}
// Don't quit when the last window is closed on macOS.
if (process.platform !== 'darwin') {
app.quit();
}
})
);
// Triggered by the 'open-file' event from Electron:
// https://electronjs.org/docs/api/app#event-open-file-macos
// For example, this is fired when a file is dragged and dropped onto the Atom application icon in the dock.
this.disposable.add(
ipcHelpers.on(app, 'open-file', (event, pathToOpen) => {
event.preventDefault();
this.openPath({ pathToOpen });
})
);
this.disposable.add(
ipcHelpers.on(app, 'open-url', (event, urlToOpen) => {
event.preventDefault();
this.openUrl({
urlToOpen,
devMode: this.devMode,
safeMode: this.safeMode
});
})
);
this.disposable.add(
ipcHelpers.on(app, 'activate', (event, hasVisibleWindows) => {
if (hasVisibleWindows) return;
if (event) event.preventDefault();
this.emit('application:new-window');
})
);
this.disposable.add(
ipcHelpers.on(ipcMain, 'restart-application', () => {
this.restart();
})
);
this.disposable.add(
ipcHelpers.on(ipcMain, 'resolve-proxy', async (event, requestId, url) => {
const proxy = await event.sender.session.resolveProxy(url);
if (!event.sender.isDestroyed())
event.sender.send('did-resolve-proxy', requestId, proxy);
})
);
this.disposable.add(
ipcHelpers.on(ipcMain, 'did-change-history-manager', event => {
for (let atomWindow of this.getAllWindows()) {
const { webContents } = atomWindow.browserWindow;
if (webContents !== event.sender)
webContents.send('did-change-history-manager');
}
})
);
// A request from the associated render process to open a set of paths using the standard window location logic.
// Used for application:reopen-project.
this.disposable.add(
ipcHelpers.on(ipcMain, 'open', (event, options) => {
if (options) {
if (typeof options.pathsToOpen === 'string') {
options.pathsToOpen = [options.pathsToOpen];
}
if (options.here) {
options.window = this.atomWindowForEvent(event);
}
if (options.pathsToOpen && options.pathsToOpen.length > 0) {
this.openPaths(options);
} else {
this.addWindow(this.createWindow(options));
}
} else {
this.promptForPathToOpen('all', {});
}
})
);
// Prompt for a file, folder, or either, then open the chosen paths. Files will be opened in the originating
// window; folders will be opened in a new window unless an existing window exactly contains all of them.
this.disposable.add(
ipcHelpers.on(ipcMain, 'open-chosen-any', (event, defaultPath) => {
this.promptForPathToOpen(
'all',
createOpenSettings({ event, sameWindow: true }),
defaultPath
);
})
);
this.disposable.add(
ipcHelpers.on(ipcMain, 'open-chosen-file', (event, defaultPath) => {
this.promptForPathToOpen(
'file',
createOpenSettings({ event, sameWindow: true }),
defaultPath
);
})
);
this.disposable.add(
ipcHelpers.on(ipcMain, 'open-chosen-folder', (event, defaultPath) => {
this.promptForPathToOpen(
'folder',
createOpenSettings({ event }),
defaultPath
);
})
);
this.disposable.add(
ipcHelpers.on(
ipcMain,
'update-application-menu',
(event, template, menu) => {
const window = BrowserWindow.fromWebContents(event.sender);
if (this.applicationMenu)
this.applicationMenu.update(window, template, menu);
}
)
);
this.disposable.add(
ipcHelpers.on(
ipcMain,
'run-package-specs',
(event, packageSpecPath, options = {}) => {
this.runTests(
Object.assign(
{
resourcePath: this.devResourcePath,
pathsToOpen: [packageSpecPath],
headless: false
},
options
)
);
}
)
);
this.disposable.add(
ipcHelpers.on(ipcMain, 'run-benchmarks', (event, benchmarksPath) => {
this.runBenchmarks({
resourcePath: this.devResourcePath,
pathsToOpen: [benchmarksPath],
headless: false,
test: false
});
})
);
this.disposable.add(
ipcHelpers.on(ipcMain, 'command', (event, command) => {
this.emit(command);
})
);
this.disposable.add(
ipcHelpers.on(ipcMain, 'window-command', (event, command, ...args) => {
const window = BrowserWindow.fromWebContents(event.sender);
return window && window.emit(command, ...args);
})
);
this.disposable.add(
ipcHelpers.respondTo(
'window-method',
(browserWindow, method, ...args) => {
const window = this.atomWindowForBrowserWindow(browserWindow);
if (window) window[method](...args);
}
)
);
this.disposable.add(
ipcHelpers.on(ipcMain, 'pick-folder', (event, responseChannel) => {
this.promptForPath('folder', paths =>
event.sender.send(responseChannel, paths)
);
})
);
this.disposable.add(
ipcHelpers.respondTo('set-window-size', (window, width, height) => {
window.setSize(width, height);
})
);
this.disposable.add(
ipcHelpers.respondTo('set-window-position', (window, x, y) => {
window.setPosition(x, y);
})
);
this.disposable.add(
ipcHelpers.respondTo(
'set-user-settings',
(window, settings, filePath) => {
if (!this.quitting) {
return ConfigFile.at(filePath || this.configFilePath).update(
JSON.parse(settings)
);
}
}
)
);
this.disposable.add(
ipcHelpers.respondTo('center-window', window => window.center())
);
this.disposable.add(
ipcHelpers.respondTo('focus-window', window => window.focus())
);
this.disposable.add(
ipcHelpers.respondTo('show-window', window => window.show())
);
this.disposable.add(
ipcHelpers.respondTo('hide-window', window => window.hide())
);
this.disposable.add(
ipcHelpers.respondTo(
'get-temporary-window-state',
window => window.temporaryState
)
);
this.disposable.add(
ipcHelpers.respondTo('set-temporary-window-state', (win, state) => {
win.temporaryState = state;
})
);
this.disposable.add(
ipcHelpers.on(
ipcMain,
'write-text-to-selection-clipboard',
(event, text) => clipboard.writeText(text, 'selection')
)
);
this.disposable.add(
ipcHelpers.on(ipcMain, 'write-to-stdout', (event, output) =>
process.stdout.write(output)
)
);
this.disposable.add(
ipcHelpers.on(ipcMain, 'write-to-stderr', (event, output) =>
process.stderr.write(output)
)
);
this.disposable.add(
ipcHelpers.on(ipcMain, 'add-recent-document', (event, filename) =>
app.addRecentDocument(filename)
)
);
this.disposable.add(
ipcHelpers.on(
ipcMain,
'execute-javascript-in-dev-tools',
(event, code) =>
event.sender.devToolsWebContents &&
event.sender.devToolsWebContents.executeJavaScript(code)
)
);
this.disposable.add(
ipcHelpers.on(ipcMain, 'get-auto-update-manager-state', event => {
event.returnValue = this.autoUpdateManager.getState();
})
);
this.disposable.add(
ipcHelpers.on(ipcMain, 'get-auto-update-manager-error', event => {
event.returnValue = this.autoUpdateManager.getErrorMessage();
})
);
this.disposable.add(
ipcHelpers.respondTo('will-save-path', (window, path) =>
this.fileRecoveryService.willSavePath(window, path)
)
);
this.disposable.add(
ipcHelpers.respondTo('did-save-path', (window, path) =>
this.fileRecoveryService.didSavePath(window, path)
)
);
this.disposable.add(this.disableZoomOnDisplayChange());
}
该函数使用 this.on() 方法注册了各种事件监听器,例如 'application:quit'、'application:new-window'、'application:open-file' 等,并在事件发生时执行相应的回调函数。
同时,该函数也使用了 ipcHelpers 对象来监听来自渲染进程的 IPC 消息,并通过 event.sender 对象发送响应消息。
总的来说,handleEvents() 函数是 Atom 应用程序的核心事件处理函数,它负责处理各种应用程序事件和 IPC 消息,并与渲染进程进行交互,以保证应用程序的正常运行。
以下是一些值得注意的点:
- 该函数使用了
createOpenSettings()函数来创建打开文件或文件夹时的配置参数。 - 该函数使用
this.openPath()函数打开文件或文件夹,使用this.promptForPathToOpen()函数提示用户选择要打开的文件或文件夹。 - 该函数使用
shell.openExternal()函数打开外部网站。 - 该函数使用
app.quit()函数退出应用程序。 - 该函数使用
this.autoUpdateManager对象处理应用程序更新。 - 该函数使用
this.getAllWindows()函数获取所有打开的窗口。 - 该函数使用
ipcHelpers对象与渲染进程进行交互。
注意: 此代码示例只展示了部分 handleEvents() 函数的代码,实际的代码可能更加复杂。
原文地址: https://www.cveoy.top/t/topic/oWaX 著作权归作者所有。请勿转载和采集!