Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

ac-electron: menubar-daemon mode for persistent tray on macOS

- launchAtLogin default true; setLoginItemSettings synced every boot
- Skip opening AC window when launched silently at login (wasOpenedAtLogin)
- syncDockVisibility() hides dock when no windows, shows when any open
- window-all-closed on macOS keeps process + trays alive (dock hidden)

Tray icons persist across window closes; clicking notepat tray launches
the piece without opening the AC pane.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

+66 -4
+66 -4
ac-electron/main.js
··· 75 75 let preferences = { 76 76 showTrayTitle: true, 77 77 trayTitleText: 'AC', // Short text next to tray icon 78 - launchAtLogin: false, 78 + launchAtLogin: true, 79 79 defaultMode: 'ac-pane', 80 80 // Window float behavior. When true, new AC Pane / Notepat windows 81 81 // open with alwaysOnTop so they float above other apps (the old ··· 350 350 } 351 351 } catch (e) { 352 352 console.warn('Could not set dock icon:', e.message); 353 + } 354 + } 355 + 356 + // On macOS, hide the dock icon when there are no visible windows so the app 357 + // acts as a pure menubar daemon. Shown again as soon as any window opens. 358 + function syncDockVisibility() { 359 + if (process.platform !== 'darwin' || !app.dock) return; 360 + const hasVisibleWindow = BrowserWindow.getAllWindows().some( 361 + (w) => !w.isDestroyed() && w.isVisible() 362 + ); 363 + if (hasVisibleWindow) { 364 + if (!app.dock.isVisible()) app.dock.show().catch(() => {}); 365 + } else { 366 + if (app.dock.isVisible()) app.dock.hide(); 353 367 } 354 368 } 355 369 ··· 2642 2656 // App lifecycle 2643 2657 app.whenReady().then(async () => { 2644 2658 loadPreferences(); 2659 + 2660 + // Always sync the OS login-item setting with our stored preference on boot. 2661 + // This way the preference survives updates / re-signing and is always honored. 2662 + if (process.platform === 'darwin' || process.platform === 'win32') { 2663 + try { 2664 + app.setLoginItemSettings({ 2665 + openAtLogin: preferences.launchAtLogin, 2666 + openAsHidden: true, 2667 + }); 2668 + } catch (e) { 2669 + console.warn('[main] setLoginItemSettings failed:', e.message); 2670 + } 2671 + } 2672 + 2673 + // Detect whether this launch was triggered by macOS at login (or with the 2674 + // hidden flag). If so, we stay in menubar-daemon mode and don't pop the AC 2675 + // window — the user will open things explicitly from the tray. 2676 + let launchedSilently = false; 2677 + if (process.platform === 'darwin') { 2678 + try { 2679 + const lis = app.getLoginItemSettings(); 2680 + launchedSilently = !!(lis.wasOpenedAtLogin || lis.wasOpenedAsHidden); 2681 + } catch (e) { 2682 + /* noop */ 2683 + } 2684 + } 2685 + // Hide the dock immediately so launch-at-login has zero visible footprint 2686 + // until the user clicks a tray icon. 2687 + if (launchedSilently) syncDockVisibility(); 2688 + 2645 2689 createMenu(); 2646 2690 createSystemTray(); 2647 2691 createNotepatTray(); ··· 2679 2723 setInterval(checkRebootMarker, 2000); 2680 2724 2681 2725 // Create initial window(s) 2682 - // Always start with an AC Pane window 2683 - openAcPaneWindow(); 2726 + // When launched silently at login, stay in menubar-daemon mode: no AC 2727 + // window, no dock icon. The user opens things explicitly from the tray. 2728 + if (!launchedSilently) { 2729 + openAcPaneWindow(); 2730 + } 2684 2731 2685 2732 app.on('activate', () => { 2686 2733 if (BrowserWindow.getAllWindows().length === 0) { 2687 2734 openAcPaneWindow(); 2688 2735 } 2736 + }); 2737 + 2738 + // Keep dock visibility in sync with window state on macOS so the app 2739 + // fades out of the dock / app-switcher whenever all windows close, and 2740 + // comes back as soon as a window opens. 2741 + app.on('browser-window-created', (_, win) => { 2742 + syncDockVisibility(); 2743 + win.on('show', syncDockVisibility); 2744 + win.on('hide', syncDockVisibility); 2745 + win.on('closed', syncDockVisibility); 2689 2746 }); 2690 2747 2691 2748 // Allow webview preload scripts (required for webview-preload.js to work) ··· 2827 2884 app.on('window-all-closed', () => { 2828 2885 // Keep tray icons (AC + Notepat) alive on macOS so the menu bar remains an entry point. 2829 2886 // Cmd+Q still quits explicitly. On Windows/Linux, close-all still quits. 2830 - if (process.platform !== 'darwin') app.quit(); 2887 + if (process.platform !== 'darwin') { 2888 + app.quit(); 2889 + return; 2890 + } 2891 + // Drop out of the dock / app-switcher — pure menubar daemon mode. 2892 + syncDockVisibility(); 2831 2893 }); 2832 2894 2833 2895 app.on('will-quit', () => {