diff --git a/desktop/src/components/layout/TabBar.test.tsx b/desktop/src/components/layout/TabBar.test.tsx index 1b8ad014..9ce9babe 100644 --- a/desktop/src/components/layout/TabBar.test.tsx +++ b/desktop/src/components/layout/TabBar.test.tsx @@ -307,8 +307,10 @@ describe('TabBar', () => { render() }) - expect(screen.getByTestId('tab-bar')).not.toHaveAttribute('data-desktop-drag-region') + expect(screen.getByTestId('tab-bar')).toHaveAttribute('data-desktop-drag-region') + expect(screen.getByTestId('tab-bar-scroll-region')).toHaveAttribute('data-desktop-drag-region') expect(screen.getByTestId('tab-bar-drag-gutter')).toHaveAttribute('data-desktop-drag-region') + expect(screen.getByText('Untitled Session').closest('.tab-bar-interactive')).toBeInTheDocument() }) it('keeps the desktop tab strip at a roomier titlebar height', async () => { @@ -332,7 +334,7 @@ describe('TabBar', () => { }) const tabBar = screen.getByTestId('tab-bar') - const tab = screen.getByText('Untitled Session').closest('.tab-bar-hit-area') + const tab = screen.getByText('Untitled Session').closest('.tab-bar-interactive') expect(tabBar).toHaveClass('min-h-11') expect(tab).toHaveClass('min-h-11') @@ -506,7 +508,7 @@ describe('TabBar', () => { expect(screen.queryByTestId('open-project-menu')).not.toBeInTheDocument() }) - it('starts dragging when clicking the empty tab-bar gutter', async () => { + it('marks the empty tab-bar gutter as a native drag region without runtime dragging', async () => { const { TabBar } = await import('./TabBar') const { useTabStore } = await import('../../stores/tabStore') const { useChatStore } = await import('../../stores/chatStore') @@ -526,14 +528,13 @@ describe('TabBar', () => { render() }) - const scrollRegion = screen.getByTestId('tab-bar').querySelector('.overflow-x-hidden') + const scrollRegion = screen.getByTestId('tab-bar-scroll-region') expect(scrollRegion).toBeInTheDocument() + expect(scrollRegion).toHaveAttribute('data-desktop-drag-region') - fireEvent.mouseDown(scrollRegion!) + fireEvent.mouseDown(scrollRegion) - await waitFor(() => { - expect(startDraggingMock).toHaveBeenCalledTimes(1) - }) + expect(startDraggingMock).not.toHaveBeenCalled() }) it('does not start dragging when clicking a tab', async () => { @@ -582,10 +583,10 @@ describe('TabBar', () => { render() }) - expect(screen.getByTestId('tab-bar').querySelector('.tab-bar-hit-area')).toBeInTheDocument() + expect(screen.getByTestId('tab-bar').querySelector('.tab-bar-interactive')).toBeInTheDocument() - const firstTab = screen.getByText('First Session').closest('.tab-bar-hit-area') - const secondTab = screen.getByText('Second Session').closest('.tab-bar-hit-area') + const firstTab = screen.getByText('First Session').closest('.tab-bar-interactive') + const secondTab = screen.getByText('Second Session').closest('.tab-bar-interactive') expect(firstTab).toBeTruthy() expect(secondTab).toBeTruthy() @@ -630,7 +631,7 @@ describe('TabBar', () => { render() }) - const firstTab = screen.getByText('First Session').closest('.tab-bar-hit-area') + const firstTab = screen.getByText('First Session').closest('.tab-bar-interactive') expect(firstTab).toBeTruthy() fireEvent.mouseDown(firstTab!, { button: 0, clientX: 20, clientY: 10 }) @@ -664,7 +665,7 @@ describe('TabBar', () => { render() }) - const firstTab = screen.getByText('First Session').closest('.tab-bar-hit-area') + const firstTab = screen.getByText('First Session').closest('.tab-bar-interactive') const closeButton = screen.getByLabelText('Close First Session') expect(firstTab).toHaveClass('group') diff --git a/desktop/src/components/layout/TabBar.tsx b/desktop/src/components/layout/TabBar.tsx index 90f13ef4..5b2e087e 100644 --- a/desktop/src/components/layout/TabBar.tsx +++ b/desktop/src/components/layout/TabBar.tsx @@ -22,7 +22,6 @@ const TAB_WIDTH = 180 const DRAG_START_THRESHOLD = 4 const desktopHost = getDesktopHost() const isDesktopRuntime = desktopHost.isDesktop -const canStartWindowDragging = desktopHost.capabilities.windowControls type PendingCloseRequest = { tabs: Tab[] @@ -92,7 +91,6 @@ export function TabBar() { const pendingDragRef = useRef<{ index: number; startX: number; startY: number } | null>(null) const suppressClickRef = useRef(false) const tabRefs = useRef(new Map()) - const startDraggingRef = useRef<(() => Promise) | null>(null) const t = useTranslation() const runningSessionIds = useMemo(() => { const ids = new Set() @@ -105,11 +103,6 @@ export function TabBar() { return ids }, [activeChatSessionIds, tabs]) - useEffect(() => { - if (!canStartWindowDragging) return - startDraggingRef.current = () => getDesktopHost().window.startDragging() - }, []) - const updateScrollState = useCallback(() => { const el = scrollRef.current if (!el) return @@ -326,16 +319,10 @@ export function TabBar() { setActiveTab(sessionId) } - const handleScrollRegionMouseDown = useCallback((event: React.MouseEvent) => { - if (event.button !== 0 || event.target !== scrollRef.current) return - const startDragging = startDraggingRef.current - if (!startDragging) return - void startDragging().catch(() => {}) - }, []) - return ( @@ -347,9 +334,10 @@ export function TabBar() { e.preventDefault()} - onMouseDown={handleScrollRegionMouseDown} > {tabs.map((tab, index) => (