diff --git a/electron/service/window-service/index.ts b/electron/service/window-service/index.ts index 6d5ddf5..30b7a34 100644 --- a/electron/service/window-service/index.ts +++ b/electron/service/window-service/index.ts @@ -1,7 +1,7 @@ import type { WindowNames } from '@runtime/lib/types' import { CONFIG_KEYS, IPC_EVENTS, WINDOW_NAMES } from '@runtime/lib/constants' -import { BrowserWindow, BrowserWindowConstructorOptions, ipcMain, IpcMainInvokeEvent, type IpcMainEvent } from 'electron' +import { app, BrowserWindow, BrowserWindowConstructorOptions, ipcMain, IpcMainInvokeEvent, type IpcMainEvent } from 'electron' import { createLogo } from '@electron/utils' import logManager from '@electron/service/logger' @@ -9,6 +9,8 @@ import configManager from '@electron/service/config-service' import themeManager from '@electron/service/theme-service' import path from 'node:path'; +declare const MAIN_WINDOW_VITE_DEV_SERVER_URL: string | undefined; + interface WindowState { instance: BrowserWindow | void; isHidden: boolean; @@ -93,8 +95,7 @@ class WindowService { if (this.get(name)) return; const isHiddenWin = this._isHiddenWin(name); let window = this._createWinInstance(name, { ...size, ...moreOpts }); - - if (this.isDev) window.webContents.openDevTools() + this._setupDevtools(window, name); !isHiddenWin && this ._setupWinLifecycle(window, name) @@ -120,6 +121,41 @@ class WindowService { return window; } + private _setupDevtools(window: BrowserWindow, name: WindowNames) { + if (!this.isDev) return; + + let opened = false; + const openDevtools = () => { + if (opened || window.isDestroyed()) return; + opened = true; + + try { + window.webContents.openDevTools({ mode: 'detach', activate: true }); + logManager.info(`DevTools opened for window: ${name}`); + } catch (error) { + opened = false; + logManager.warn(`Failed to open DevTools for window: ${name}`, error); + } + }; + + window.webContents.once('did-finish-load', () => { + setTimeout(openDevtools, 150); + }); + + window.webContents.on('before-input-event', (_event, input) => { + const isMacDevtoolsShortcut = process.platform === 'darwin' && input.meta && input.alt && input.key.toLowerCase() === 'i'; + const isF12 = input.key === 'F12'; + if (!isF12 && !isMacDevtoolsShortcut) return; + + if (window.webContents.isDevToolsOpened()) { + window.webContents.closeDevTools(); + return; + } + + openDevtools(); + }); + } + private _setupWinLifecycle(window: BrowserWindow, name: WindowNames) { window.once('closed', () => { this._winStates[name].onClosed.forEach(callback => callback(window)); diff --git a/src/components/layout/MainLayout.tsx b/src/components/layout/MainLayout.tsx index 632a448..f2f3679 100644 --- a/src/components/layout/MainLayout.tsx +++ b/src/components/layout/MainLayout.tsx @@ -6,7 +6,7 @@ export default function MainLayout() { const platform = (window as any).api?.platform ?? ''; return ( -