diff --git a/src/bank_panel.cpp b/src/bank_panel.cpp index 64a64c7..827e927 100644 --- a/src/bank_panel.cpp +++ b/src/bank_panel.cpp @@ -2584,6 +2584,13 @@ void handleClick(int x, int y) { g_panel.dragStartX = x; g_panel.dragStartY = y; g_panel.dragSourceRegion = reg; + // Capture the mouse NOW so WM_MOUSEMOVE is delivered even when the pointer leaves the + // panel client rect before the drag threshold is crossed. Without capture, outside moves + // are not delivered, so a fast straight-out drag never transitions dragArmed → dragging + // and the OS drag-out never fires on the first pass. The capture is released on button-up + // (no drag: onLBtnUp dragArmed branch; drag: OsDrag path or onLBtnUp dragging branch) + // and on WM_CAPTURECHANGED (stolen or external release — already calls resetDragState). + SetCapture(g_panel.hwnd); invalidatePanel(); return; } @@ -2950,7 +2957,7 @@ void onMouseMove(int x, int y) { } g_panel.hovered = Hover{}; // clear hover — the drag owns the visual feedback now g_panel.tooltipShown = false; // a drag never shows a tooltip - SetCapture(g_panel.hwnd); + // SetCapture was already called at drag-arm time (handleClick); no re-capture needed. } } if (g_panel.dragging) { @@ -3129,6 +3136,8 @@ void onLBtnUp(int x, int y) { } else if (g_panel.dragArmed) { // Press-release on a selected cell with no drag: treat as a plain click that // collapses the multi-selection to the pressed cell (standard behavior). + // Release capture acquired at arm time (handleClick) — drag never started. + if (GetCapture() == g_panel.hwnd) ReleaseCapture(); const BankIndex* idx = indexForRegion(g_panel.focusedRegion); const int count = idx ? static_cast(idx->size()) : 0; const int focus = g_panel.selection.focus;