Bug 1342874 - (Part 4) DocGroup labeling for timer callbacks in nsMenuFrame. r?dholbert
Note that we still use InitWithCallback() instead of upgrading to
InitWithNamedFuncCallback(). This is because they have different lifetime
implications for the callback arg that nsMenuFrame passes in, mTimerMediator.
So to label the callback with InitWithCallback(), we make nsMenuTimerMediator
inherit from nsINamed to provide the label via that API's GetName method.
MozReview-Commit-ID: 45c6kDF2xCJ
--- a/layout/xul/nsMenuFrame.cpp
+++ b/layout/xul/nsMenuFrame.cpp
@@ -520,16 +520,18 @@ nsMenuFrame::HandleEvent(nsPresContext*
// past the menu. This conditional check ensures that only menus have this
// behaviour
if (!IsDisabled() && IsMenu() && !IsOpen() && !mOpenTimer && !menuParent->IsMenuBar()) {
int32_t menuDelay =
LookAndFeel::GetInt(LookAndFeel::eIntID_SubmenuDelay, 300); // ms
// We're a menu, we're built, we're closed, and no timer has been kicked off.
mOpenTimer = do_CreateInstance("@mozilla.org/timer;1");
+ mOpenTimer->SetTarget(
+ mContent->OwnerDoc()->EventTargetFor(TaskCategory::Other));
mOpenTimer->InitWithCallback(mTimerMediator, menuDelay, nsITimer::TYPE_ONE_SHOT);
}
}
return NS_OK;
}
void
@@ -1232,16 +1234,18 @@ nsMenuFrame::StartBlinking(WidgetGUIEven
nsMenuParent* menuParent = GetMenuParent();
if (menuParent) {
// Make this menu ignore events from now on.
menuParent->LockMenuUntilClosed(true);
}
// Set up a timer to blink back on.
mBlinkTimer = do_CreateInstance("@mozilla.org/timer;1");
+ mBlinkTimer->SetTarget(
+ mContent->OwnerDoc()->EventTargetFor(TaskCategory::Other));
mBlinkTimer->InitWithCallback(mTimerMediator, kBlinkDelay, nsITimer::TYPE_ONE_SHOT);
mBlinkState = 1;
}
void
nsMenuFrame::StopBlinking()
{
mBlinkState = 0;
@@ -1475,18 +1479,18 @@ nsIScrollableFrame* nsMenuFrame::GetScro
// nsMenuTimerMediator implementation.
NS_IMPL_ISUPPORTS(nsMenuTimerMediator, nsITimerCallback)
/**
* Constructs a wrapper around an nsMenuFrame.
* @param aFrame nsMenuFrame to create a wrapper around.
*/
-nsMenuTimerMediator::nsMenuTimerMediator(nsMenuFrame *aFrame) :
- mFrame(aFrame)
+nsMenuTimerMediator::nsMenuTimerMediator(nsMenuFrame *aFrame)
+ : mFrame(aFrame)
{
NS_ASSERTION(mFrame, "Must have frame");
}
nsMenuTimerMediator::~nsMenuTimerMediator()
{
}
@@ -1506,8 +1510,30 @@ NS_IMETHODIMP nsMenuTimerMediator::Notif
/**
* Clear the pointer to the contained nsMenuFrame. This should be called
* when the contained nsMenuFrame is destroyed.
*/
void nsMenuTimerMediator::ClearFrame()
{
mFrame = nullptr;
}
+
+/**
+ * Get the name of this timer callback.
+ * @param aName the name to return
+ */
+NS_IMETHODIMP
+nsMenuTimerMediator::GetName(nsACString& aName)
+{
+ aName.AssignLiteral("nsMenuTimerMediator");
+ return NS_OK;
+}
+
+/**
+ * Set the name to this timer callback.
+ * @param aName the name to set
+ */
+NS_IMETHODIMP
+nsMenuTimerMediator::SetName(const char* aName)
+{
+ // We don't need to change the name for nsMenuTimerMediator.
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
--- a/layout/xul/nsMenuFrame.h
+++ b/layout/xul/nsMenuFrame.h
@@ -13,16 +13,17 @@
#include "nsIAtom.h"
#include "nsCOMPtr.h"
#include "nsBoxFrame.h"
#include "nsFrameList.h"
#include "nsGkAtoms.h"
#include "nsMenuParent.h"
#include "nsXULPopupManager.h"
+#include "nsINamed.h"
#include "nsIReflowCallback.h"
#include "nsITimer.h"
#include "mozilla/Attributes.h"
nsIFrame* NS_NewMenuFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
nsIFrame* NS_NewMenuItemFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
class nsIContent;
@@ -50,23 +51,25 @@ class nsMenuFrame;
/**
* nsMenuTimerMediator is a wrapper around an nsMenuFrame which can be safely
* passed to timers. The class is reference counted unlike the underlying
* nsMenuFrame, so that it will exist as long as the timer holds a reference
* to it. The callback is delegated to the contained nsMenuFrame as long as
* the contained nsMenuFrame has not been destroyed.
*/
-class nsMenuTimerMediator final : public nsITimerCallback
+class nsMenuTimerMediator final : public nsITimerCallback,
+ public nsINamed
{
public:
explicit nsMenuTimerMediator(nsMenuFrame* aFrame);
NS_DECL_ISUPPORTS
NS_DECL_NSITIMERCALLBACK
+ NS_DECL_NSINAMED
void ClearFrame();
private:
~nsMenuTimerMediator();
// Pointer to the wrapped frame.
nsMenuFrame* mFrame;