feat(desktop-client): adapt title bar and drag region for Windows/Linux
Frontend CI / Frontend (push) Has been cancelled
Frontend CI / Frontend (push) Has been cancelled
- Add appTitleBarStyle() and appTitleBarOverlay() helpers for cross-platform title bar - Use titleBarOverlay on Windows/Linux so system caption buttons render correctly - Disable minimize button on login window (non-resizable, no need to minimize) - Detect platform at renderer startup and set data-platform on <html> for CSS targeting - DesktopShell: flip drag bar layout — full-width minus caption area on Win/Linux, traffic-light gap on macOS - LoginView: move top-bar to Win/Linux caption area (top: 34px), mirror to left on macOS Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -132,6 +132,23 @@ const SETTINGS_WINDOW_SIZE: WindowSizePreset = {
|
||||
resizable: true,
|
||||
};
|
||||
|
||||
const TITLE_BAR_OVERLAY_HEIGHT = 24;
|
||||
|
||||
function appTitleBarStyle(): "hidden" | "hiddenInset" {
|
||||
return process.platform === "darwin" ? "hiddenInset" : "hidden";
|
||||
}
|
||||
|
||||
function appTitleBarOverlay(color: string): { color: string; symbolColor: string; height: number } | undefined {
|
||||
if (process.platform === "darwin") {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
color,
|
||||
symbolColor: nativeTheme.shouldUseDarkColors ? "#f8fafc" : "#111827",
|
||||
height: TITLE_BAR_OVERLAY_HEIGHT,
|
||||
};
|
||||
}
|
||||
|
||||
function suppressNativeWindowMenu(window?: ElectronBrowserWindow): void {
|
||||
if (process.platform === "darwin") {
|
||||
return;
|
||||
@@ -459,6 +476,7 @@ async function mountRendererWebContents(window: ElectronBrowserWindow, mode: Ren
|
||||
|
||||
async function createAppWindow(mode: WindowMode): Promise<ElectronBrowserWindow> {
|
||||
const initial = WINDOW_SIZES[mode];
|
||||
const backgroundColor = mode === "login" ? "#eaf2ff" : nativeTheme.shouldUseDarkColors ? "#15191a" : "#f0f2f5";
|
||||
const window = new BrowserWindow({
|
||||
width: initial.width,
|
||||
height: initial.height,
|
||||
@@ -467,13 +485,15 @@ async function createAppWindow(mode: WindowMode): Promise<ElectronBrowserWindow>
|
||||
show: false,
|
||||
title: "省心推",
|
||||
icon: createDesktopHealthIcon("normal"),
|
||||
titleBarStyle: "hiddenInset",
|
||||
titleBarStyle: appTitleBarStyle(),
|
||||
titleBarOverlay: appTitleBarOverlay(mode === "login" ? "#00000000" : backgroundColor),
|
||||
trafficLightPosition: { x: 12, y: 14 },
|
||||
resizable: initial.resizable,
|
||||
minimizable: mode !== "login",
|
||||
maximizable: initial.resizable,
|
||||
fullscreenable: initial.resizable,
|
||||
autoHideMenuBar: true,
|
||||
backgroundColor: mode === "login" ? "#eaf2ff" : nativeTheme.shouldUseDarkColors ? "#15191a" : "#f0f2f5",
|
||||
backgroundColor,
|
||||
webPreferences: {
|
||||
preload: preloadPath(),
|
||||
sandbox: true,
|
||||
@@ -536,6 +556,7 @@ async function createAppWindow(mode: WindowMode): Promise<ElectronBrowserWindow>
|
||||
|
||||
async function createSettingsWindow(): Promise<ElectronBrowserWindow> {
|
||||
const initial = SETTINGS_WINDOW_SIZE;
|
||||
const backgroundColor = nativeTheme.shouldUseDarkColors ? "#15191a" : "#f2f4f7";
|
||||
const window = new BrowserWindow({
|
||||
width: initial.width,
|
||||
height: initial.height,
|
||||
@@ -544,13 +565,14 @@ async function createSettingsWindow(): Promise<ElectronBrowserWindow> {
|
||||
show: false,
|
||||
title: "省心推设置",
|
||||
icon: createDesktopHealthIcon("normal"),
|
||||
titleBarStyle: "hiddenInset",
|
||||
titleBarStyle: appTitleBarStyle(),
|
||||
titleBarOverlay: appTitleBarOverlay(backgroundColor),
|
||||
trafficLightPosition: { x: 14, y: 15 },
|
||||
resizable: initial.resizable,
|
||||
maximizable: initial.resizable,
|
||||
fullscreenable: false,
|
||||
autoHideMenuBar: true,
|
||||
backgroundColor: nativeTheme.shouldUseDarkColors ? "#15191a" : "#f2f4f7",
|
||||
backgroundColor,
|
||||
webPreferences: {
|
||||
preload: preloadPath(),
|
||||
sandbox: true,
|
||||
|
||||
@@ -33,6 +33,8 @@ function syncWindowMode(authenticated: boolean): void {
|
||||
|
||||
const rendererWindowMode = resolveRendererWindowMode();
|
||||
document.documentElement.dataset.windowMode = rendererWindowMode;
|
||||
document.documentElement.dataset.platform =
|
||||
navigator.platform.toLowerCase().includes("mac") ? "darwin" : "win32";
|
||||
const usesAutomaticWindowMode = rendererWindowMode === "auto";
|
||||
const showsSettingsSurface = rendererWindowMode === "settings";
|
||||
const showsMainSurface = computed(() =>
|
||||
|
||||
@@ -170,11 +170,17 @@ function openSettingsWindow() {
|
||||
.window-drag-bar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 144px;
|
||||
height: 24px;
|
||||
z-index: 1000;
|
||||
-webkit-app-region: drag;
|
||||
}
|
||||
|
||||
:global(html[data-platform="darwin"]) .window-drag-bar {
|
||||
left: 80px;
|
||||
right: 0;
|
||||
height: 28px;
|
||||
z-index: 1000;
|
||||
-webkit-app-region: drag;
|
||||
}
|
||||
|
||||
.app-shell :where(button, a, input, select, textarea, [role="button"], [role="link"]) {
|
||||
|
||||
@@ -260,12 +260,17 @@ onBeforeUnmount(() => {
|
||||
|
||||
.top-bar {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
top: 34px;
|
||||
right: 14px;
|
||||
z-index: 10;
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
:global(html[data-platform="darwin"]) .top-bar {
|
||||
left: 52px;
|
||||
right: auto;
|
||||
}
|
||||
|
||||
.menu-trigger {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
|
||||
Reference in New Issue
Block a user