Bug 1699792 - Implement icon update listening without help from nsMenuObjectX. r=harry

Depends on D109121

Differential Revision: https://phabricator.services.mozilla.com/D109122
This commit is contained in:
Markus Stange 2021-03-23 13:40:27 +00:00
Родитель 10f6d5b657
Коммит ad7989e6dc
8 изменённых файлов: 39 добавлений и 23 удалений

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

@ -27,13 +27,6 @@ class nsMenuObjectX {
public: public:
virtual ~nsMenuObjectX() {} virtual ~nsMenuObjectX() {}
virtual nsMenuObjectTypeX MenuObjectType() = 0; 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() {}
}; };
// //

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

@ -23,10 +23,14 @@ class nsMenuObjectX;
class nsMenuItemIconX final : public mozilla::widget::IconLoader::Listener { class nsMenuItemIconX final : public mozilla::widget::IconLoader::Listener {
public: public:
explicit nsMenuItemIconX(nsMenuObjectX* aMenuItem); class Listener {
public:
virtual void IconUpdated() = 0;
};
explicit nsMenuItemIconX(Listener* aListener);
~nsMenuItemIconX(); ~nsMenuItemIconX();
public:
// SetupIcon starts the icon load. Once the icon has loaded, // SetupIcon starts the icon load. Once the icon has loaded,
// nsMenuObjectX::IconUpdated will be called. The icon image needs to be // nsMenuObjectX::IconUpdated will be called. The icon image needs to be
// retrieved from GetIconImage(). If aContent is an icon-less menuitem, // retrieved from GetIconImage(). If aContent is an icon-less menuitem,
@ -51,7 +55,7 @@ class nsMenuItemIconX final : public mozilla::widget::IconLoader::Listener {
already_AddRefed<nsIURI> GetIconURI(nsIContent* aContent); already_AddRefed<nsIURI> GetIconURI(nsIContent* aContent);
nsCOMPtr<nsIContent> mContent; // always non-null nsCOMPtr<nsIContent> mContent; // always non-null
nsMenuObjectX* mMenuObject; // [weak] Listener* mListener; // [weak]
nsIntRect mImageRegionRect; nsIntRect mImageRegionRect;
NSImage* mIconImage = nil; // [strong] NSImage* mIconImage = nil; // [strong]
RefPtr<mozilla::widget::IconLoader> mIconLoader; RefPtr<mozilla::widget::IconLoader> mIconLoader;

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

@ -41,7 +41,7 @@ using mozilla::widget::IconLoader;
static const uint32_t kIconSize = 16; static const uint32_t kIconSize = 16;
nsMenuItemIconX::nsMenuItemIconX(nsMenuObjectX* aMenuItem) : mMenuObject(aMenuItem) { nsMenuItemIconX::nsMenuItemIconX(Listener* aListener) : mListener(aListener) {
MOZ_COUNT_CTOR(nsMenuItemIconX); MOZ_COUNT_CTOR(nsMenuItemIconX);
} }
@ -168,8 +168,8 @@ nsresult nsMenuItemIconX::OnComplete(imgIContainer* aImage) {
withSize:NSMakeSize(kIconSize, kIconSize) withSize:NSMakeSize(kIconSize, kIconSize)
subrect:mImageRegionRect subrect:mImageRegionRect
scaleFactor:0.0f] retain]; scaleFactor:0.0f] retain];
if (mMenuObject) { if (mListener) {
mMenuObject->IconUpdated(); mListener->IconUpdated();
} }
mIconLoader->Destroy(); mIconLoader->Destroy();

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

