From bccd3a1b44bb8b745a7a5848b4f77812c1f6d558 Mon Sep 17 00:00:00 2001 From: Ronen Kreimer Date: Fri, 21 Aug 2026 16:01:41 +0300 Subject: [PATCH 1/3] Fixed resize and titlebar double click on Mac --- electron/main/index.ts | 28 ++++++++++++++++++++++++- electron/preload/index.ts | 6 +++++- src/components/layout/TopBar.module.css | 18 ++++++++++++++++ src/components/layout/TopBar.tsx | 16 +++++++++++++- 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/electron/main/index.ts b/electron/main/index.ts index 858f80c..7dcd85d 100644 --- a/electron/main/index.ts +++ b/electron/main/index.ts @@ -1,4 +1,4 @@ -import { app, BrowserWindow, dialog, ipcMain, session } from 'electron' +import { app, BrowserWindow, dialog, ipcMain, session, systemPreferences } from 'electron' import type { IpcMainInvokeEvent } from 'electron' import { mkdir, readFile, writeFile } from 'node:fs/promises' import { execFile } from 'node:child_process' @@ -227,6 +227,32 @@ async function pickOpenPath(): Promise { } function registerIpcHandlers(): void { + /* + * `titleBarStyle: 'hiddenInset'` gives the renderer the drag region + * (`-webkit-app-region: drag` on the TopBar, see TopBar.module.css) but + * NOT the OS's usual double-click-to-zoom behaviour that a real title + * bar has for free — Chromium's drag region is a plain mouse listener, + * not an NSWindow title bar, so nothing tells macOS to react to the + * second click. The renderer's own dblclick handler calls this so we + * can honour the user's actual System Settings > Desktop & Dock choice + * ("Zoom", "Minimize" or "None") instead of hardcoding one. + */ + ipcMain.handle('window:titlebarDoubleClick', (evt) => { + if (process.platform !== 'darwin') return + const win = BrowserWindow.fromWebContents(evt.sender) + if (!win) return + const action = systemPreferences.getUserDefault('AppleActionOnDoubleClick', 'string') + if (action === 'Minimize') { + win.minimize() + } else if (action === 'None') { + // no-op, matches the system setting + } else { + // Default action ('Maximize', or unset) mirrors a native title bar. + if (win.isMaximized()) win.unmaximize() + else win.maximize() + } + }) + ipcMain.handle('dialog:save', async (evt, defaultName: string) => { /* * Parent the modal to the window that MADE the call, not to whatever diff --git a/electron/preload/index.ts b/electron/preload/index.ts index 4bba3fc..11957f5 100644 --- a/electron/preload/index.ts +++ b/electron/preload/index.ts @@ -268,7 +268,11 @@ const api = { window: { /** Represented file + edited flag: macOS proxy icon and title-bar dot. */ setDocument: (p: { path: string | null; edited: boolean }): void => - ipcRenderer.send('window:document', p) + ipcRenderer.send('window:document', p), + // Custom drag region (see TopBar.module.css) has no native title bar + // behind it, so double-click-to-zoom needs to be wired up by hand. + titlebarDoubleClick: (): Promise => + ipcRenderer.invoke('window:titlebarDoubleClick') }, /** Errors the main process caught instead of dying from. */ onMainError: (cb: (msg: string) => void): (() => void) => onChannel('app:main-error', cb), diff --git a/src/components/layout/TopBar.module.css b/src/components/layout/TopBar.module.css index f53debd..39a7249 100644 --- a/src/components/layout/TopBar.module.css +++ b/src/components/layout/TopBar.module.css @@ -22,6 +22,24 @@ */ position: relative; z-index: var(--dp-z-chrome, 20); + /* + * macOS uses `titleBarStyle: 'hiddenInset'` (see electron/main/index.ts) + * so the OS gives us no title bar and no drag region of its own — the + * content area fills the whole window. This row is the only thing tall + * enough to grab, so it opts itself into the drag region and every + * clickable descendant opts back out below. Harmless on Windows/Linux, + * where the frame already supplies its own drag/move handling. + */ + -webkit-app-region: drag; +} + +.root button, +.root input, +.root select, +.root a, +.root [role='tab'], +.root [role='option'] { + -webkit-app-region: no-drag; } .left { diff --git a/src/components/layout/TopBar.tsx b/src/components/layout/TopBar.tsx index 351fa1c..a11900d 100644 --- a/src/components/layout/TopBar.tsx +++ b/src/components/layout/TopBar.tsx @@ -230,8 +230,22 @@ export function TopBar() { const [verificationOpen, setVerificationOpen] = useState(false) const [testKind, setTestKind] = useState(null) + /* + * The drag region (`-webkit-app-region: drag` in TopBar.module.css) + * substitutes for the title bar `hiddenInset` removes, but it's just a + * mouse listener to Chromium — macOS never learns to zoom the window on + * a second click there the way it would for a real NSWindow title bar. + * Skip it entirely over interactive descendants so double-clicking a + * button/tab doesn't ALSO toggle the window size. + */ + const onRootDoubleClick = (e: React.MouseEvent): void => { + const target = e.target as HTMLElement + if (target.closest('button, input, select, a, [role="tab"], [role="option"]')) return + void window.daisy.window.titlebarDoubleClick() + } + return ( -
+
DAISYPATCHER From bb25129a45df3ba5b3cf5663df7586503996ecfe Mon Sep 17 00:00:00 2001 From: Ronen Kreimer Date: Fri, 21 Aug 2026 16:07:28 +0300 Subject: [PATCH 2/3] Removed redundant comment --- electron/preload/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/electron/preload/index.ts b/electron/preload/index.ts index 11957f5..eff60b6 100644 --- a/electron/preload/index.ts +++ b/electron/preload/index.ts @@ -269,8 +269,6 @@ const api = { /** Represented file + edited flag: macOS proxy icon and title-bar dot. */ setDocument: (p: { path: string | null; edited: boolean }): void => ipcRenderer.send('window:document', p), - // Custom drag region (see TopBar.module.css) has no native title bar - // behind it, so double-click-to-zoom needs to be wired up by hand. titlebarDoubleClick: (): Promise => ipcRenderer.invoke('window:titlebarDoubleClick') }, From e006043783ce84e9a233455b51a3a8def734c22e Mon Sep 17 00:00:00 2001 From: Ronen Kreimer Date: Fri, 21 Aug 2026 16:08:11 +0300 Subject: [PATCH 3/3] Removed redundant comment --- src/components/layout/TopBar.module.css | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/components/layout/TopBar.module.css b/src/components/layout/TopBar.module.css index 39a7249..aefa754 100644 --- a/src/components/layout/TopBar.module.css +++ b/src/components/layout/TopBar.module.css @@ -22,14 +22,6 @@ */ position: relative; z-index: var(--dp-z-chrome, 20); - /* - * macOS uses `titleBarStyle: 'hiddenInset'` (see electron/main/index.ts) - * so the OS gives us no title bar and no drag region of its own — the - * content area fills the whole window. This row is the only thing tall - * enough to grab, so it opts itself into the drag region and every - * clickable descendant opts back out below. Harmless on Windows/Linux, - * where the frame already supplies its own drag/move handling. - */ -webkit-app-region: drag; }