diff --git a/ui/desktop/src/App.tsx b/ui/desktop/src/App.tsx index 47a24b7b2204..956fa17ad320 100644 --- a/ui/desktop/src/App.tsx +++ b/ui/desktop/src/App.tsx @@ -503,9 +503,9 @@ export default function App() { setIsDiffSidePanelOpen(true); await toggleWindow(); } else if (diffContentMatches) { - // Close when open and content matches + // Close when open and content matches - don't resize window setIsDiffSidePanelOpen(false); - await toggleWindow(); + // Note: We don't call toggleWindow() here because the window should stay at its current size } } catch (error) { console.error('Failed to toggle window for diff viewer:', error); @@ -669,14 +669,9 @@ export default function App() { return; } - try { - setIsDiffSidePanelOpen(false); - await toggleWindow(); - } catch (error) { - console.error('Failed to toggle window when closing diff panel:', error); - // Revert state on error - setIsDiffSidePanelOpen(true); - } + // Just close the panel - don't resize the window + setIsDiffSidePanelOpen(false); + // Note: We don't call toggleWindow() here because the window should stay at its current size }} enableActions={false} /> diff --git a/ui/desktop/src/hooks/useWindowManager.ts b/ui/desktop/src/hooks/useWindowManager.ts index 74d0aace1e98..4bb0c228f8bb 100644 --- a/ui/desktop/src/hooks/useWindowManager.ts +++ b/ui/desktop/src/hooks/useWindowManager.ts @@ -47,20 +47,62 @@ export function useWindowManager(options: WindowManagerOptions = {}): WindowMana // Update window dimensions when window is resized externally useEffect(() => { const handleResize = () => { - // Only update if we're not in the middle of a programmatic resize - if (!resizeInProgressRef.current) { - setWindowState((prev) => ({ + setWindowState((prev) => { + const newWidth = window.innerWidth; + + // Always update current width to match actual window + const updatedState = { ...prev, - currentWidth: window.innerWidth, - // If window was manually resized, update original width when not expanded - originalWidth: prev.isExpanded ? prev.originalWidth : window.innerWidth, - })); - } + currentWidth: newWidth, + }; + + // If we're in the middle of a programmatic resize, don't change expanded state + if (resizeInProgressRef.current) { + return updatedState; + } + + // Check if window was manually resized to a smaller size + // We consider it manually collapsed if: + // 1. It was previously expanded, AND + // 2. The new width is significantly smaller than what we expect for expanded state + if (prev.isExpanded) { + // Calculate what the expanded width should be based on original width + const expectedExpandedWidth = Math.floor( + prev.originalWidth * (1 + opts.expandPercentage / 100) + ); + const collapseThreshold = expectedExpandedWidth * 0.85; // 85% threshold for more reliable detection + + if (newWidth < collapseThreshold) { + console.log('Window manually collapsed - resetting expanded state', { + originalWidth: prev.originalWidth, + expectedExpandedWidth, + newWidth, + threshold: collapseThreshold, + }); + + return { + ...updatedState, + isExpanded: false, + originalWidth: newWidth, // Update original width to new smaller size + }; + } + } + + // If not expanded, update original width to track manual resizing + if (!prev.isExpanded) { + return { + ...updatedState, + originalWidth: newWidth, + }; + } + + return updatedState; + }); }; window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); - }, []); + }, [opts.expandPercentage]); // Manage component mounting based on window state useEffect(() => { @@ -89,6 +131,12 @@ export function useWindowManager(options: WindowManagerOptions = {}): WindowMana return; } + // Don't resize if window is already expanded + if (windowState.isExpanded) { + console.log('Window is already expanded, skipping resize operation'); + return; + } + try { resizeInProgressRef.current = true; @@ -97,55 +145,33 @@ export function useWindowManager(options: WindowManagerOptions = {}): WindowMana isTransitioning: true, })); - if (windowState.isExpanded) { - // Collapsing: unmount component first, then resize - setIsComponentMounted(false); - - // Small delay to allow component to unmount cleanly - await new Promise((resolve) => window.setTimeout(resolve, 100)); - - // Reset to original size - const success = await window.electron.resizeWindow(0); - - if (success) { - setWindowState((prev) => ({ - ...prev, - isExpanded: false, - currentWidth: prev.originalWidth, - isTransitioning: false, - })); - } else { - throw new Error('Failed to resize window to original size'); - } - } else { - // Expanding: resize first, then mount component - if (!canExpand) { - console.log('Window too wide for expansion, skipping resize'); - setWindowState((prev) => ({ - ...prev, - isTransitioning: false, - })); - // Still mount the component even if we don't resize - setIsComponentMounted(true); - return; - } + // Only expanding logic remains since we skip when already expanded + if (!canExpand) { + console.log('Window too wide for expansion, skipping resize'); + setWindowState((prev) => ({ + ...prev, + isTransitioning: false, + })); + // Still mount the component even if we don't resize + setIsComponentMounted(true); + return; + } - const success = await window.electron.resizeWindow(opts.expandPercentage); + const success = await window.electron.resizeWindow(opts.expandPercentage); - if (success) { - const newWidth = Math.floor(windowState.currentWidth * (1 + opts.expandPercentage / 100)); + if (success) { + const newWidth = Math.floor(windowState.currentWidth * (1 + opts.expandPercentage / 100)); - setWindowState((prev) => ({ - ...prev, - isExpanded: true, - currentWidth: newWidth, - isTransitioning: false, - })); + setWindowState((prev) => ({ + ...prev, + isExpanded: true, + currentWidth: newWidth, + isTransitioning: false, + })); - // Component will be mounted by the useEffect above - } else { - throw new Error('Failed to resize window for expansion'); - } + // Component will be mounted by the useEffect above + } else { + throw new Error('Failed to resize window for expansion'); } } catch (error) { console.error('Error during window toggle:', error);