这个函数是 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() 函数的代码,实际的代码可能更加复杂。

Atom 应用程序事件处理函数 handleEvents() 解释

原文地址: https://www.cveoy.top/t/topic/oWaX 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录