From 3fa4d10b91de9bacc0d8228efa123be99b931116 Mon Sep 17 00:00:00 2001 From: daniel-c-harvey Date: Fri, 21 Aug 2026 15:59:32 -0400 Subject: [PATCH] Lift the sign-off DRAFT note, fix footer/cursor CLAUDE.md overclaim, honest-en the readout-width test, trim duplicated rationale Removed DRAFT marker on approved readout strings; corrected "paint and cursor cannot disagree" to note drag-cue suppression; renamed the width test to state it only bounds character count, not pixels; trimmed restated rationale to its CLAUDE.md/header home. --- src/core/ui/footer_bar.h | 9 ++++----- src/shell/panel/CLAUDE.md | 7 +++++-- src/shell/panel/panel_render.cpp | 5 ++--- src/shell/panel/panel_window.cpp | 13 ++++--------- tests/test_footer_bar.cpp | 19 ++++++++++--------- 5 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/core/ui/footer_bar.h b/src/core/ui/footer_bar.h index 2aa03a7..fc23a98 100644 --- a/src/core/ui/footer_bar.h +++ b/src/core/ui/footer_bar.h @@ -88,11 +88,10 @@ bool modeSegmentEnabled(bool isActiveSegment, bool transportRunning, bool routab // Idle is "nothing moving", never "no work queued" — the shell's enum owns that reasoning. enum class FxDrainState { Idle, Online, Offline }; -// DRAFT wording, pending sign-off. Short on purpose: these share the count box, whose -// default 64px holds roughly a dozen glyphs at the panel's smallest font before the -// shell's kit end-ellipsizes it. The two directions read differently because they ARE -// different acts — Offline takes the inactive modes' chains out, Online brings the -// entering mode's back. +// Short on purpose: these share the count box, whose default 64px holds roughly a +// dozen glyphs at the panel's smallest font before the shell's kit end-ellipsizes it. +// The two directions read differently because they ARE different acts — Offline +// takes the inactive modes' chains out, Online brings the entering mode's back. inline constexpr const char* kFxParkingReadout = "parking FX"; inline constexpr const char* kFxRestoringReadout = "restoring FX"; diff --git a/src/shell/panel/CLAUDE.md b/src/shell/panel/CLAUDE.md index 1126f2b..2fe6f43 100644 --- a/src/shell/panel/CLAUDE.md +++ b/src/shell/panel/CLAUDE.md @@ -64,8 +64,11 @@ live in `shell/bank_ops`, a sibling directory, not here. reused WDL pieces are the toolkit; reject any path that pulls in a new framework. - **The FX-drain indicator asks `fxReclaimActivity()` and decides nothing itself.** `panel_input` polls it once per tick into `g_panel.fxDrain`; the footer readout and the - `WM_SETCURSOR` busy cursor both read that cached state, so paint and cursor cannot - disagree within a tick. The transport gate, the park debounce and the open-undo-block + `WM_SETCURSOR` busy cursor both read that cached state, so the two never disagree about + the drain's own direction. The cursor additionally suppresses on `dragArmed`/`dragging` (a + live card drag outranks it), so mid-drag the footer can still read "parking FX"/"restoring + FX" while the cursor shows the drag cue — that is the one case where paint and cursor + diverge, and it is deliberate. The transport gate, the park debounce and the open-undo-block stand-off are all already folded into that answer, against the reclaim queue's own pinned project — do not re-evaluate any of them here, and never drive this off `fxReclaimPending` (true throughout the debounce, when only the opposite direction is eligible). diff --git a/src/shell/panel/panel_render.cpp b/src/shell/panel/panel_render.cpp index 0696908..9541a27 100644 --- a/src/shell/panel/panel_render.cpp +++ b/src/shell/panel/panel_render.cpp @@ -147,9 +147,8 @@ void drawFooter(LICE_IBitmap* bmp, int w, int h) { } } - // The one passive readout beside the toggle: a moving FX drain, else the per-mode member - // count (footerReadout owns which). Passive text, not a control. The drain draws - // text/primary against the count's text/dim so a transient state reads as one. + // footerReadout (core/ui) owns which string shows; the drain draws text/primary against + // the count's text/dim so the transient state visually reads as one. if (!fb.count.empty()) { const bool draining = g_panel.fxDrain != FxDrainState::Idle; const std::string label = footerReadout(g_panel.fxDrain, activeModeMemberCount()); diff --git a/src/shell/panel/panel_window.cpp b/src/shell/panel/panel_window.cpp index 3282a08..edb7e3a 100644 --- a/src/shell/panel/panel_window.cpp +++ b/src/shell/panel/panel_window.cpp @@ -94,15 +94,10 @@ void handleDropFiles(HDROP hDrop) { if (!paths.empty()) ingestDroppedFiles(paths); } -// IDC_APPSTARTING — arrow plus hourglass, "busy in the background, still usable" — is the -// exact reading for the FX reclaimer's drain, and IDC_WAIT is not: nothing here blocks. -// SWELL defines neither anywhere in vendor/WDL/WDL/swell, so on mac/Linux there is no busy -// 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. [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. +// IDC_APPSTARTING ("busy in the background, still usable"), not IDC_WAIT ("blocking") — +// nothing here blocks. Platform reach and the SetSystemCursor rejection: see this +// directory's CLAUDE.md. [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 rests on. #ifdef _WIN32 HCURSOR busyCursor() { return LoadCursor(nullptr, IDC_APPSTARTING); } #else diff --git a/tests/test_footer_bar.cpp b/tests/test_footer_bar.cpp index 6cae30e..764174a 100644 --- a/tests/test_footer_bar.cpp +++ b/tests/test_footer_bar.cpp @@ -265,9 +265,8 @@ static void testActiveSegmentStaysLiveEvenWhenUnroutable() { // --- The readout: count, and the drain's pre-emption of it ------------------- static void testIdleReadsTheCountAndNeitherDrainString() { - // Idle is the whole no-work-moving family — an empty queue, an item inside its park - // debounce, one held by the transport, one held by an open undo block. The readout - // cannot tell them apart and must show the count in every one of them. + // Idle covers the whole no-work-moving family: empty queue, park debounce, transport + // hold, open undo block — indistinguishable to this predicate (see footer_bar.h). CHECK(footerReadout(FxDrainState::Idle, 0) == "0 tracks"); CHECK(footerReadout(FxDrainState::Idle, 1) == "1 track"); CHECK(footerReadout(FxDrainState::Idle, 2) == "2 tracks"); @@ -294,11 +293,13 @@ static void testTheTwoDirectionsReadDifferently() { CHECK(footerReadout(FxDrainState::Online, 3) != footerReadout(FxDrainState::Offline, 3)); } -static void testDrainReadoutsFitTheCountBox() { - // They borrow the count box, so neither may be long enough to make the kit's - // end-ellipsis the normal case. Twelve glyphs is the default 64px box's rough capacity - // at the panel's smallest font; a longer string wants a wider box, not a silent - // truncation. +static void testDrainReadoutsStayShort() { + // NOT a pixel-width bound. Font::Micro is proportional (~10px, DT_END_ELLIPSIS in + // shell/panel/draw_kit.cpp) and this pure footer_bar test links no LICE, so it cannot + // measure rendered glyph width without pulling shell drawing into core/ui, which the + // pure/shell split (core/ui/CLAUDE.md) forbids. This only catches a readout that grew + // unreasonably long in character count; a real overflow end-ellipsizes rather than + // breaking layout, so fit is confirmed by the DAW pass, not by this assertion. CHECK(std::string(kFxParkingReadout).size() <= 12); CHECK(std::string(kFxRestoringReadout).size() <= 12); CHECK(!std::string(kFxParkingReadout).empty()); @@ -326,7 +327,7 @@ int main() { testIdleReadsTheCountAndNeitherDrainString(); testEachDirectionPreEmptsTheCount(); testTheTwoDirectionsReadDifferently(); - testDrainReadoutsFitTheCountBox(); + testDrainReadoutsStayShort(); if (g_fail == 0) std::printf("footer_bar: all tests passed\n"); else std::printf("footer_bar: %d CHECK(s) FAILED\n", g_fail);