From e54823d44e8606121cfcf18ea08e06b9a48b2cad Mon Sep 17 00:00:00 2001 From: "L. David Baron" Date: Thu, 2 Apr 2009 11:05:29 -0700 Subject: [PATCH] Backed out changeset 5263468b1d60 (bug 395668) due to unit test timeouts in test_tooltip.xul and test_tooltip_noautohide.xul --- layout/xul/base/src/nsXULTooltipListener.cpp | 64 ++++++++++++-------- layout/xul/base/src/nsXULTooltipListener.h | 15 ++--- 2 files changed, 46 insertions(+), 33 deletions(-) diff --git a/layout/xul/base/src/nsXULTooltipListener.cpp b/layout/xul/base/src/nsXULTooltipListener.cpp index 34e38d309eb..27edd703c20 100644 --- a/layout/xul/base/src/nsXULTooltipListener.cpp +++ b/layout/xul/base/src/nsXULTooltipListener.cpp @@ -72,7 +72,6 @@ nsXULTooltipListener* nsXULTooltipListener::mInstance = nsnull; nsXULTooltipListener::nsXULTooltipListener() : mMouseScreenX(0) , mMouseScreenY(0) - , mTooltipShownOnce(PR_FALSE) #ifdef MOZ_XUL , mIsSourceTree(PR_FALSE) , mNeedTitletip(PR_FALSE) @@ -137,9 +136,6 @@ nsXULTooltipListener::MouseUp(nsIDOMEvent* aMouseEvent) NS_IMETHODIMP nsXULTooltipListener::MouseOut(nsIDOMEvent* aMouseEvent) { - // reset flag so that tooltip will display on the next MouseMove - mTooltipShownOnce = PR_FALSE; - // Clear the cached mouse event as it might hold a window alive too long, see // bug 420803. mCachedMouseEvent = nsnull; @@ -208,18 +204,7 @@ nsXULTooltipListener::MouseMove(nsIDOMEvent* aMouseEvent) PRInt32 newMouseX, newMouseY; mouseEvent->GetScreenX(&newMouseX); mouseEvent->GetScreenY(&newMouseY); - - // filter out false win32 MouseMove event if (mMouseScreenX == newMouseX && mMouseScreenY == newMouseY) - return NS_OK; - - // filter out minor movements due to crappy optical mice and shaky hands - // to prevent tooltips from hiding prematurely. - nsCOMPtr currentTooltip = do_QueryReferent(mCurrentTooltip); - - if ((currentTooltip) && - (abs(mMouseScreenX - newMouseX) <= kTooltipMouseMoveTolerance) && - (abs(mMouseScreenY - newMouseY) <= kTooltipMouseMoveTolerance)) return NS_OK; mMouseScreenX = newMouseX; mMouseScreenY = newMouseY; @@ -241,10 +226,11 @@ nsXULTooltipListener::MouseMove(nsIDOMEvent* aMouseEvent) // the node. KillTooltipTimer(); - // If the mouse moves while the tooltip is up, hide it. If nothing is - // showing and the tooltip hasn't been displayed since the mouse entered - // the node, then start the timer to show the tooltip. - if (!currentTooltip && !mTooltipShownOnce) { + // If the mouse moves while the tooltip is up, don't do anything. We make it + // go away only if it times out or leaves the target node. If nothing is + // showing, though, we have to do the work. + nsCOMPtr currentTooltip = do_QueryReferent(mCurrentTooltip); + if (!currentTooltip) { mTooltipTimer = do_CreateInstance("@mozilla.org/timer;1"); if (mTooltipTimer) { aMouseEvent->GetTarget(getter_AddRefs(eventTarget)); @@ -259,8 +245,6 @@ nsXULTooltipListener::MouseMove(nsIDOMEvent* aMouseEvent) } } } - } else { - HideTooltip(); } return NS_OK; @@ -435,6 +419,13 @@ nsXULTooltipListener::ShowTooltip() if (!currentTooltip) return NS_OK; + // at this point, |currentTooltip| holds the content node of + // the tooltip. If there is an attribute on the popup telling us + // not to create the auto-hide timer, don't. + if (!currentTooltip->AttrValueIs(kNameSpaceID_None, nsGkAtoms::noautohide, + nsGkAtoms::_true, eCaseMatters)) + CreateAutoHideTimer(); + // listen for popuphidden on the tooltip node, so that we can // be sure DestroyPopup is called even if someone else closes the tooltip nsCOMPtr evtTarget(do_QueryInterface(currentTooltip)); @@ -536,11 +527,6 @@ nsXULTooltipListener::LaunchTooltip() // Clear the current tooltip if the popup was not opened successfully. if (!pm->IsPopupOpen(currentTooltip)) mCurrentTooltip = nsnull; - else { - // set a flag so that the tooltip is only displayed once until the mouse - // leaves the node - mTooltipShownOnce = PR_TRUE; - } } #endif @@ -725,6 +711,10 @@ nsXULTooltipListener::DestroyTooltip() #ifdef MOZ_XUL mLastTreeCol = nsnull; #endif + if (mAutoHideTimer) { + mAutoHideTimer->Cancel(); + mAutoHideTimer = nsnull; + } return NS_OK; } @@ -739,6 +729,20 @@ nsXULTooltipListener::KillTooltipTimer() } } +void +nsXULTooltipListener::CreateAutoHideTimer() +{ + if (mAutoHideTimer) { + mAutoHideTimer->Cancel(); + mAutoHideTimer = nsnull; + } + + mAutoHideTimer = do_CreateInstance("@mozilla.org/timer;1"); + if ( mAutoHideTimer ) + mAutoHideTimer->InitWithFuncCallback(sAutoHideCallback, this, kTooltipAutoHideTime, + nsITimer::TYPE_ONE_SHOT); +} + void nsXULTooltipListener::sTooltipCallback(nsITimer *aTimer, void *aListener) { @@ -747,6 +751,14 @@ nsXULTooltipListener::sTooltipCallback(nsITimer *aTimer, void *aListener) instance->ShowTooltip(); } +void +nsXULTooltipListener::sAutoHideCallback(nsITimer *aTimer, void* aListener) +{ + nsRefPtr instance = mInstance; + if (instance) + instance->HideTooltip(); +} + #ifdef MOZ_XUL nsresult nsXULTooltipListener::GetSourceTreeBoxObject(nsITreeBoxObject** aBoxObject) diff --git a/layout/xul/base/src/nsXULTooltipListener.h b/layout/xul/base/src/nsXULTooltipListener.h index 5d1851d447f..3cdf047585e 100644 --- a/layout/xul/base/src/nsXULTooltipListener.h +++ b/layout/xul/base/src/nsXULTooltipListener.h @@ -107,10 +107,12 @@ protected: ~nsXULTooltipListener(); // pref callback for when the "show tooltips" pref changes + static int sTooltipPrefChanged (const char* aPref, void* aData); static PRBool sShowTooltips; static PRUint32 sTooltipListenerCount; void KillTooltipTimer(); + void CreateAutoHideTimer(); #ifdef MOZ_XUL void CheckTreeBodyMove(nsIDOMMouseEvent* aMouseEvent); @@ -144,18 +146,17 @@ protected: // last cached mouse event nsCOMPtr mCachedMouseEvent; + + // a timer for auto-hiding the tooltip after a certain delay + nsCOMPtr mAutoHideTimer; + static void sAutoHideCallback (nsITimer* aTimer, void* aListener); - // various constants for tooltips + // various delays for tooltips enum { - kTooltipMouseMoveTolerance = 7, // 7 pixel tolerance for mousemove event + kTooltipAutoHideTime = 5000, // 5000ms = 5 seconds kTooltipShowTime = 500 // 500ms = 0.5 seconds }; - // flag specifying if the tooltip has already been displayed by a MouseMove - // event. The flag is reset on MouseOut so that the tooltip will display - // the next time the mouse enters the node (bug #395668). - PRBool mTooltipShownOnce; - #ifdef MOZ_XUL // special members for handling trees PRBool mIsSourceTree;