diff --git a/src/bank_panel.cpp b/src/bank_panel.cpp index ba6132d..feabfba 100644 --- a/src/bank_panel.cpp +++ b/src/bank_panel.cpp @@ -1098,6 +1098,9 @@ bool currentTooltip(int w, int h, std::string& textOut, int& ax, int& ay, int& a // The full name is stored already prefix-free, but strip defensively in case a source ever // carries the "ReaSampler:" display prefix (the tooltip must never show it — L5 refinement 2). + // Intentionally distinct sources: the tooltip reads the registered phrase (fullName) while the + // keybinding sub-row in drawToolbar reads the live binding via kbd_getTextFromCmd. Do not + // unify them — each serves a different purpose and has a different lifetime. textOut = stripActionPrefix(rows[static_cast(hv.index)].fullName, actionDisplayPrefix()); ax = slot->x; ay = slot->y; aw = slot->width; ah = slot->height; diff --git a/src/tooltip.cpp b/src/tooltip.cpp index 0505f24..b9d902a 100644 --- a/src/tooltip.cpp +++ b/src/tooltip.cpp @@ -18,7 +18,10 @@ TooltipBox computeTooltip(int anchorX, int anchorY, int anchorW, int anchorH, TooltipBox box; if (textW <= 0 || textH <= 0 || clientW <= 0 || clientH <= 0) return box; - const int boxW = textW + 2 * spec.padX; + // Clamp boxW so it never exceeds the available client span; then clamp x so the (possibly + // reduced) box always sits within [margin, clientW - margin]. + const int maxBoxW = clientW - 2 * spec.margin; + const int boxW = (textW + 2 * spec.padX < maxBoxW) ? textW + 2 * spec.padX : maxBoxW; const int boxH = textH + 2 * spec.padY; // Horizontal: centre on the anchor, then clamp within [margin, clientW - margin - boxW]. diff --git a/tests/test_tooltip.cpp b/tests/test_tooltip.cpp index 5b99d4e..2d7cf11 100644 --- a/tests/test_tooltip.cpp +++ b/tests/test_tooltip.cpp @@ -93,6 +93,20 @@ static void testBothClipClampsBottom() { CHECK(tb.y == 2); } +// --- Narrow client: box width clamped ---------------------------------------- + +// When the client is narrower than the box's natural width, the box is shrunk to fit and +// the result satisfies x >= margin AND x + width <= clientW - margin. +// Natural boxW = 80+12 = 92. Narrow client = 60. maxBoxW = 60-4 = 56. +// Clamped boxW = 56. x = 2 + (108-56)/2 ... centred but clamped to [2, 60-2-56] = [2, 2]. +static void testNarrowClientBoxClamped() { + const TooltipSpec spec{}; // margin = 2 + const TooltipBox tb = computeTooltip(2, 10, 108, 34, 80, 14, 60, 300, spec); + CHECK(!tb.empty()); + CHECK(tb.x >= spec.margin); + CHECK(tb.x + tb.width <= 60 - spec.margin); +} + // --- Degenerate -------------------------------------------------------------- static void testDegenerateEmpty() { @@ -113,6 +127,7 @@ int main() { testClampLeft(); testFlipAbove(); testBothClipClampsBottom(); + testNarrowClientBoxClamped(); testDegenerateEmpty(); if (g_fail == 0) std::printf("tooltip: all tests passed\n");