mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 17:23:59 +00:00
Bug 376802 Use one global tooltip listener instead of creating one for each XUL element that needs one r=Smaug sr=jst
This commit is contained in:
parent
61877955f2
commit
af293ef660
@ -831,7 +831,6 @@ GK_ATOM(toolbarbutton, "toolbarbutton")
|
|||||||
GK_ATOM(toolbaritem, "toolbaritem")
|
GK_ATOM(toolbaritem, "toolbaritem")
|
||||||
GK_ATOM(toolbox, "toolbox")
|
GK_ATOM(toolbox, "toolbox")
|
||||||
GK_ATOM(tooltip, "tooltip")
|
GK_ATOM(tooltip, "tooltip")
|
||||||
GK_ATOM(tooltiplistener, "tooltiplistener")
|
|
||||||
GK_ATOM(tooltiptext, "tooltiptext")
|
GK_ATOM(tooltiptext, "tooltiptext")
|
||||||
GK_ATOM(top, "top")
|
GK_ATOM(top, "top")
|
||||||
GK_ATOM(topmargin, "topmargin")
|
GK_ATOM(topmargin, "topmargin")
|
||||||
|
@ -83,6 +83,7 @@
|
|||||||
#include "nsXULContentUtils.h"
|
#include "nsXULContentUtils.h"
|
||||||
#include "nsXULElement.h"
|
#include "nsXULElement.h"
|
||||||
#include "nsXULPrototypeCache.h"
|
#include "nsXULPrototypeCache.h"
|
||||||
|
#include "nsXULTooltipListener.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MOZ_MATHML
|
#ifdef MOZ_MATHML
|
||||||
@ -241,6 +242,7 @@ nsLayoutStatics::Shutdown()
|
|||||||
nsXULElement::ReleaseGlobals();
|
nsXULElement::ReleaseGlobals();
|
||||||
nsXULPrototypeCache::ReleaseGlobals();
|
nsXULPrototypeCache::ReleaseGlobals();
|
||||||
nsXULPrototypeElement::ReleaseGlobals();
|
nsXULPrototypeElement::ReleaseGlobals();
|
||||||
|
nsXULTooltipListener::ReleaseInstance();
|
||||||
nsSprocketLayout::Shutdown();
|
nsSprocketLayout::Shutdown();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -311,42 +311,16 @@ nsRootBoxFrame::SetDefaultTooltip(nsIContent* aTooltip)
|
|||||||
mDefaultTooltip = aTooltip;
|
mDefaultTooltip = aTooltip;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
TooltipListenerPropertyDtor(void *aObject, nsIAtom *aPropertyName,
|
|
||||||
void *aPropertyValue, void *aData)
|
|
||||||
{
|
|
||||||
nsXULTooltipListener* listener =
|
|
||||||
NS_STATIC_CAST(nsXULTooltipListener*, aPropertyValue);
|
|
||||||
if (listener) {
|
|
||||||
listener->RemoveTooltipSupport(NS_STATIC_CAST(nsIContent*, aObject));
|
|
||||||
NS_RELEASE(listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsRootBoxFrame::AddTooltipSupport(nsIContent* aNode)
|
nsRootBoxFrame::AddTooltipSupport(nsIContent* aNode)
|
||||||
{
|
{
|
||||||
NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
|
NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
|
||||||
nsRefPtr<nsXULTooltipListener> listener =
|
|
||||||
NS_STATIC_CAST(nsXULTooltipListener*,
|
|
||||||
aNode->GetProperty(nsGkAtoms::tooltiplistener));
|
|
||||||
if (listener) {
|
|
||||||
// Tooltip listener is already installed.
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
listener = new nsXULTooltipListener();
|
nsXULTooltipListener *listener = nsXULTooltipListener::GetInstance();
|
||||||
if (!listener)
|
if (!listener)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
if (NS_SUCCEEDED(listener->Init(aNode))) {
|
return listener->AddTooltipSupport(aNode);
|
||||||
nsresult rv = aNode->SetProperty(nsGkAtoms::tooltiplistener, listener,
|
|
||||||
TooltipListenerPropertyDtor, PR_TRUE);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
nsXULTooltipListener* listenerRef = listener;
|
|
||||||
NS_ADDREF(listenerRef);
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -61,6 +61,8 @@
|
|||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsIRootBox.h"
|
#include "nsIRootBox.h"
|
||||||
|
|
||||||
|
nsXULTooltipListener* nsXULTooltipListener::mInstance = nsnull;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
//// nsISupports
|
//// nsISupports
|
||||||
|
|
||||||
@ -199,7 +201,11 @@ nsXULTooltipListener::MouseMove(nsIDOMEvent* aMouseEvent)
|
|||||||
mMouseClientX = newMouseX;
|
mMouseClientX = newMouseX;
|
||||||
mMouseClientY = newMouseY;
|
mMouseClientY = newMouseY;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMEventTarget> eventTarget;
|
||||||
|
aMouseEvent->GetCurrentTarget(getter_AddRefs(eventTarget));
|
||||||
|
mSourceNode = do_QueryInterface(eventTarget);
|
||||||
#ifdef MOZ_XUL
|
#ifdef MOZ_XUL
|
||||||
|
mIsSourceTree = mSourceNode->Tag() == nsGkAtoms::treechildren;
|
||||||
if (mIsSourceTree)
|
if (mIsSourceTree)
|
||||||
CheckTreeBodyMove(mouseEvent);
|
CheckTreeBodyMove(mouseEvent);
|
||||||
#endif
|
#endif
|
||||||
@ -215,17 +221,15 @@ nsXULTooltipListener::MouseMove(nsIDOMEvent* aMouseEvent)
|
|||||||
if (!mCurrentTooltip) {
|
if (!mCurrentTooltip) {
|
||||||
mTooltipTimer = do_CreateInstance("@mozilla.org/timer;1");
|
mTooltipTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||||
if (mTooltipTimer) {
|
if (mTooltipTimer) {
|
||||||
nsCOMPtr<nsIDOMEventTarget> eventTarget;
|
|
||||||
aMouseEvent->GetTarget(getter_AddRefs(eventTarget));
|
aMouseEvent->GetTarget(getter_AddRefs(eventTarget));
|
||||||
if (eventTarget) {
|
mTargetNode = do_QueryInterface(eventTarget);
|
||||||
nsCOMPtr<nsIContent> targetContent(do_QueryInterface(eventTarget));
|
|
||||||
mTargetNode = targetContent;
|
|
||||||
}
|
|
||||||
if (mTargetNode) {
|
if (mTargetNode) {
|
||||||
nsresult rv = mTooltipTimer->InitWithFuncCallback(sTooltipCallback, this,
|
nsresult rv = mTooltipTimer->InitWithFuncCallback(sTooltipCallback, this,
|
||||||
kTooltipShowTime, nsITimer::TYPE_ONE_SHOT);
|
kTooltipShowTime, nsITimer::TYPE_ONE_SHOT);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv)) {
|
||||||
mTargetNode = nsnull;
|
mTargetNode = nsnull;
|
||||||
|
mSourceNode = nsnull;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -284,22 +288,6 @@ nsXULTooltipListener::PopupHiding(nsIDOMEvent* aEvent)
|
|||||||
PRBool nsXULTooltipListener::sShowTooltips = PR_FALSE;
|
PRBool nsXULTooltipListener::sShowTooltips = PR_FALSE;
|
||||||
PRUint32 nsXULTooltipListener::sTooltipListenerCount = 0;
|
PRUint32 nsXULTooltipListener::sTooltipListenerCount = 0;
|
||||||
|
|
||||||
// XXX: This could all be done in the ctor.
|
|
||||||
nsresult
|
|
||||||
nsXULTooltipListener::Init(nsIContent* aSourceNode)
|
|
||||||
{
|
|
||||||
mSourceNode = aSourceNode;
|
|
||||||
AddTooltipSupport(aSourceNode);
|
|
||||||
|
|
||||||
#ifdef MOZ_XUL
|
|
||||||
// if the target is an treechildren, we may have some special
|
|
||||||
// case handling to do
|
|
||||||
mIsSourceTree = mSourceNode->Tag() == nsGkAtoms::treechildren;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsXULTooltipListener::AddTooltipSupport(nsIContent* aNode)
|
nsXULTooltipListener::AddTooltipSupport(nsIContent* aNode)
|
||||||
{
|
{
|
||||||
@ -307,8 +295,8 @@ nsXULTooltipListener::AddTooltipSupport(nsIContent* aNode)
|
|||||||
return NS_ERROR_NULL_POINTER;
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMEventTarget> evtTarget(do_QueryInterface(aNode));
|
nsCOMPtr<nsIDOMEventTarget> evtTarget(do_QueryInterface(aNode));
|
||||||
evtTarget->AddEventListener(NS_LITERAL_STRING("mouseout"), (nsIDOMMouseListener*)this, PR_TRUE);
|
evtTarget->AddEventListener(NS_LITERAL_STRING("mouseout"), (nsIDOMMouseListener*)this, PR_FALSE);
|
||||||
evtTarget->AddEventListener(NS_LITERAL_STRING("mousemove"), (nsIDOMMouseListener*)this, PR_TRUE);
|
evtTarget->AddEventListener(NS_LITERAL_STRING("mousemove"), (nsIDOMMouseListener*)this, PR_FALSE);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -320,8 +308,8 @@ nsXULTooltipListener::RemoveTooltipSupport(nsIContent* aNode)
|
|||||||
return NS_ERROR_NULL_POINTER;
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMEventTarget> evtTarget(do_QueryInterface(aNode));
|
nsCOMPtr<nsIDOMEventTarget> evtTarget(do_QueryInterface(aNode));
|
||||||
evtTarget->RemoveEventListener(NS_LITERAL_STRING("mouseout"), (nsIDOMMouseListener*)this, PR_TRUE);
|
evtTarget->RemoveEventListener(NS_LITERAL_STRING("mouseout"), (nsIDOMMouseListener*)this, PR_FALSE);
|
||||||
evtTarget->RemoveEventListener(NS_LITERAL_STRING("mousemove"), (nsIDOMMouseListener*)this, PR_TRUE);
|
evtTarget->RemoveEventListener(NS_LITERAL_STRING("mousemove"), (nsIDOMMouseListener*)this, PR_FALSE);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -369,9 +357,7 @@ nsXULTooltipListener::CheckTreeBodyMove(nsIDOMMouseEvent* aMouseEvent)
|
|||||||
// XXX check the disabletitletips attribute on the tree content
|
// XXX check the disabletitletips attribute on the tree content
|
||||||
mNeedTitletip = PR_FALSE;
|
mNeedTitletip = PR_FALSE;
|
||||||
if (row >= 0 && obj.EqualsLiteral("text")) {
|
if (row >= 0 && obj.EqualsLiteral("text")) {
|
||||||
PRBool isCropped;
|
obx->IsCellCropped(row, col, &mNeedTitletip);
|
||||||
obx->IsCellCropped(row, col, &isCropped);
|
|
||||||
mNeedTitletip = isCropped;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCurrentTooltip && (row != mLastTreeRow || col != mLastTreeCol)) {
|
if (mCurrentTooltip && (row != mLastTreeRow || col != mLastTreeCol)) {
|
||||||
@ -405,8 +391,7 @@ nsXULTooltipListener::ShowTooltip()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> targetNode(do_QueryInterface(mTargetNode));
|
xulDoc->SetTooltipNode(mTargetNode);
|
||||||
xulDoc->SetTooltipNode(targetNode);
|
|
||||||
LaunchTooltip(mSourceNode, mMouseClientX, mMouseClientY);
|
LaunchTooltip(mSourceNode, mMouseClientX, mMouseClientY);
|
||||||
mTargetNode = nsnull;
|
mTargetNode = nsnull;
|
||||||
|
|
||||||
@ -440,6 +425,7 @@ nsXULTooltipListener::ShowTooltip()
|
|||||||
evtTarget->AddEventListener(NS_LITERAL_STRING("keydown"),
|
evtTarget->AddEventListener(NS_LITERAL_STRING("keydown"),
|
||||||
(nsIDOMMouseListener*)this, PR_TRUE);
|
(nsIDOMMouseListener*)this, PR_TRUE);
|
||||||
}
|
}
|
||||||
|
mSourceNode = nsnull;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -699,6 +685,10 @@ nsXULTooltipListener::DestroyTooltip()
|
|||||||
|
|
||||||
// kill any ongoing timers
|
// kill any ongoing timers
|
||||||
KillTooltipTimer();
|
KillTooltipTimer();
|
||||||
|
mSourceNode = nsnull;
|
||||||
|
#ifdef MOZ_XUL
|
||||||
|
mLastTreeCol = nsnull;
|
||||||
|
#endif
|
||||||
if (mAutoHideTimer) {
|
if (mAutoHideTimer) {
|
||||||
mAutoHideTimer->Cancel();
|
mAutoHideTimer->Cancel();
|
||||||
mAutoHideTimer = nsnull;
|
mAutoHideTimer = nsnull;
|
||||||
@ -734,19 +724,15 @@ nsXULTooltipListener::CreateAutoHideTimer()
|
|||||||
void
|
void
|
||||||
nsXULTooltipListener::sTooltipCallback(nsITimer *aTimer, void *aListener)
|
nsXULTooltipListener::sTooltipCallback(nsITimer *aTimer, void *aListener)
|
||||||
{
|
{
|
||||||
nsXULTooltipListener* self = NS_STATIC_CAST(nsXULTooltipListener*, aListener);
|
if (mInstance)
|
||||||
if (self)
|
mInstance->ShowTooltip();
|
||||||
self->ShowTooltip();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsXULTooltipListener::sAutoHideCallback(nsITimer *aTimer, void* aListener)
|
nsXULTooltipListener::sAutoHideCallback(nsITimer *aTimer, void* aListener)
|
||||||
{
|
{
|
||||||
nsXULTooltipListener* self = NS_STATIC_CAST(nsXULTooltipListener*, aListener);
|
if (mInstance)
|
||||||
if (self) {
|
mInstance->HideTooltip();
|
||||||
nsCOMPtr<nsIDOMMouseListener> kungFuDeathGrip(self);
|
|
||||||
self->HideTooltip();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MOZ_XUL
|
#ifdef MOZ_XUL
|
||||||
|
@ -60,9 +60,6 @@ class nsXULTooltipListener : public nsIDOMMouseListener,
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
nsXULTooltipListener();
|
|
||||||
virtual ~nsXULTooltipListener();
|
|
||||||
|
|
||||||
// nsISupports
|
// nsISupports
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
@ -96,12 +93,20 @@ public:
|
|||||||
// nsIDOMEventListener
|
// nsIDOMEventListener
|
||||||
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
|
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
|
||||||
|
|
||||||
nsresult Init(nsIContent* aSourceNode);
|
|
||||||
nsresult AddTooltipSupport(nsIContent* aNode);
|
nsresult AddTooltipSupport(nsIContent* aNode);
|
||||||
nsresult RemoveTooltipSupport(nsIContent* aNode);
|
nsresult RemoveTooltipSupport(nsIContent* aNode);
|
||||||
|
static nsXULTooltipListener* GetInstance() {
|
||||||
|
if (!mInstance)
|
||||||
|
NS_IF_ADDREF(mInstance = new nsXULTooltipListener());
|
||||||
|
return mInstance;
|
||||||
|
}
|
||||||
|
static void ReleaseInstance() { NS_IF_RELEASE(mInstance); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
nsXULTooltipListener();
|
||||||
|
~nsXULTooltipListener();
|
||||||
|
|
||||||
// pref callback for when the "show tooltips" pref changes
|
// pref callback for when the "show tooltips" pref changes
|
||||||
static int sTooltipPrefChanged (const char* aPref, void* aData);
|
static int sTooltipPrefChanged (const char* aPref, void* aData);
|
||||||
static PRBool sShowTooltips;
|
static PRBool sShowTooltips;
|
||||||
@ -125,10 +130,11 @@ protected:
|
|||||||
// can be really used (i.e. tooltip is not a menu).
|
// can be really used (i.e. tooltip is not a menu).
|
||||||
nsresult GetTooltipFor(nsIContent* aTarget, nsIContent** aTooltip);
|
nsresult GetTooltipFor(nsIContent* aTarget, nsIContent** aTooltip);
|
||||||
|
|
||||||
|
static nsXULTooltipListener* mInstance;
|
||||||
static int ToolbarTipsPrefChanged(const char *aPref, void *aClosure);
|
static int ToolbarTipsPrefChanged(const char *aPref, void *aClosure);
|
||||||
|
|
||||||
nsIContent* mSourceNode;
|
nsCOMPtr<nsIContent> mSourceNode;
|
||||||
nsCOMPtr<nsIContent> mTargetNode;
|
nsCOMPtr<nsIDOMNode> mTargetNode;
|
||||||
nsCOMPtr<nsIContent> mCurrentTooltip;
|
nsCOMPtr<nsIContent> mCurrentTooltip;
|
||||||
|
|
||||||
// a timer for showing the tooltip
|
// a timer for showing the tooltip
|
||||||
|
Loading…
Reference in New Issue
Block a user