diff --git a/src/shell/panel/CLAUDE.md b/src/shell/panel/CLAUDE.md index e2711c2..1126f2b 100644 --- a/src/shell/panel/CLAUDE.md +++ b/src/shell/panel/CLAUDE.md @@ -73,7 +73,8 @@ live in `shell/bank_ops`, a sibling directory, not here. REAPER's, and the SDK exposes nothing host-wide. A global `SetSystemCursor` or a message hook would reach further and is rejected — do not reintroduce either. `IDC_APPSTARTING` is Windows-only (SWELL ships no equivalent), so on mac/Linux the readout is the whole - indicator. + indicator. `[verify — DAW]` whether REAPER's docker even routes `WM_SETCURSOR` to the + docked child dialog at all — the whole Windows half of this rests on that. - **No hit-test geometry in untestable shell code.** Even when reusing a WDL piece (e.g. a `vwnd` control for a long scroll list), layout/hit-test math stays in pure CTest-covered modules — do not import a WDL control's retained-mode object model diff --git a/src/shell/panel/panel_input.cpp b/src/shell/panel/panel_input.cpp index fcf9b74..7c73ec2 100644 --- a/src/shell/panel/panel_input.cpp +++ b/src/shell/panel/panel_input.cpp @@ -479,6 +479,19 @@ bool g_accelRegistered = false; // The ONE map from the reclaimer's answer to the pure readout's vocabulary. Name-for-name // so a divergence reads as one; the decision itself is entirely fxReclaimActivity's. +// This TU compiles straight into the reaper_reasampler MODULE, which carries none of +// reasampler_pure_library's -Werror=switch/we4062 promotion (footer_bar's mirror switch +// over FxDrainState has that; this one didn't) — a fourth FxReclaimActivity enumerator +// would fall through to Idle here with no diagnostic at all. Promoted locally instead of +// widening the target-wide flag, which would need auditing every switch already compiled +// into this MODULE for an intentionally-partial case list. +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(error : 4062) +#elif defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic error "-Wswitch" +#endif FxDrainState drainStateNow() { switch (fxReclaimActivity()) { case FxReclaimActivity::Online: return FxDrainState::Online; @@ -487,6 +500,11 @@ FxDrainState drainStateNow() { } return FxDrainState::Idle; } +#if defined(_MSC_VER) +#pragma warning(pop) +#elif defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif } // namespace diff --git a/src/shell/panel/panel_window.cpp b/src/shell/panel/panel_window.cpp index f7d0f92..3282a08 100644 --- a/src/shell/panel/panel_window.cpp +++ b/src/shell/panel/panel_window.cpp @@ -100,7 +100,9 @@ void handleDropFiles(HDROP hDrop) { // cursor at all and the footer readout carries the state alone. The cursor reaches OUR // windows only; REAPER's arrange and mixer answer their own WM_SETCURSOR and the SDK // exposes nothing host-wide to ask for. A global SetSystemCursor or a message hook would -// reach further and is deliberately not done. +// reach further and is deliberately not done. [verify — DAW] whether REAPER's docker even +// routes WM_SETCURSOR to the docked child dialog at all — the premise the whole Windows +// half of this feature rests on. #ifdef _WIN32 HCURSOR busyCursor() { return LoadCursor(nullptr, IDC_APPSTARTING); } #else @@ -118,12 +120,24 @@ bool busyCursorApplies() { WDL_DLGRET dlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_SETCURSOR: + // Non-client hits (resize border, etc.) are not ours to answer for; let the + // default handling run. Harmless today (IDD_BANK_PANEL is a bare WS_CHILD + // with no controls or border) but the guard is the conventional one. + if (LOWORD(lParam) != HTCLIENT) return 0; // Claiming the message (non-zero) is what stops the default arrow from being // reapplied underneath us — on Win32 via DefDlgProc, on SWELL via the same // return test in swell-wnd-generic.cpp. Falling through leaves every other // cursor decision exactly where it was (panel_drag's per-move SetCursor). if (busyCursorApplies()) { SetCursor(busyCursor()); + // A DLGPROC conveys its result through DWLP_MSGRESULT, not the raw + // return value; WM_SETCURSOR is not on the exception-message list that + // skips this. Without it the bare `return 1` still suppresses + // DefDlgProc's own cursor (SWELL checks the raw return too), but a + // parent or sender reading the result would see "unhandled". +#ifdef _WIN32 + SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE); +#endif return 1; } return 0; @@ -240,7 +254,10 @@ void closePanel() { } // namespace void refreshBusyCursor() { - if (!g_panel.hwnd) return; + // Nothing to refresh on mac/Linux (busyCursor() is always null there), and a live + // drag owns the cursor already (panel_drag::applyDragCursor) — forcing IDC_ARROW + // here on a drain edge mid-drag would stomp that cue until the next mouse move. + if (!g_panel.hwnd || !busyCursor() || g_panel.dragArmed || g_panel.dragging) return; POINT pt{}; GetCursorPos(&pt); // SWELL's returns void, so its result is deliberately not tested // Only when our own window is the one under the pointer: a menu or another window