Files
openpylon/src/components/layout/WindowControls.tsx
Your Name 08fbeaa1b2 fix: window controls, dragging, and text selection
- 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
2026-02-15 21:19:24 +02:00

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>
);
}