diff --git a/electron/main/index.ts b/electron/main/index.ts index 7c87795a2..911e0794b 100644 --- a/electron/main/index.ts +++ b/electron/main/index.ts @@ -582,6 +582,7 @@ function registerIpcHandlers() { // ==================== window control handler ==================== ipcMain.on('window-close', (_, data) => { + console.log('window-close', data); if(data.isForceQuit) { return app?.quit() } diff --git a/src/components/TopBar/index.tsx b/src/components/TopBar/index.tsx index 0e6c4c89f..293a63a56 100644 --- a/src/components/TopBar/index.tsx +++ b/src/components/TopBar/index.tsx @@ -12,7 +12,7 @@ import { Power, ChevronDown, ChevronLeft, - House, + LayoutGrid, Share, } from "lucide-react"; import "./index.css"; @@ -246,7 +246,7 @@ function HeaderWin() { className="no-drag" onClick={() => navigate("/history")} > - + (null); + const [platform, setPlatform] = useState(""); + + useEffect(() => { + const p = window.electronAPI.getPlatform(); + setPlatform(p); + + if (p === "darwin") { + if (controlsRef.current) { + controlsRef.current.style.display = "none"; + } + } + }, []); + + if (platform === "darwin") { + return null; + } + + return ( + + window.electronAPI.minimizeWindow()} + > + + + window.electronAPI.toggleMaximizeWindow()} + > + + + { + e.stopPropagation(); + e.preventDefault(); + // Use forceQuit=true to bypass before-close handler + window.electronAPI.closeWindow(true); + }} + onMouseDown={(e) => { + e.stopPropagation(); + }} + > + + + + ); +} + diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx index aa2c79f7c..3bd0e87f1 100644 --- a/src/pages/Login.tsx +++ b/src/pages/Login.tsx @@ -1,6 +1,6 @@ import { useAuthStore } from "@/store/authStore"; import { useNavigate, useLocation } from "react-router-dom"; -import { useCallback, useEffect, useState } from "react"; +import { useCallback, useEffect, useState, useRef } from "react"; import { useStackApp } from "@stackframe/react"; import loginGif from "@/assets/login.gif"; import { Button } from "@/components/ui/button"; @@ -14,6 +14,7 @@ import eyeOff from "@/assets/eye-off.svg"; import { proxyFetchPost } from "@/api/http"; import { hasStackKeys } from "@/lib"; import { useTranslation } from "react-i18next"; +import WindowControls from "@/components/WindowControls"; const HAS_STACK_KEYS = hasStackKeys(); let lock = false; @@ -34,6 +35,8 @@ export default function Login() { }); const [isLoading, setIsLoading] = useState(false); const [generalError, setGeneralError] = useState(""); + const titlebarRef = useRef(null); + const [platform, setPlatform] = useState(""); const validateEmail = (email: string) => { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; @@ -211,12 +214,72 @@ export default function Login() { }; }, []); + useEffect(() => { + const p = window.electronAPI.getPlatform(); + setPlatform(p); + + if (platform === "darwin") { + titlebarRef.current?.classList.add("mac"); + } + }, [platform]); + + // Handle before-close event for login page + useEffect(() => { + const handleBeforeClose = () => { + // On login page, always close directly without confirmation + window.electronAPI.closeWindow(true); + }; + + window.ipcRenderer?.on("before-close", handleBeforeClose); + + return () => { + window.ipcRenderer?.off("before-close", handleBeforeClose); + }; + }, []); + return ( - - - + + {/* Titlebar with drag region and window controls */} + + {/* Left spacer for macOS */} + + {platform === "darwin" && Eigent} + + + {/* Center drag region */} + + + + + {/* Right window controls */} + e.stopPropagation()} + onClick={(e) => e.stopPropagation()} + > + + - + + {/* Main content - image extends to top, form has padding */} + + + + + @@ -319,6 +382,7 @@ export default function Login() { > {t("layout.privacy-policy")} + ); diff --git a/utils/__pycache__/__init__.cpython-310.pyc b/utils/__pycache__/__init__.cpython-310.pyc index 664fc47bd..744ca18d8 100644 Binary files a/utils/__pycache__/__init__.cpython-310.pyc and b/utils/__pycache__/__init__.cpython-310.pyc differ diff --git a/utils/__pycache__/traceroot_wrapper.cpython-310.pyc b/utils/__pycache__/traceroot_wrapper.cpython-310.pyc index 6d17bd26b..b86cd68b6 100644 Binary files a/utils/__pycache__/traceroot_wrapper.cpython-310.pyc and b/utils/__pycache__/traceroot_wrapper.cpython-310.pyc differ