feat: macOS Electron native titlebar, dock icon, and drag regions#190
feat: macOS Electron native titlebar, dock icon, and drag regions#190
Conversation
Review notesCI is green and the drag-region approach looks right. Two issues I verified against the branch source: 1. Windows/Linux Electron will get bogus padding
titleBarStyle: isMac ? 'hiddenInset' : 'default',But the React side detects Electron platform-agnostically: // SidebarHeader.tsx
const isElectronApp = typeof navigator !== 'undefined' && /Electron/.test(navigator.userAgent);
// ...
<div style={{ paddingLeft: isElectronApp ? '68px' : '0px' }}>and similarly in style={{ paddingTop: /Electron/.test(navigator.userAgent) ? '32px' : '12px' }}So on Windows/Linux Electron, where there is still a native title bar and no traffic lights in the sidebar, users get:
Suggested fix: gate the safe-zone on macOS specifically, e.g. via 2. Dead CSS ruleThe file adds: html[data-electron][data-platform="darwin"] .electron-mac-sidebar-header {
padding-top: 38px;
}but grepping the branch shows The |
|
Thanks for the thorough review — both issues fixed in fe9f707. 1. Windows/Linux bogus padding → fixed The preload already exposes
2. Dead CSS rule → removed Deleted the |
|
Follow-up fix: macOS dock icon now uses squircle shape (011acb9) The dock icon was showing as a raw square because
Before → After (dock icon):
|
|
Follow-up: dock icon sizing + app name (8fe5a4b) Two more fixes for the macOS dock appearance:
|
|
Hide sidebar logo on all Electron platforms (bb5cf68) The sidebar logo/title was reappearing on macOS Electron because the previous fix gated visibility on Simplified: now uses
|
…fe-zone Switch titleBarStyle to hiddenInset on macOS so web content fills the full window and the traffic-light buttons (close/minimize/maximize) overlay the top-left corner. Sidebar adjustments: - Hide the sidebar logo/title on all Electron platforms (desktop clients show identity in the dock/taskbar; web version keeps the logo) - Add 68px left padding on macOS to clear the traffic-light buttons - Add 32px top padding in the collapsed sidebar strip on macOS - Mark sidebar header and main content header as -webkit-app-region:drag so the window is draggable; interactive children use no-drag - Place drag-region CSS outside @layer to avoid Tailwind cascade issues Detection uses navigator.userAgent (Chromium injects "Electron/x.y.z" unconditionally) rather than preload-dependent window.isElectron, which can miss if the module evaluates before contextBridge is wired. Made-with: Cursor
Overhaul the icon build pipeline so the macOS dock icon matches native app icons (Chrome, Finder, etc.) in shape and visual weight. Icon build script (scripts/build-electron-icons.mjs): - Generate icon-dock.png with squircle-rounded corners (~22.37% radius per Apple HIG) via sharp dest-in compositing with an SVG mask - Size artwork to 82% of canvas with transparent padding, matching the visual weight of system icons - Fix .iconset sizes to the exact set iconutil expects (16/32/128/256/512 + @2x retina), removing invalid 64x64 and standalone 1024x1024 entries - Add iconutil --convert icns step for .icns generation on macOS Electron main process (electron/main.mjs): - Only set dock icon in dev mode (no .app bundle); packaged builds rely on the bundled .icns which gets native squircle masking from macOS - Use the pre-masked icon-dock.png instead of the raw square icon.png Made-with: Cursor
In dev mode the macOS dock shows "Electron" because the label comes from the Electron.app bundle's Info.plist, not app.setName(). Patch CFBundleName and CFBundleDisplayName via PlistBuddy before launching the Electron binary so the dock reads "Dr. Claw" during development. Production builds are unaffected (electron-builder sets these). Made-with: Cursor
bb5cf68 to
d62ff19
Compare
Summary
Bring the macOS Electron desktop client in line with native app conventions — custom titlebar, proper dock icon, and window drag regions.
1. Custom titlebar with drag regions (
7c0aa85)titleBarStyletohiddenInseton macOS so web content fills the full window and the traffic-light buttons overlay the top-left corner-webkit-app-region: drag; interactive children useno-drag@layerto avoid Tailwind cascade issuesnavigator.userAgent(Chromium injectsElectron/x.y.zunconditionally) —window.isElectronvia preload can miss if the module evaluates beforecontextBridgeis wired2. macOS dock icon with native squircle shape (
a7c3461)icon-dock.pngwith rounded corners (~22.37 % radius per Apple HIG) via sharpdest-incompositing.iconsetsizes to the exact seticonutilexpects (16/32/128/256/512 + @2x retina)iconutil --convert icnsstep for proper.icnsgeneration.icns3. Dev dock label patch (
d62ff19)CFBundleName/CFBundleDisplayNameinElectron.app/Contents/Info.plistvia PlistBuddy before launching, so the macOS dock reads "Dr. Claw" instead of "Electron" during developmentFiles changed
electron/main.mjshiddenInsettitlebar on macOS; dev-only dock icon fromicon-dock.pngelectron/cli.mjsscripts/build-electron-icons.mjsiconutilstep, correct.iconsetsizesSidebarHeader.tsxelectron-drag/no-dragSidebarCollapsed.tsxelectron-drag/no-dragon buttonsMainContentHeader.tsxelectron-dragon header areasrc/index.css.electron-drag/.electron-no-dragrules outside@layerTest plan