From 8ce846e2b1443408df635e73c3651d87c1d7363a Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Mon, 26 Aug 2013 22:34:06 +0200 Subject: [PATCH] Fix infinite loop with huge tooltips * With a tooltip big enough trying to align below or above the mouse, the algorithm would loop endlessly trying to fit it on either side. * After trying each side once, set alignment to middle to try to show as much as the tooltip as possible. A way to trigger this is browsing WebKit github repository in WebPositive. Github will show the full commit message in a tooltip when you hover a file or directory, and some of their messages are big enough to overflow my desktop. --- src/kits/interface/ToolTipManager.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/kits/interface/ToolTipManager.cpp b/src/kits/interface/ToolTipManager.cpp index 918ad0ac23..5084adcebf 100644 --- a/src/kits/interface/ToolTipManager.cpp +++ b/src/kits/interface/ToolTipManager.cpp @@ -239,12 +239,19 @@ ToolTipView::ResetWindowFrame(BPoint where) && alignment.horizontal == B_ALIGN_CENTER)) alignment.vertical = B_ALIGN_BOTTOM; + // Adjust the tooltip position in cases where it would be partly out of the + // screen frame. Try to fit the tooltip on the requested side of the + // cursor, if that fails, try the opposite side, and if that fails again, + // give up and leave the tooltip under the mouse cursor. + bool firstTry = true; while (true) { switch (alignment.vertical) { case B_ALIGN_TOP: location.y = where.y - size.height - offset.y; if (location.y < screenFrame.top) { - alignment.vertical = B_ALIGN_BOTTOM; + alignment.vertical = firstTry ? B_ALIGN_BOTTOM + : B_ALIGN_MIDDLE; + firstTry = false; continue; } break; @@ -260,7 +267,9 @@ ToolTipView::ResetWindowFrame(BPoint where) default: location.y = where.y + offset.y; if (location.y + size.height > screenFrame.bottom) { - alignment.vertical = B_ALIGN_TOP; + alignment.vertical = firstTry ? B_ALIGN_TOP + : B_ALIGN_MIDDLE; + firstTry = false; continue; } break;