From c5efd8fd57a36935f6b11057cab96781d0ace3ce Mon Sep 17 00:00:00 2001 From: ciregenz Date: Tue, 21 Jul 2026 18:40:19 -0700 Subject: [PATCH] [eric] desktop: fullscreen card collapses its traffic lights to one exit control (native lights own that corner) --- .../app/pages/Dashboard/cards/AgentCard.tsx | 2 +- .../app/pages/Dashboard/cards/BrowserCard.tsx | 1 + .../Dashboard/cards/DashboardViewCard.tsx | 2 +- .../app/pages/Dashboard/cards/NoteCard.tsx | 2 +- .../pages/Dashboard/cards/WindowControls.tsx | 30 ++++++++++++++++++- 5 files changed, 33 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/pages/Dashboard/cards/AgentCard.tsx b/frontend/src/app/pages/Dashboard/cards/AgentCard.tsx index 5436279d..4f6d461c 100644 --- a/frontend/src/app/pages/Dashboard/cards/AgentCard.tsx +++ b/frontend/src/app/pages/Dashboard/cards/AgentCard.tsx @@ -1071,7 +1071,7 @@ const AgentCard: React.FC = ({ onPointerDown={(e) => e.stopPropagation()} sx={{ display: 'flex', alignItems: 'center', mr: 0.75, flexShrink: 0 }} > - handleRemove()} onMinimize={onMinimize} onTile={onTile} tiled={!!tileZone} /> + handleRemove()} onMinimize={onMinimize} onTile={onTile} tiled={!!tileZone} fullscreen={isFullscreen} /> = ({ onMinimize={handleMinimize} onTile={onTile} tiled={!!tileZone} + fullscreen={tileZone === 'fullscreen'} /> = ({ }} > e.stopPropagation()} sx={{ display: 'flex', alignItems: 'center', flexShrink: 0, mr: 0.25 }}> - handleRemove()} onMinimize={onMinimize} onTile={onTile} tiled={!!tileZone} /> + handleRemove()} onMinimize={onMinimize} onTile={onTile} tiled={!!tileZone} fullscreen={tileZone === 'fullscreen'} /> {!isMinimized && } = ({ }} > e.stopPropagation()} sx={{ display: 'flex', alignItems: 'center' }}> - handleRemove()} onMinimize={onMinimize} onTile={onTile} tiled={!!tileZone} /> + handleRemove()} onMinimize={onMinimize} onTile={onTile} tiled={!!tileZone} fullscreen={tileZone === 'fullscreen'} /> {isMinimized && ( diff --git a/frontend/src/app/pages/Dashboard/cards/WindowControls.tsx b/frontend/src/app/pages/Dashboard/cards/WindowControls.tsx index 392c7b29..73291ea9 100644 --- a/frontend/src/app/pages/Dashboard/cards/WindowControls.tsx +++ b/frontend/src/app/pages/Dashboard/cards/WindowControls.tsx @@ -1,5 +1,6 @@ import React, { useRef, useState } from 'react'; import Box from '@mui/material/Box'; +import FullscreenExitRoundedIcon from '@mui/icons-material/FullscreenExitRounded'; import { TILE_ZONES } from './tileZones'; interface WindowControlsProps { @@ -7,6 +8,9 @@ interface WindowControlsProps { onMinimize: () => void; onTile: (zone: string) => void; // a TILE_ZONES key, or 'restore' tiled?: boolean; + // Full size view: the native macOS lights sit right above this corner, so a second dot cluster + // reads as double chrome; collapse to ONE exit control and let the natives own window ops. + fullscreen?: boolean; } // macOS-style traffic lights on every card = the "AI OS" window feel. Grey at rest so a canvas @@ -50,13 +54,37 @@ export const ARC_CHIP_SX: Record = { '.osw-pill-host:hover & .osw-window-lights > :nth-of-type(3)': { transform: 'translate(calc(-50% + 11px), calc(-50% + 5px)) scale(1)', opacity: 1, transitionDelay: '80ms' }, }; -function WindowControls({ onClose, onMinimize, onTile, tiled }: WindowControlsProps): React.ReactElement { +function WindowControls({ onClose, onMinimize, onTile, tiled, fullscreen }: WindowControlsProps): React.ReactElement { const [menuOpen, setMenuOpen] = useState(false); const closeTimer = useRef(null); const openMenu = (): void => { if (closeTimer.current) window.clearTimeout(closeTimer.current); setMenuOpen(true); }; const scheduleClose = (): void => { closeTimer.current = window.setTimeout(() => setMenuOpen(false), 180); }; const stop = (e: React.PointerEvent | React.MouseEvent): void => { e.stopPropagation(); }; + if (fullscreen) { + return ( + + { e.stopPropagation(); onTile('restore'); }} + onPointerDown={stop} + sx={{ + display: 'flex', alignItems: 'center', justifyContent: 'center', + width: 22, height: 22, p: 0, border: 'none', borderRadius: '6px', + background: 'transparent', color: 'inherit', opacity: 0.65, cursor: 'pointer', + transition: 'opacity 120ms, background 120ms', + '&:hover': { opacity: 1, background: 'rgba(136,136,136,0.18)' }, + }} + > + + + + ); + } + const btn = (color: string, symbol: string, onClick: () => void, label: string): React.ReactElement => ( { e.stopPropagation(); onClick(); }} onPointerDown={stop} sx={dotSx(color)}>