Bug 395668 - tooltips remain for only 5 seconds, should hide on mousemove instead. ui-r=faaborg, r=enn, sr=neil

This commit is contained in:
John Morkel 2009-04-02 16:59:55 +02:00
Родитель e1cf0a4560
Коммит ff123c3702
2 изменённых файлов: 33 добавлений и 46 удалений

Просмотреть файл

@ -72,6 +72,7 @@ nsXULTooltipListener* nsXULTooltipListener::mInstance = nsnull;
nsXULTooltipListener::nsXULTooltipListener()
: mMouseScreenX(0)
, mMouseScreenY(0)
, mTooltipShownOnce(PR_FALSE)
#ifdef MOZ_XUL
, mIsSourceTree(PR_FALSE)
, mNeedTitletip(PR_FALSE)
@ -136,6 +137,9 @@ 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;
@ -204,7 +208,18 @@ 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<nsIContent> currentTooltip = do_QueryReferent(mCurrentTooltip);
if ((currentTooltip) &&
(abs(mMouseScreenX - newMouseX) <= kTooltipMouseMoveTolerance) &&
(abs(mMouseScreenY - newMouseY) <= kTooltipMouseMoveTolerance))
return NS_OK;
mMouseScreenX = newMouseX;
mMouseScreenY = newMouseY;
@ -226,11 +241,10 @@ nsXULTooltipListener::MouseMove(nsIDOMEvent* aMouseEvent)
// the node.
KillTooltipTimer();
// 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<nsIContent> currentTooltip = do_QueryReferent(mCurrentTooltip);
if (!currentTooltip) {
// 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) {
mTooltipTimer = do_CreateInstance("@mozilla.org/timer;1");
if (mTooltipTimer) {
aMouseEvent->GetTarget(getter_AddRefs(eventTarget));
@ -245,6 +259,8 @@ nsXULTooltipListener::MouseMove(nsIDOMEvent* aMouseEvent)
}
}
}
} else {
HideTooltip();
}
return NS_OK;
@ -419,13 +435,6 @@ 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<nsIDOMEventTarget> evtTarget(do_QueryInterface(currentTooltip));
@ -527,6 +536,11 @@ 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
@ -711,10 +725,6 @@ nsXULTooltipListener::DestroyTooltip()
#ifdef MOZ_XUL
mLastTreeCol = nsnull;
#endif
if (mAutoHideTimer) {
mAutoHideTimer->Cancel();
mAutoHideTimer = nsnull;
}
return NS_OK;
}
@ -729,20 +739,6 @@ 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)
{
@ -751,14 +747,6 @@ nsXULTooltipListener::sTooltipCallback(nsITimer *aTimer, void *aListener)
instance->ShowTooltip();
}
void
nsXULTooltipListener::sAutoHideCallback(nsITimer *aTimer, void* aListener)
{
nsRefPtr<nsXULTooltipListener> instance = mInstance;
if (instance)
instance->HideTooltip();
}
#ifdef MOZ_XUL
nsresult
nsXULTooltipListener::GetSourceTreeBoxObject(nsITreeBoxObject** aBoxObject)

Просмотреть файл

@ -107,12 +107,10 @@ 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);
@ -146,17 +144,18 @@ protected:
// last cached mouse event
nsCOMPtr<nsIDOMEvent> mCachedMouseEvent;
// a timer for auto-hiding the tooltip after a certain delay
nsCOMPtr<nsITimer> mAutoHideTimer;
static void sAutoHideCallback (nsITimer* aTimer, void* aListener);
// various delays for tooltips
// various constants for tooltips
enum {
kTooltipAutoHideTime = 5000, // 5000ms = 5 seconds
kTooltipMouseMoveTolerance = 7, // 7 pixel tolerance for mousemove event
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;