fix electron titlebar context menu freeze

This commit is contained in:
chyoo
2026-07-03 10:38:39 +09:00
parent a50c7c6945
commit 429fceda43
2 changed files with 73 additions and 4 deletions
+11
View File
@@ -3119,6 +3119,16 @@ function attachDevToolsShortcut(win: BrowserWindow): void {
})
}
function suppressSystemContextMenu(win: BrowserWindow): void {
type SystemContextMenuWindow = BrowserWindow & {
on(event: 'system-context-menu', listener: (event: { preventDefault: () => void }) => void): BrowserWindow
}
;(win as SystemContextMenuWindow).on('system-context-menu', (event) => {
event.preventDefault()
})
}
function toggleFocusedDevTools(): void {
const target = BrowserWindow.getFocusedWindow()
if (!target) return
@@ -3178,6 +3188,7 @@ function createWindow(): void {
})
attachDevToolsShortcut(mainWindow)
suppressSystemContextMenu(mainWindow)
mainWindow.once('ready-to-show', () => {
setTimeout(() => {
splashWindow?.close()
+62 -4
View File
@@ -445,14 +445,24 @@ export default function TitleBar({ user, accessToken = '', onHelpClick, onOpenCo
event.preventDefault()
event.stopPropagation()
}
const handleWindowControlMouseDown = (event: React.MouseEvent<HTMLButtonElement>): void => {
if (event.button !== 0) suppressTitlebarContextMenu(event)
}
const releaseWindowControlFocus = (event: React.SyntheticEvent<HTMLButtonElement>): void => {
event.currentTarget.blur()
}
const windowControlStyle = { WebkitAppRegion: 'no-drag' } as React.CSSProperties
return (
<>
<header
className="relative z-[10020] flex h-[38px] shrink-0 items-center justify-between rounded-t-[18px] bg-[#111520] px-3 pl-5"
style={{ WebkitAppRegion: 'drag' } as React.CSSProperties}
onContextMenuCapture={suppressTitlebarContextMenu}
onContextMenu={suppressTitlebarContextMenu}
onMouseDownCapture={(event) => {
if (event.button === 2) suppressTitlebarContextMenu(event)
}}
onMouseDown={(event) => {
if (event.button === 2) suppressTitlebarContextMenu(event)
}}
@@ -648,13 +658,61 @@ export default function TitleBar({ user, accessToken = '', onHelpClick, onOpenCo
) : null}
</div>
<div className="ml-1 flex items-center gap-0.5">
<button type="button" aria-label="Minimize" className={winButton} onClick={() => window.titlebar.minimize()}>
<button
type="button"
tabIndex={-1}
aria-label="Minimize"
className={winButton}
style={windowControlStyle}
onClick={(event) => {
releaseWindowControlFocus(event)
window.titlebar.minimize()
}}
onPointerDownCapture={handleWindowControlMouseDown}
onMouseDown={handleWindowControlMouseDown}
onMouseUp={releaseWindowControlFocus}
onAuxClick={suppressTitlebarContextMenu}
onContextMenuCapture={suppressTitlebarContextMenu}
onContextMenu={suppressTitlebarContextMenu}
>
<Minus size={15} />
</button>
<button type="button" aria-label="Maximize" className={winButton} onClick={() => window.titlebar.maximize()}>
<button
type="button"
tabIndex={-1}
aria-label="Maximize"
className={winButton}
style={windowControlStyle}
onClick={(event) => {
releaseWindowControlFocus(event)
window.titlebar.maximize()
}}
onPointerDownCapture={handleWindowControlMouseDown}
onMouseDown={handleWindowControlMouseDown}
onMouseUp={releaseWindowControlFocus}
onAuxClick={suppressTitlebarContextMenu}
onContextMenuCapture={suppressTitlebarContextMenu}
onContextMenu={suppressTitlebarContextMenu}
>
<Square size={13} />
</button>
<button type="button" aria-label="Close" className={winButton} onClick={() => setShowCloseConfirm(true)}>
<button
type="button"
tabIndex={-1}
aria-label="Close"
className={winButton}
style={windowControlStyle}
onClick={(event) => {
releaseWindowControlFocus(event)
setShowCloseConfirm(true)
}}
onPointerDownCapture={handleWindowControlMouseDown}
onMouseDown={handleWindowControlMouseDown}
onMouseUp={releaseWindowControlFocus}
onAuxClick={suppressTitlebarContextMenu}
onContextMenuCapture={suppressTitlebarContextMenu}
onContextMenu={suppressTitlebarContextMenu}
>
<X size={15} />
</button>
</div>