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:
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() {}
};
//

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

@ -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<nsIURI> GetIconURI(nsIContent* aContent);
nsCOMPtr<nsIContent> mContent; // always non-null
nsMenuObjectX* mMenuObject; // [weak]
Listener* mListener; // [weak]
nsIntRect mImageRegionRect;
NSImage* mIconImage = nil; // [strong]
RefPtr<mozilla::widget::IconLoader> mIconLoader;

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

@ -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();

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

@ -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

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

@ -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<nsMenuX>, RefPtr<nsMenuItemX>>;
@ -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<MenuChild> 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<nsMenuItemIconX> mIcon;
GeckoNSMenu* mNativeMenu = nil; // [strong]
MenuDelegate* mMenuDelegate = nil; // [strong]

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

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

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

@ -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; }

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

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