- Add Tauri permissions for window minimize/maximize/close/drag - Rewrite WindowControls with plain buttons + stopPropagation to prevent drag region from capturing button clicks - Add data-tauri-drag-region to TopBar child containers - Make OpenPylon text pointer-events-none and select-none
82 lines
2.6 KiB
TypeScript
82 lines
2.6 KiB
TypeScript
import { useState, useEffect, useCallback } from "react";
|
|
import { getCurrentWindow } from "@tauri-apps/api/window";
|
|
import { Minus, Square, Copy, X } from "lucide-react";
|
|
|
|
export function WindowControls() {
|
|
const [isMaximized, setIsMaximized] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const appWindow = getCurrentWindow();
|
|
|
|
appWindow.isMaximized().then(setIsMaximized);
|
|
|
|
const unlisten = appWindow.onResized(async () => {
|
|
const maximized = await appWindow.isMaximized();
|
|
setIsMaximized(maximized);
|
|
});
|
|
|
|
return () => {
|
|
unlisten.then((fn) => fn());
|
|
};
|
|
}, []);
|
|
|
|
const handleMinimize = useCallback((e: React.MouseEvent) => {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
getCurrentWindow().minimize();
|
|
}, []);
|
|
|
|
const handleToggleMaximize = useCallback((e: React.MouseEvent) => {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
getCurrentWindow().toggleMaximize();
|
|
}, []);
|
|
|
|
const handleClose = useCallback((e: React.MouseEvent) => {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
getCurrentWindow().close();
|
|
}, []);
|
|
|
|
return (
|
|
<div className="flex items-center" onMouseDown={(e) => e.stopPropagation()}>
|
|
{/* Separator */}
|
|
<div className="mx-2 h-4 w-px bg-pylon-text-secondary/20" />
|
|
|
|
{/* Minimize */}
|
|
<button
|
|
onClick={handleMinimize}
|
|
onMouseDown={(e) => e.stopPropagation()}
|
|
className="flex size-8 items-center justify-center rounded-md text-pylon-text-secondary transition-all hover:scale-110 hover:bg-pylon-accent/10 hover:text-pylon-text active:scale-90"
|
|
aria-label="Minimize"
|
|
>
|
|
<Minus className="size-4" />
|
|
</button>
|
|
|
|
{/* Maximize / Restore */}
|
|
<button
|
|
onClick={handleToggleMaximize}
|
|
onMouseDown={(e) => e.stopPropagation()}
|
|
className="flex size-8 items-center justify-center rounded-md text-pylon-text-secondary transition-all hover:scale-110 hover:bg-pylon-accent/10 hover:text-pylon-text active:scale-90"
|
|
aria-label={isMaximized ? "Restore" : "Maximize"}
|
|
>
|
|
{isMaximized ? (
|
|
<Copy className="size-3.5" />
|
|
) : (
|
|
<Square className="size-3.5" />
|
|
)}
|
|
</button>
|
|
|
|
{/* Close */}
|
|
<button
|
|
onClick={handleClose}
|
|
onMouseDown={(e) => e.stopPropagation()}
|
|
className="flex size-8 items-center justify-center rounded-md text-pylon-text-secondary transition-all hover:scale-110 hover:bg-pylon-danger/15 hover:text-pylon-danger active:scale-90"
|
|
aria-label="Close"
|
|
>
|
|
<X className="size-4" />
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|