From c4157a7e90b0583203ecd18d32f30d4f78ddf33d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E9=98=BF=E6=B1=9F=28Relakkes?= =?UTF-8?q?=29?= Date: Thu, 2 Jul 2026 21:00:25 +0800 Subject: [PATCH] fix(desktop): restore workspace panel shrinking (#940) Tested: cd desktop && bun run test -- src/pages/ActiveSession.test.tsx --run Tested: cd desktop && bun run test -- src/stores/workspacePanelStore.test.ts --run Tested: git diff --check Not-tested: bun run check:desktop remains blocked by an unrelated MessageList timestamp assertion and existing TabBar unhandled rejections. Confidence: high Scope-risk: narrow --- desktop/src/pages/ActiveSession.test.tsx | 28 +++++++++++++++++++++++ desktop/src/pages/ActiveSession.tsx | 21 +++++++++++++---- desktop/src/stores/workspacePanelStore.ts | 2 +- 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/desktop/src/pages/ActiveSession.test.tsx b/desktop/src/pages/ActiveSession.test.tsx index aaf5a869..618ac162 100644 --- a/desktop/src/pages/ActiveSession.test.tsx +++ b/desktop/src/pages/ActiveSession.test.tsx @@ -1441,6 +1441,34 @@ describe('ActiveSession task polling', () => { }) expect(useWorkspacePanelStore.getState().width).toBe(WORKSPACE_PANEL_DEFAULT_WIDTH + 32) + + vi.spyOn(workbenchPanel, 'getBoundingClientRect').mockReturnValue({ + x: 0, + y: 0, + width: 558, + height: 720, + top: 0, + right: 558, + bottom: 720, + left: 0, + toJSON: () => ({}), + }) + + act(() => { + const pointerDown = createEvent.pointerDown(resizeHandle) + Object.defineProperty(pointerDown, 'button', { value: 0 }) + Object.defineProperty(pointerDown, 'clientX', { value: 100 }) + fireEvent(resizeHandle, pointerDown) + }) + + act(() => { + const pointerMove = new Event('pointermove') + Object.defineProperty(pointerMove, 'clientX', { value: 132 }) + window.dispatchEvent(pointerMove) + window.dispatchEvent(new Event('pointerup')) + }) + + expect(useWorkspacePanelStore.getState().width).toBe(526) }) it('does not render the workspace panel when closed or for member sessions', () => { diff --git a/desktop/src/pages/ActiveSession.tsx b/desktop/src/pages/ActiveSession.tsx index bae58a58..7152aa70 100644 --- a/desktop/src/pages/ActiveSession.tsx +++ b/desktop/src/pages/ActiveSession.tsx @@ -1,4 +1,5 @@ import { useEffect, useMemo, useRef, useState } from 'react' +import type { RefObject } from 'react' import { Target } from 'lucide-react' import { SCHEDULED_TAB_ID, @@ -127,7 +128,14 @@ function ActiveGoalStrip({ ) } -function WorkspaceResizeHandle() { +function getRenderedWorkspacePanelWidth(panelRef: RefObject, fallbackWidth: number) { + const renderedWidth = panelRef.current?.getBoundingClientRect().width ?? 0 + return Number.isFinite(renderedWidth) && renderedWidth > 0 + ? renderedWidth + : fallbackWidth +} + +function WorkspaceResizeHandle({ panelRef }: { panelRef: RefObject }) { const t = useTranslation() const width = useWorkspacePanelStore((state) => state.width) const setWidth = useWorkspacePanelStore((state) => state.setWidth) @@ -177,16 +185,17 @@ function WorkspaceResizeHandle() { onPointerDown={(event) => { if (event.button !== 0) return event.preventDefault() - setDragState({ startX: event.clientX, startWidth: width }) + setDragState({ startX: event.clientX, startWidth: getRenderedWorkspacePanelWidth(panelRef, width) }) }} onKeyDown={(event) => { + const renderedWidth = getRenderedWorkspacePanelWidth(panelRef, width) if (event.key === 'ArrowLeft') { event.preventDefault() - setWidth(width + WORKSPACE_RESIZE_STEP) + setWidth(renderedWidth + WORKSPACE_RESIZE_STEP) } if (event.key === 'ArrowRight') { event.preventDefault() - setWidth(width - WORKSPACE_RESIZE_STEP) + setWidth(renderedWidth - WORKSPACE_RESIZE_STEP) } }} className="group relative z-10 flex w-2 shrink-0 cursor-col-resize items-stretch justify-center bg-[var(--color-surface)] outline-none focus-visible:bg-[var(--color-surface-container)]" @@ -278,6 +287,7 @@ function TerminalResizeHandle() { export function ActiveSession() { const isMobileLayout = useMobileViewport() && !isDesktopRuntime() + const workbenchPanelRef = useRef(null) const activeTabId = useTabStore((s) => s.activeTabId) const [dismissedBackgroundTaskKeysBySession, setDismissedBackgroundTaskKeysBySession] = useState>>({}) const activeTabType = useTabStore((s) => s.tabs.find((tab) => tab.sessionId === s.activeTabId)?.type ?? null) @@ -640,8 +650,9 @@ export function ActiveSession() { {showWorkbench ? ( <> - +