fix: avoid iPad PWA traffic light overlap

Adds tablet standalone PWA detection
Reuses macOS traffic-light header spacing
Protects session sidebar and multirun headers
This commit is contained in:
Bohdan Triapitsyn
2026-05-03 21:39:30 +03:00
parent 9964dcdb99
commit fc2f4746e5
5 changed files with 83 additions and 11 deletions
@@ -4,7 +4,7 @@ import { RiLayoutLeftLine } from '@remixicon/react';
import { toast } from '@/components/ui';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { useI18n } from '@/lib/i18n';
import { useDeviceInfo } from '@/lib/device';
import { useDeviceInfo, useTabletStandalonePwaRuntime } from '@/lib/device';
import { isDesktopShell } from '@/lib/desktop';
import { isDesktopWindowFullscreen as getDesktopWindowFullscreen, onDesktopWindowResized, startDesktopWindowDrag } from '@/lib/desktopNative';
import { sessionEvents } from '@/lib/sessionEvents';
@@ -435,6 +435,7 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
}, []);
const isDesktopShellRuntime = React.useMemo(() => isDesktopShell(), []);
const isTabletStandalonePwa = useTabletStandalonePwaRuntime();
const [isDesktopWindowFullscreen, setIsDesktopWindowFullscreen] = React.useState(false);
const isVSCode = React.useMemo(() => isVSCodeRuntime(), []);
@@ -448,7 +449,7 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
}, []);
const isWebRuntime = !mobileVariant && !isVSCode && !isDesktopShellRuntime;
const showDesktopSidebarChrome = !mobileVariant && !isVSCode && !isWebRuntime;
const desktopSidebarTopPaddingClass = isDesktopShellRuntime && isMacPlatform && !isDesktopWindowFullscreen ? 'pl-[5.5rem]' : 'pl-3';
const desktopSidebarTopPaddingClass = (isDesktopShellRuntime && isMacPlatform && !isDesktopWindowFullscreen) || isTabletStandalonePwa ? 'pl-[5.5rem]' : 'pl-3';
const desktopSidebarToggleButtonClass = 'app-region-no-drag inline-flex h-8 w-8 items-center justify-center rounded-md typography-ui-label font-medium text-foreground transition-colors hover:bg-interactive-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-50';
React.useEffect(() => {
@@ -1680,6 +1681,7 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
onToggleSelectionMode={handleToggleSelectionMode}
showSidebarToggle={isWebRuntime}
onToggleSidebar={toggleSidebar}
avoidWindowControlsOverlay={isTabletStandalonePwa}
/>
<SidebarProjectsList
@@ -48,6 +48,7 @@ type Props = {
onToggleSelectionMode: () => void;
showSidebarToggle?: boolean;
onToggleSidebar?: () => void;
avoidWindowControlsOverlay?: boolean;
};
export function SidebarHeader(props: Props): React.ReactNode {
@@ -75,6 +76,7 @@ export function SidebarHeader(props: Props): React.ReactNode {
onToggleSelectionMode,
showSidebarToggle = false,
onToggleSidebar,
avoidWindowControlsOverlay = false,
} = props;
const displayMode = useSessionDisplayStore((state) => state.displayMode);
@@ -90,7 +92,7 @@ export function SidebarHeader(props: Props): React.ReactNode {
<div
className={cn(
'select-none flex-shrink-0',
showSidebarToggle ? 'pl-3 pr-3' : 'px-2.5 py-1',
showSidebarToggle ? (avoidWindowControlsOverlay ? 'pl-[5.5rem] pr-3' : 'pl-3 pr-3') : 'px-2.5 py-1',
)}
>
{reserveHeaderActionsSpace ? (