@ -10,6 +10,7 @@
#include "nsISupports.h" #include "nsISupports.h"
#include "nsMenuBaseX.h" #include "nsMenuBaseX.h"
#include "nsMenuGroupOwnerX.h" #include "nsMenuGroupOwnerX.h"
#include "nsMenuItemIconX.h"
#include "nsChangeObserver.h" #include "nsChangeObserver.h"
#include "nsStringFwd.h" #include "nsStringFwd.h"
@ -42,7 +43,9 @@ enum EMenuItemType {
// Once instantiated, this object lives until its DOM node or its parent window // 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 // is destroyed. Do not hold references to this, they can become invalid any
// time the DOM node can be destroyed. // 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: public:
nsMenuItemX(nsMenuX* aParent, const nsString& aLabel, EMenuItemType aItemType, nsMenuItemX(nsMenuX* aParent, const nsString& aLabel, EMenuItemType aItemType,
nsMenuGroupOwnerX* aMenuGroupOwner, nsIContent* aNode); nsMenuGroupOwnerX* aMenuGroupOwner, nsIContent* aNode);
@ -64,6 +67,8 @@ class nsMenuItemX final : public nsMenuObjectX, public nsChangeObserver {
// nsMenuObjectX // nsMenuObjectX
nsMenuObjectTypeX MenuObjectType() override { return eMenuItemObjectType; } nsMenuObjectTypeX MenuObjectType() override { return eMenuItemObjectType; }
// nsMenuItemIconX::Listener
void IconUpdated() override; void IconUpdated() override;
// nsMenuItemX // nsMenuItemX

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

@ -16,11 +16,11 @@
#include "nsMenuBaseX.h" #include "nsMenuBaseX.h"
#include "nsMenuBarX.h" #include "nsMenuBarX.h"
#include "nsMenuGroupOwnerX.h" #include "nsMenuGroupOwnerX.h"
#include "nsMenuItemIconX.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsChangeObserver.h" #include "nsChangeObserver.h"
class nsMenuX; class nsMenuX;
class nsMenuItemIconX;
class nsMenuItemX; class nsMenuItemX;
class nsIWidget; class nsIWidget;
@ -34,7 +34,9 @@ class nsIWidget;
// Once instantiated, this object lives until its DOM node or its parent window is destroyed. // 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. // 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: public:
using MenuChild = mozilla::Variant<RefPtr<nsMenuX>, RefPtr<nsMenuItemX>>; using MenuChild = mozilla::Variant<RefPtr<nsMenuX>, RefPtr<nsMenuItemX>>;
@ -51,6 +53,8 @@ class nsMenuX final : public nsMenuObjectX, public nsChangeObserver {
// nsMenuObjectX // nsMenuObjectX
nsMenuObjectTypeX MenuObjectType() override { return eSubmenuObjectType; } nsMenuObjectTypeX MenuObjectType() override { return eSubmenuObjectType; }
// nsMenuItemIconX::Listener
void IconUpdated() override; void IconUpdated() override;
// nsMenuX // nsMenuX
@ -88,6 +92,9 @@ class nsMenuX final : public nsMenuObjectX, public nsChangeObserver {
NSMenuItem* NativeNSMenuItem() { return mNativeMenuItem; } NSMenuItem* NativeNSMenuItem() { return mNativeMenuItem; }
GeckoNSMenu* NativeNSMenu() { return mNativeMenu; } 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 // If aChild is one of our child menus, insert aChild's native menu item in our native menu at the
// right location. // right location.
void InsertChildNativeMenuItem(nsMenuX* aChild); void InsertChildNativeMenuItem(nsMenuX* aChild);
@ -128,9 +135,10 @@ class nsMenuX final : public nsMenuObjectX, public nsChangeObserver {
nsTArray<MenuChild> mMenuChildren; nsTArray<MenuChild> mMenuChildren;
nsString mLabel; nsString mLabel;
uint32_t mVisibleItemsCount = 0; // cache uint32_t mVisibleItemsCount = 0; // cache
nsMenuObjectX* mParent = nullptr; // [weak] nsMenuObjectX* mParent = nullptr; // [weak]
nsMenuGroupOwnerX* mMenuGroupOwner = nullptr; // [weak] nsMenuGroupOwnerX* mMenuGroupOwner = nullptr; // [weak]
nsMenuItemIconX::Listener* mIconListener = nullptr; // [weak]
mozilla::UniquePtr<nsMenuItemIconX> mIcon; mozilla::UniquePtr<nsMenuItemIconX> mIcon;
GeckoNSMenu* mNativeMenu = nil; // [strong] GeckoNSMenu* mNativeMenu = nil; // [strong]
MenuDelegate* mMenuDelegate = nil; // [strong] MenuDelegate* mMenuDelegate = nil; // [strong]

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

@ -657,8 +657,8 @@ void nsMenuX::SetupIcon() {
void nsMenuX::IconUpdated() { void nsMenuX::IconUpdated() {
mNativeMenuItem.image = mIcon->GetIconImage(); mNativeMenuItem.image = mIcon->GetIconImage();
if (mParent) { if (mIconListener) {
mParent->IconUpdated(); mIconListener->IconUpdated();
} }
} }

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

@ -7,11 +7,13 @@
#define nsStandaloneNativeMenu_h_ #define nsStandaloneNativeMenu_h_
#include "nsMenuGroupOwnerX.h" #include "nsMenuGroupOwnerX.h"
#include "nsMenuItemIconX.h"
#include "nsMenuX.h" #include "nsMenuX.h"
#include "nsIStandaloneNativeMenu.h" #include "nsIStandaloneNativeMenu.h"
class nsStandaloneNativeMenu : public nsMenuGroupOwnerX, class nsStandaloneNativeMenu : public nsMenuGroupOwnerX,
public nsIStandaloneNativeMenu { public nsIStandaloneNativeMenu,
public nsMenuItemIconX::Listener {
public: public:
nsStandaloneNativeMenu(); nsStandaloneNativeMenu();
@ -22,7 +24,9 @@ class nsStandaloneNativeMenu : public nsMenuGroupOwnerX,
nsMenuObjectTypeX MenuObjectType() override { nsMenuObjectTypeX MenuObjectType() override {
return eStandaloneNativeMenuObjectType; return eStandaloneNativeMenuObjectType;
} }
virtual void IconUpdated() override;
// nsMenuItemIconX::Listener
void IconUpdated() override;
NSMenu* NativeNSMenu() { return mMenu ? mMenu->NativeNSMenu() : nil; } NSMenu* NativeNSMenu() { return mMenu ? mMenu->NativeNSMenu() : nil; }

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

@ -26,6 +26,7 @@ nsStandaloneNativeMenu::~nsStandaloneNativeMenu() {
if (mMenu) { if (mMenu) {
mMenu->DetachFromGroupOwnerRecursive(); mMenu->DetachFromGroupOwnerRecursive();
mMenu->DetachFromParent(); mMenu->DetachFromParent();
mMenu->ClearIconListener();
} }
} }
@ -45,6 +46,7 @@ nsStandaloneNativeMenu::Init(Element* aElement) {
} }
mMenu = MakeRefPtr<nsMenuX>(this, this, aElement); mMenu = MakeRefPtr<nsMenuX>(this, this, aElement);
mMenu->SetIconListener(this);
mMenu->SetupIcon(); mMenu->SetupIcon();
return NS_OK; return NS_OK;