From d405c221ed3f72fd72b730bdc9b822a7d0421091 Mon Sep 17 00:00:00 2001 From: ciregenz Date: Wed, 15 Jul 2026 18:45:43 -0700 Subject: [PATCH] [eric] dashboard: one click focuses a card (arm webview shield on first drag-move, not pointerdown; arming on down made the click-focus camera fit skip = felt like two clicks) --- .../src/app/pages/Dashboard/hooks/interaction/useCardDrag.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/pages/Dashboard/hooks/interaction/useCardDrag.ts b/frontend/src/app/pages/Dashboard/hooks/interaction/useCardDrag.ts index 6bba46dd..5a8e3280 100644 --- a/frontend/src/app/pages/Dashboard/hooks/interaction/useCardDrag.ts +++ b/frontend/src/app/pages/Dashboard/hooks/interaction/useCardDrag.ts @@ -81,8 +81,6 @@ export function useCardDrag({ const handleCardDragStart = useCallback((id: string, _type: CardType) => { activeDragCardRef.current = id; - // Reuse the marquee's webview shield: a pointerup released over a live is eaten by the guest process, so neither the card's onDragEnd nor the window backstop ever fires and the edge-pan loop pans forever (the "card drifts on its own" bug). - document.body.classList.add('dashboard-marquee-active'); if (selection.isSelected(id)) { isMultiDragRef.current = true; } else { @@ -95,6 +93,8 @@ export function useCardDrag({ if (mouseX !== undefined && mouseY !== undefined) { lastMousePosRef.current = { x: mouseX, y: mouseY }; } + // Arm the webview shield on the first real MOVE, not on pointerdown: a plain click also arms the drag machinery, and shielding then made the click-to-focus camera fit skip (it saw a "drag in progress"), so focusing a card took two clicks. On a real drag the shield still goes up before the pointer travels, so the webview neutralization + no-nudge + release-over-webview fixes all hold. Idempotent add. + document.body.classList.add('dashboard-marquee-active'); // Start edge panning only once actual dragging begins; a live frame handle means the loop is already running. if (edgePanFrameRef.current === null) { edgePanFrameRef.current = requestAnimationFrame(tickEdgePan);