Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion desktop/src/app/AppTopChrome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import {
} from "lucide-react";
import * as React from "react";

import { isMacPlatform } from "@/shared/lib/platform";
import { useIsFullscreen } from "@/shared/lib/useIsFullscreen";
import { Button } from "@/shared/ui/button";
import { cn } from "@/shared/lib/cn";
import { useOptionalSidebar } from "@/shared/ui/sidebar";

type AppTopChromeProps = {
Expand Down Expand Up @@ -48,6 +51,14 @@ export function AppTopChrome({
onGoBack,
onGoForward,
}: AppTopChromeProps) {
const isFullscreen = useIsFullscreen();
// On macOS the traffic-light buttons overlay the chrome at x≈12 (see
// `trafficLightPosition` in `tauri.conf.json`), so the nav row sits at
// `left-[80px]` to clear them. In fullscreen those buttons hide, so shift
// the row back to the standard left inset.
const navRowLeftClass =
isMacPlatform() && isFullscreen ? "left-[12px]" : "left-[80px]";

React.useEffect(() => {
const handleWheel = (event: WheelEvent) => {
if (event.clientY <= TOP_CHROME_WHEEL_GUARD_HEIGHT) {
Expand All @@ -71,7 +82,12 @@ export function AppTopChrome({
className="fixed inset-x-0 top-0 z-20 h-10 cursor-default select-none"
data-tauri-drag-region
/>
<div className="fixed left-[80px] top-[6px] z-45 flex items-center gap-0.5">
<div
className={cn(
"fixed top-[6px] z-45 flex items-center gap-0.5",
navRowLeftClass,
)}
>
<TopChromeSidebarTrigger />
<Button
aria-label="Go back"
Expand Down
50 changes: 50 additions & 0 deletions desktop/src/shared/lib/useIsFullscreen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { getCurrentWindow } from "@tauri-apps/api/window";
import * as React from "react";

/**
* Returns whether the current Tauri window is in fullscreen mode.
*
* Initial value resolves from `isFullscreen()`; subsequent updates come from
* `onResized` (macOS native fullscreen, Windows F11, and Linux fullscreen all
* fire a resize on transition). Each consumer owns one listener cleaned up on
* unmount.
*/
export function useIsFullscreen(): boolean {
const [isFullscreen, setIsFullscreen] = React.useState(false);

React.useEffect(() => {
let unlisten: (() => void) | undefined;
let cancelled = false;

const appWindow = getCurrentWindow();

void appWindow.isFullscreen().then((value) => {
if (!cancelled) {
setIsFullscreen(value);
}
});

void appWindow
.onResized(() => {
void appWindow.isFullscreen().then((value) => {
if (!cancelled) {
setIsFullscreen(value);
}
});
})
.then((fn) => {
if (cancelled) {
fn();
} else {
unlisten = fn;
}
});

return () => {
cancelled = true;
unlisten?.();
};
}, []);

return isFullscreen;
}
Loading