From c9f6cbc34dc00634c3befef030569726c64922a4 Mon Sep 17 00:00:00 2001 From: daniel-c-harvey Date: Sun, 26 Jul 2026 22:05:43 -0400 Subject: [PATCH] fix(bank_panel): arm drag from unselected cell in one gesture Plain press on an unselected grid cell now commits the single-cell selection immediately and arms the drag, so moving past the threshold begins a drag without a prior selecting click. Already-selected and ctrl/shift paths are unchanged. --- src/bank_panel.cpp | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/bank_panel.cpp b/src/bank_panel.cpp index 7509169..2a2d10d 100644 --- a/src/bank_panel.cpp +++ b/src/bank_panel.cpp @@ -2001,21 +2001,34 @@ void handleClick(int x, int y) { return; } - // If the pressed cell is already SELECTED and no modifier is held, arm a drag — - // the actual selection change is deferred to LBUTTONUP if no drag begins (so a - // plain click on a multi-selection can start a drag without collapsing it first). - // Otherwise apply the click immediately. This is the M5-multi-select-drag - // disambiguation: M5 has no cell drag; a drag here begins only from a selected - // cell past a movement threshold (see onMouseMove), so plain click/shift/ctrl - // multi-select is untouched. + // Drag-arm disambiguation for plain (no ctrl, no shift) presses on a grid cell: + // + // • Already-selected cell: defer the selection change to LBUTTONUP so a plain + // press on a multi-selection doesn't collapse it before we know whether a drag + // will happen. Arm the drag with the current (multi-)selection as the payload + // candidate; only the caret moves immediately. + // + // • Unselected cell: apply the plain-click selection immediately (collapses to + // the single pressed cell) THEN arm a drag from it — so the user can press-and- + // drag in one gesture without a prior selecting click. The selection is set + // before arming so that focusedSelectionIds() resolves the right payload when + // the threshold is crossed in onMouseMove. + // + // ctrl / shift presses are selection-only gestures — no drag arm in either case. const bool onSelected = g_panel.selection.contains(hit); - if (onSelected && !ctrlDown() && !shiftDown()) { + if (!ctrlDown() && !shiftDown()) { + if (!onSelected) { + // Commit the single-cell selection now so the drag payload is correct. + g_panel.selection = applyClick(g_panel.selection, hit, false, false, count); + g_panel.selItemCount = count; + } else { + // Move the caret to the pressed cell; defer collapsing multi-selection. + g_panel.selection.focus = hit; + } g_panel.dragArmed = true; g_panel.dragStartX = x; g_panel.dragStartY = y; g_panel.dragSourceRegion = reg; - // Keep the current (multi-)selection as the drag payload candidate. - g_panel.selection.focus = hit; // move the caret to the pressed cell invalidatePanel(); return; }