From 195d3953e46a7fbe0a1c0e2a9d060399fe964efa Mon Sep 17 00:00:00 2001 From: chyoo Date: Fri, 3 Jul 2026 10:38:21 +0900 Subject: [PATCH] fix electron titlebar context menu freeze --- src/main/index.ts | 14 ++++++- src/renderer/src/components/TitleBar.tsx | 51 ++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/src/main/index.ts b/src/main/index.ts index b77364a..e0f969d 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -617,6 +617,16 @@ function attachDevToolsShortcut(window: BrowserWindow): void { }) } +function suppressSystemContextMenu(window: BrowserWindow): void { + type SystemContextMenuWindow = BrowserWindow & { + on(event: 'system-context-menu', listener: (event: { preventDefault: () => void }) => void): BrowserWindow + } + + ;(window as SystemContextMenuWindow).on('system-context-menu', (event) => { + event.preventDefault() + }) +} + function createWindow(): void { const appWindows = new Map() const appProcesses = new Map() @@ -634,6 +644,7 @@ function createWindow(): void { } }) attachDevToolsShortcut(mainWindow) + suppressSystemContextMenu(mainWindow) mainWindow.on('ready-to-show', () => { setTimeout(() => { @@ -822,7 +833,7 @@ function createWindow(): void { } const existingProc = appProcesses.get(appName) if (existingProc) { - if (is.dev && handoffCode && audienceApp !== 'ADS IDE') { + if (handoffCode) { existingProc.kill() appProcesses.delete(appName) } else { @@ -928,6 +939,7 @@ function createWindow(): void { }) appWindows.set(appName, appWin) attachDevToolsShortcut(appWin) + suppressSystemContextMenu(appWin) if (is.dev && process.env['ELECTRON_RENDERER_URL']) { appWin.loadURL(process.env['ELECTRON_RENDERER_URL']) diff --git a/src/renderer/src/components/TitleBar.tsx b/src/renderer/src/components/TitleBar.tsx index 9bcfd8a..51c75ac 100644 --- a/src/renderer/src/components/TitleBar.tsx +++ b/src/renderer/src/components/TitleBar.tsx @@ -16,17 +16,27 @@ function TitleBar({ appName }: TitleBarProps): React.JSX.Element { event.preventDefault() event.stopPropagation() } - + const handleWindowControlMouseDown = (event: React.MouseEvent): void => { + if (event.button !== 0) suppressTitlebarContextMenu(event) + } + const releaseWindowControlFocus = (event: React.SyntheticEvent): void => { + event.currentTarget.blur() + } + const windowControlStyle = { WebkitAppRegion: 'no-drag' } as React.CSSProperties const winBtn = - 'flex h-[20px] w-[20px] items-center justify-center text-white/50 hover:text-white transition cursor-pointer' + 'flex h-[20px] w-[20px] items-center justify-center text-white/50 hover:text-white transition cursor-pointer focus:outline-none' return ( <>
{ + if (event.button === 2) suppressTitlebarContextMenu(event) + }} onMouseDown={(event) => { if (event.button === 2) suppressTitlebarContextMenu(event) }} @@ -48,17 +58,50 @@ function TitleBar({ appName }: TitleBarProps): React.JSX.Element { className="flex items-center gap-3" style={{ WebkitAppRegion: 'no-drag' } as React.CSSProperties} > - -