From 6d76af3379f75b2c0abaeeb5303b7788dd25bc13 Mon Sep 17 00:00:00 2001 From: Michael Suchacz <203725896+ibetitsmike@users.noreply.github.com> Date: Mon, 1 Dec 2025 05:46:16 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20feat:=20add=20Settings=20to=20ma?= =?UTF-8?q?cOS=20menu=20bar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a Settings menu item to the macOS application menu (Cmd+,) for easier access to the settings modal. Closes #810 _Generated with mux_ --- src/browser/App.tsx | 8 ++++++++ src/common/constants/ipc-constants.ts | 3 +++ src/common/types/ipc.ts | 3 +++ src/desktop/main.ts | 10 ++++++++++ src/desktop/preload.ts | 7 +++++++ 5 files changed, 31 insertions(+) diff --git a/src/browser/App.tsx b/src/browser/App.tsx index 7de592e5e2..199c7694a4 100644 --- a/src/browser/App.tsx +++ b/src/browser/App.tsx @@ -479,6 +479,14 @@ function AppInner() { openSettings, ]); + // Subscribe to menu bar "Open Settings" (macOS Cmd+, from app menu) + useEffect(() => { + const unsubscribe = window.api.menu?.onOpenSettings(() => { + openSettings(); + }); + return () => unsubscribe?.(); + }, [openSettings]); + // Handle workspace fork switch event useEffect(() => { const handleForkSwitch = (e: Event) => { diff --git a/src/common/constants/ipc-constants.ts b/src/common/constants/ipc-constants.ts index 828797a311..be7bc45ccf 100644 --- a/src/common/constants/ipc-constants.ts +++ b/src/common/constants/ipc-constants.ts @@ -50,6 +50,9 @@ export const IPC_CHANNELS = { // Window channels WINDOW_SET_TITLE: "window:setTitle", + // Menu channels (main -> renderer) + MENU_OPEN_SETTINGS: "menu:openSettings", + // Debug channels (for testing only) DEBUG_TRIGGER_STREAM_ERROR: "debug:triggerStreamError", diff --git a/src/common/types/ipc.ts b/src/common/types/ipc.ts index d257600810..22f844e504 100644 --- a/src/common/types/ipc.ts +++ b/src/common/types/ipc.ts @@ -377,6 +377,9 @@ export interface IPCApi { install(): void; onStatus(callback: (status: UpdateStatus) => void): () => void; }; + menu?: { + onOpenSettings(callback: () => void): () => void; + }; server?: { getLaunchProject(): Promise; }; diff --git a/src/desktop/main.ts b/src/desktop/main.ts index 4eb8f39d92..80b815b515 100644 --- a/src/desktop/main.ts +++ b/src/desktop/main.ts @@ -187,6 +187,16 @@ function createMenu() { submenu: [ { role: "about" }, { type: "separator" }, + { + label: "Settings...", + accelerator: "Cmd+,", + click: () => { + if (mainWindow) { + mainWindow.webContents.send(IPC_CHANNELS.MENU_OPEN_SETTINGS); + } + }, + }, + { type: "separator" }, { role: "services", submenu: [] }, { type: "separator" }, { role: "hide" }, diff --git a/src/desktop/preload.ts b/src/desktop/preload.ts index 8b5cd86e3e..8a9ea1c71c 100644 --- a/src/desktop/preload.ts +++ b/src/desktop/preload.ts @@ -210,6 +210,13 @@ const api: IPCApi = { closeWindow: (workspaceId: string) => ipcRenderer.invoke(IPC_CHANNELS.TERMINAL_WINDOW_CLOSE, workspaceId), }, + menu: { + onOpenSettings: (callback: () => void) => { + const handler = () => callback(); + ipcRenderer.on(IPC_CHANNELS.MENU_OPEN_SETTINGS, handler); + return () => ipcRenderer.removeListener(IPC_CHANNELS.MENU_OPEN_SETTINGS, handler); + }, + }, }; // Expose the API along with platform/versions