From ad7989e6dcfe00b40a08e3e8ff342e9dc14e6cb5 Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Tue, 23 Mar 2021 13:40:27 +0000 Subject: [PATCH] Bug 1699792 - Implement icon update listening without help from nsMenuObjectX. r=harry Depends on D109121 Differential Revision: https://phabricator.services.mozilla.com/D109122 --- widget/cocoa/nsMenuBaseX.h | 7 ------- widget/cocoa/nsMenuItemIconX.h | 10 +++++++--- widget/cocoa/nsMenuItemIconX.mm | 6 +++--- widget/cocoa/nsMenuItemX.h | 7 ++++++- widget/cocoa/nsMenuX.h | 18 +++++++++++++----- widget/cocoa/nsMenuX.mm | 4 ++-- widget/cocoa/nsStandaloneNativeMenu.h | 8 ++++++-- widget/cocoa/nsStandaloneNativeMenu.mm | 2 ++ 8 files changed, 39 insertions(+), 23 deletions(-) diff --git a/widget/cocoa/nsMenuBaseX.h b/widget/cocoa/nsMenuBaseX.h index 35252ad1b897..ed5324099343 100644 --- a/widget/cocoa/nsMenuBaseX.h +++ b/widget/cocoa/nsMenuBaseX.h @@ -27,13 +27,6 @@ class nsMenuObjectX { public: virtual ~nsMenuObjectX() {} virtual nsMenuObjectTypeX MenuObjectType() = 0; - - /** - * Called when an icon of a menu item somewhere in this menu has updated. - * Menu objects with parents need to propagate the notification to their - * parent. - */ - virtual void IconUpdated() {} }; // diff --git a/widget/cocoa/nsMenuItemIconX.h b/widget/cocoa/nsMenuItemIconX.h index 6be2531043e8..734f00329895 100644 --- a/widget/cocoa/nsMenuItemIconX.h +++ b/widget/cocoa/nsMenuItemIconX.h @@ -23,10 +23,14 @@ class nsMenuObjectX; class nsMenuItemIconX final : public mozilla::widget::IconLoader::Listener { public: - explicit nsMenuItemIconX(nsMenuObjectX* aMenuItem); + class Listener { + public: + virtual void IconUpdated() = 0; + }; + + explicit nsMenuItemIconX(Listener* aListener); ~nsMenuItemIconX(); - public: // SetupIcon starts the icon load. Once the icon has loaded, // nsMenuObjectX::IconUpdated will be called. The icon image needs to be // retrieved from GetIconImage(). If aContent is an icon-less menuitem, @@ -51,7 +55,7 @@ class nsMenuItemIconX final : public mozilla::widget::IconLoader::Listener { already_AddRefed GetIconURI(nsIContent* aContent); nsCOMPtr mContent; // always non-null - nsMenuObjectX* mMenuObject; // [weak] + Listener* mListener; // [weak] nsIntRect mImageRegionRect; NSImage* mIconImage = nil; // [strong] RefPtr mIconLoader; diff --git a/widget/cocoa/nsMenuItemIconX.mm b/widget/cocoa/nsMenuItemIconX.mm index b9ec23a96f3a..9221ea49c945 100644 --- a/widget/cocoa/nsMenuItemIconX.mm +++ b/widget/cocoa/nsMenuItemIconX.mm @@ -41,7 +41,7 @@ using mozilla::widget::IconLoader; static const uint32_t kIconSize = 16; -nsMenuItemIconX::nsMenuItemIconX(nsMenuObjectX* aMenuItem) : mMenuObject(aMenuItem) { +nsMenuItemIconX::nsMenuItemIconX(Listener* aListener) : mListener(aListener) { MOZ_COUNT_CTOR(nsMenuItemIconX); } @@ -168,8 +168,8 @@ nsresult nsMenuItemIconX::OnComplete(imgIContainer* aImage) { withSize:NSMakeSize(kIconSize, kIconSize) subrect:mImageRegionRect scaleFactor:0.0f] retain]; - if (mMenuObject) { - mMenuObject->IconUpdated(); + if (mListener) { + mListener->IconUpdated(); } mIconLoader->Destroy(); diff --git a/widget/cocoa/nsMenuItemX.h b/widget/cocoa/nsMenuItemX.h index e352e01fa662..ee30a5070392 100644 --- a/widget/cocoa/nsMenuItemX.h +++ b/widget/cocoa/nsMenuItemX.h @@ -10,6 +10,7 @@ #include "nsISupports.h" #include "nsMenuBaseX.h" #include "nsMenuGroupOwnerX.h" +#include "nsMenuItemIconX.h" #include "nsChangeObserver.h" #include "nsStringFwd.h" @@ -42,7 +43,9 @@ enum EMenuItemType { // Once instantiated, this object lives until its DOM node or its parent window // is destroyed. Do not hold references to this, they can become invalid any // time the DOM node can be destroyed. -class nsMenuItemX final : public nsMenuObjectX, public nsChangeObserver { +class nsMenuItemX final : public nsMenuObjectX, + public nsChangeObserver, + public nsMenuItemIconX::Listener { public: nsMenuItemX(nsMenuX* aParent, const nsString& aLabel, EMenuItemType aItemType, nsMenuGroupOwnerX* aMenuGroupOwner, nsIContent* aNode); @@ -64,6 +67,8 @@ class nsMenuItemX final : public nsMenuObjectX, public nsChangeObserver { // nsMenuObjectX nsMenuObjectTypeX MenuObjectType() override { return eMenuItemObjectType; } + + // nsMenuItemIconX::Listener void IconUpdated() override; // nsMenuItemX diff --git a/widget/cocoa/nsMenuX.h b/widget/cocoa/nsMenuX.h index f99a7c557b42..42ea469300fb 100644 --- a/widget/cocoa/nsMenuX.h +++ b/widget/cocoa/nsMenuX.h @@ -16,11 +16,11 @@ #include "nsMenuBaseX.h" #include "nsMenuBarX.h" #include "nsMenuGroupOwnerX.h" +#include "nsMenuItemIconX.h" #include "nsCOMPtr.h" #include "nsChangeObserver.h" class nsMenuX; -class nsMenuItemIconX; class nsMenuItemX; class nsIWidget; @@ -34,7 +34,9 @@ class nsIWidget; // Once instantiated, this object lives until its DOM node or its parent window is destroyed. // Do not hold references to this, they can become invalid any time the DOM node can be destroyed. -class nsMenuX final : public nsMenuObjectX, public nsChangeObserver { +class nsMenuX final : public nsMenuObjectX, + public nsChangeObserver, + public nsMenuItemIconX::Listener { public: using MenuChild = mozilla::Variant, RefPtr>; @@ -51,6 +53,8 @@ class nsMenuX final : public nsMenuObjectX, public nsChangeObserver { // nsMenuObjectX nsMenuObjectTypeX MenuObjectType() override { return eSubmenuObjectType; } + + // nsMenuItemIconX::Listener void IconUpdated() override; // nsMenuX @@ -88,6 +92,9 @@ class nsMenuX final : public nsMenuObjectX, public nsChangeObserver { NSMenuItem* NativeNSMenuItem() { return mNativeMenuItem; } GeckoNSMenu* NativeNSMenu() { return mNativeMenu; } + void SetIconListener(nsMenuItemIconX::Listener* aListener) { mIconListener = aListener; } + void ClearIconListener() { mIconListener = nullptr; } + // If aChild is one of our child menus, insert aChild's native menu item in our native menu at the // right location. void InsertChildNativeMenuItem(nsMenuX* aChild); @@ -128,9 +135,10 @@ class nsMenuX final : public nsMenuObjectX, public nsChangeObserver { nsTArray mMenuChildren; nsString mLabel; - uint32_t mVisibleItemsCount = 0; // cache - nsMenuObjectX* mParent = nullptr; // [weak] - nsMenuGroupOwnerX* mMenuGroupOwner = nullptr; // [weak] + uint32_t mVisibleItemsCount = 0; // cache + nsMenuObjectX* mParent = nullptr; // [weak] + nsMenuGroupOwnerX* mMenuGroupOwner = nullptr; // [weak] + nsMenuItemIconX::Listener* mIconListener = nullptr; // [weak] mozilla::UniquePtr mIcon; GeckoNSMenu* mNativeMenu = nil; // [strong] MenuDelegate* mMenuDelegate = nil; // [strong] diff --git a/widget/cocoa/nsMenuX.mm b/widget/cocoa/nsMenuX.mm index 8b3b01e825d4..b3baf1c537b4 100644 --- a/widget/cocoa/nsMenuX.mm +++ b/widget/cocoa/nsMenuX.mm @@ -657,8 +657,8 @@ void nsMenuX::SetupIcon() { void nsMenuX::IconUpdated() { mNativeMenuItem.image = mIcon->GetIconImage(); - if (mParent) { - mParent->IconUpdated(); + if (mIconListener) { + mIconListener->IconUpdated(); } } diff --git a/widget/cocoa/nsStandaloneNativeMenu.h b/widget/cocoa/nsStandaloneNativeMenu.h index 6adcf07f1ccc..38f7f9050675 100644 --- a/widget/cocoa/nsStandaloneNativeMenu.h +++ b/widget/cocoa/nsStandaloneNativeMenu.h @@ -7,11 +7,13 @@ #define nsStandaloneNativeMenu_h_ #include "nsMenuGroupOwnerX.h" +#include "nsMenuItemIconX.h" #include "nsMenuX.h" #include "nsIStandaloneNativeMenu.h" class nsStandaloneNativeMenu : public nsMenuGroupOwnerX, - public nsIStandaloneNativeMenu { + public nsIStandaloneNativeMenu, + public nsMenuItemIconX::Listener { public: nsStandaloneNativeMenu(); @@ -22,7 +24,9 @@ class nsStandaloneNativeMenu : public nsMenuGroupOwnerX, nsMenuObjectTypeX MenuObjectType() override { return eStandaloneNativeMenuObjectType; } - virtual void IconUpdated() override; + + // nsMenuItemIconX::Listener + void IconUpdated() override; NSMenu* NativeNSMenu() { return mMenu ? mMenu->NativeNSMenu() : nil; } diff --git a/widget/cocoa/nsStandaloneNativeMenu.mm b/widget/cocoa/nsStandaloneNativeMenu.mm index 18eb7bc82c34..acf19fa448e1 100644 --- a/widget/cocoa/nsStandaloneNativeMenu.mm +++ b/widget/cocoa/nsStandaloneNativeMenu.mm @@ -26,6 +26,7 @@ nsStandaloneNativeMenu::~nsStandaloneNativeMenu() { if (mMenu) { mMenu->DetachFromGroupOwnerRecursive(); mMenu->DetachFromParent(); + mMenu->ClearIconListener(); } } @@ -45,6 +46,7 @@ nsStandaloneNativeMenu::Init(Element* aElement) { } mMenu = MakeRefPtr(this, this, aElement); + mMenu->SetIconListener(this); mMenu->SetupIcon(); return NS_OK;