From 273f7bb91142342c16640f9b65701c022feac8af Mon Sep 17 00:00:00 2001 From: Acbox Date: Sat, 25 Apr 2026 12:08:33 +0800 Subject: [PATCH] feat(desktop): macOS hidden-inset chrome and floating chat title Apply hiddenInset titleBarStyle on darwin so the system titlebar is hidden but native traffic lights remain. Reusable web sidebars inject a new DesktopShellKey to reserve a 36px TopBar that holds the traffic-light inset (drag region + right border) without colliding with the bot list, and the sidebar stays pinned open in the Electron shell so window resize doesn't fight the layout. Overlay a centered "Title - BotName" header above the chat content with a bottom shadow gradient that obscures scrolling messages, and reserve top padding so the first message stays visible when content fits the viewport. Route the sidebar + action by path (/settings/bots) so the chat router's /settings/* interception forwards it to the settings window cleanly while remaining a normal navigation in web. --- apps/desktop/src/main/index.ts | 9 +++ apps/desktop/src/renderer/src/chat/App.vue | 3 + .../desktop/src/renderer/src/settings/App.vue | 3 + .../desktop/src/renderer/types/web-stubs.d.ts | 5 ++ apps/web/package.json | 1 + .../src/components/settings-sidebar/index.vue | 19 ++++-- apps/web/src/components/sidebar/index.vue | 67 +++++++++---------- apps/web/src/layout/main-layout/index.vue | 11 ++- apps/web/src/lib/desktop-shell.ts | 6 ++ .../src/pages/home/components/chat-area.vue | 36 +++++++++- 10 files changed, 115 insertions(+), 45 deletions(-) create mode 100644 apps/web/src/lib/desktop-shell.ts diff --git a/apps/desktop/src/main/index.ts b/apps/desktop/src/main/index.ts index c672b7de..340e27f9 100644 --- a/apps/desktop/src/main/index.ts +++ b/apps/desktop/src/main/index.ts @@ -33,9 +33,17 @@ function loadRendererEntry(window: BrowserWindow, entry: 'index' | 'settings'): // output is what wires the IPC bridge into the renderer. const PRELOAD_FILE = '../preload/index.mjs' +// On macOS we hide the system titlebar but keep the native traffic lights +// (`hiddenInset`). Renderers reserve space for them via a custom TopBar. +const macTitleBarOptions: Partial + = process.platform === 'darwin' + ? { titleBarStyle: 'hiddenInset', trafficLightPosition: { x: 14, y: 12 } } + : {} + function createChatWindow(): BrowserWindow { const window = new BrowserWindow({ ...CHAT_DEFAULTS, + ...macTitleBarOptions, show: false, autoHideMenuBar: true, title: 'Memoh', @@ -63,6 +71,7 @@ function createChatWindow(): BrowserWindow { function createSettingsWindow(parent: BrowserWindow | null): BrowserWindow { const window = new BrowserWindow({ ...SETTINGS_DEFAULTS, + ...macTitleBarOptions, show: false, autoHideMenuBar: true, title: 'Memoh · Settings', diff --git a/apps/desktop/src/renderer/src/chat/App.vue b/apps/desktop/src/renderer/src/chat/App.vue index a6f6e8c3..fbf8c526 100644 --- a/apps/desktop/src/renderer/src/chat/App.vue +++ b/apps/desktop/src/renderer/src/chat/App.vue @@ -1,9 +1,12 @@ diff --git a/apps/desktop/src/renderer/src/settings/App.vue b/apps/desktop/src/renderer/src/settings/App.vue index c7cb7884..fcb66f84 100644 --- a/apps/desktop/src/renderer/src/settings/App.vue +++ b/apps/desktop/src/renderer/src/settings/App.vue @@ -1,10 +1,13 @@ diff --git a/apps/desktop/src/renderer/types/web-stubs.d.ts b/apps/desktop/src/renderer/types/web-stubs.d.ts index b675aa65..6a170bb5 100644 --- a/apps/desktop/src/renderer/types/web-stubs.d.ts +++ b/apps/desktop/src/renderer/types/web-stubs.d.ts @@ -34,6 +34,11 @@ declare module '@memohai/web/store/settings' { export function useSettingsStore(): unknown } +declare module '@memohai/web/lib/desktop-shell' { + import type { InjectionKey } from 'vue' + export const DesktopShellKey: InjectionKey +} + declare module '@memohai/web/style.css' // Fallback for every Vue SFC reachable through the @memohai/web/* wildcard diff --git a/apps/web/package.json b/apps/web/package.json index f838ce88..0c69e289 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -10,6 +10,7 @@ "./router": "./src/router.ts", "./i18n": "./src/i18n.ts", "./api-client": "./src/lib/api-client.ts", + "./lib/desktop-shell": "./src/lib/desktop-shell.ts", "./style.css": "./src/style.css", "./*": "./src/*" }, diff --git a/apps/web/src/components/settings-sidebar/index.vue b/apps/web/src/components/settings-sidebar/index.vue index ca08b28c..dfc15d40 100644 --- a/apps/web/src/components/settings-sidebar/index.vue +++ b/apps/web/src/components/settings-sidebar/index.vue @@ -1,6 +1,14 @@ diff --git a/apps/web/src/layout/main-layout/index.vue b/apps/web/src/layout/main-layout/index.vue index 33074210..f2ebe3c5 100644 --- a/apps/web/src/layout/main-layout/index.vue +++ b/apps/web/src/layout/main-layout/index.vue @@ -16,16 +16,23 @@