Bug 1663784 - Make StatusBarEntry and IconLoader classes work with the cycle collector. r=mccr8

Depends on D90007

Differential Revision: https://phabricator.services.mozilla.com/D91644
This commit is contained in:
Mike Conley 2020-09-30 15:15:27 +00:00
Родитель 455e99b3e0
Коммит 2a5f7a42c2
7 изменённых файлов: 57 добавлений и 10 удалений

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

@ -17,7 +17,13 @@ using mozilla::gfx::SourceSurface;
namespace mozilla::widget {
NS_IMPL_ISUPPORTS(mozilla::widget::IconLoader, imgINotificationObserver)
NS_IMPL_CYCLE_COLLECTION(mozilla::widget::IconLoader, mContent, mHelper)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(mozilla::widget::IconLoader)
NS_INTERFACE_MAP_ENTRY(imgINotificationObserver)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(mozilla::widget::IconLoader)
NS_IMPL_CYCLE_COLLECTING_RELEASE(mozilla::widget::IconLoader)
IconLoader::IconLoader(Helper* aHelper, nsINode* aContent,
const nsIntRect& aImageRegionRect)

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

@ -10,6 +10,7 @@
#include "mozilla/RefPtr.h"
#include "nsCOMPtr.h"
#include "nsIContentPolicy.h"
#include "nsISupports.h"
class nsIURI;
class nsINode;
@ -32,9 +33,10 @@ class IconLoader : public imgINotificationObserver {
* Helper needs to implement the OnComplete method in order to handle the
* imgIContainer of the loaded icon.
*/
class Helper {
class Helper : public nsISupports {
public:
NS_INLINE_DECL_REFCOUNTING(mozilla::widget::IconLoader::Helper)
// Helper needs to implement nsISupports in order for its subclasses to
// participate in cycle collection
virtual nsresult OnComplete(imgIContainer* aContainer,
const nsIntRect& aRect) = 0;
@ -46,8 +48,9 @@ class IconLoader : public imgINotificationObserver {
const nsIntRect& aImageRegionRect);
public:
NS_DECL_ISUPPORTS
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_IMGINOTIFICATIONOBSERVER
NS_DECL_CYCLE_COLLECTION_CLASS(IconLoader)
// LoadIcon will start a load request for the icon.
// The request may not complete until after LoadIcon returns.

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

@ -36,6 +36,8 @@ class IconLoaderHelperCocoa final : public mozilla::widget::IconLoader::Helper {
IconLoaderHelperCocoa(mozilla::widget::IconLoaderListenerCocoa* aLoadListener,
uint32_t aIconHeight, uint32_t aIconWidth, CGFloat aScaleFactor = 0.0f);
NS_DECL_ISUPPORTS
nsresult OnComplete(imgIContainer* aImage, const nsIntRect& aRect) override;
/**

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

@ -43,6 +43,8 @@ using mozilla::widget::IconLoaderListenerCocoa;
namespace mozilla::widget {
NS_IMPL_ISUPPORTS0(IconLoaderHelperCocoa)
IconLoaderHelperCocoa::IconLoaderHelperCocoa(IconLoaderListenerCocoa* aListener,
uint32_t aIconHeight, uint32_t aIconWidth,
CGFloat aScaleFactor)

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

@ -29,9 +29,18 @@ using mozilla::widget::IconLoaderListenerWin;
namespace mozilla::widget {
NS_IMPL_CYCLE_COLLECTION(IconLoaderHelperWin, mLoadListener)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IconLoaderHelperWin)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(IconLoaderHelperWin)
NS_IMPL_CYCLE_COLLECTING_RELEASE(IconLoaderHelperWin)
IconLoaderHelperWin::IconLoaderHelperWin(IconLoaderListenerWin* aListener)
: mLoadListener(aListener) {
MOZ_ASSERT(aListener);
MOZ_ASSERT(NS_IsMainThread());
}
IconLoaderHelperWin::~IconLoaderHelperWin() { Destroy(); }

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

@ -7,6 +7,7 @@
#define mozilla_widget_IconLoaderHelperWin_h
#include "mozilla/widget/IconLoader.h"
#include "nsISupports.h"
namespace mozilla::widget {
@ -15,11 +16,12 @@ namespace mozilla::widget {
* IconLoaderListenerWin, and implement the OnComplete() method,
* which will be called once the load of the icon has completed.
*/
class IconLoaderListenerWin {
class IconLoaderListenerWin : public nsISupports {
public:
IconLoaderListenerWin() = default;
NS_INLINE_DECL_REFCOUNTING(mozilla::widget::IconLoaderListenerWin)
// IconLoaderListenerWin needs to implement nsISupports in order for its
// subclasses to participate in cycle collection.
virtual nsresult OnComplete() = 0;
@ -36,6 +38,11 @@ class IconLoaderHelperWin final : public mozilla::widget::IconLoader::Helper {
explicit IconLoaderHelperWin(
mozilla::widget::IconLoaderListenerWin* aLoadListener);
// IconLoaderHelperWin needs to implement nsISupports in order for its
// subclasses to participate in cycle collection.
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(IconLoaderHelperWin)
nsresult OnComplete(imgIContainer* aImage, const nsIntRect& aRect) override;
/**

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

@ -22,11 +22,14 @@ namespace mozilla::widget {
using mozilla::LinkedListElement;
using mozilla::dom::Element;
using mozilla::widget::IconLoaderListenerWin;
class StatusBarEntry final : public LinkedListElement<RefPtr<StatusBarEntry>>,
public mozilla::widget::IconLoaderListenerWin {
public IconLoaderListenerWin {
public:
explicit StatusBarEntry(Element* aMenu);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(StatusBarEntry)
nsresult Init();
LRESULT OnMessage(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp);
const Element* GetMenu() { return mMenu; };
@ -42,6 +45,24 @@ class StatusBarEntry final : public LinkedListElement<RefPtr<StatusBarEntry>>,
boolean mInitted;
};
NS_IMPL_CYCLE_COLLECTION_CLASS(StatusBarEntry)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(StatusBarEntry)
tmp->OnComplete();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(StatusBarEntry)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIconLoader)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIconLoaderHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMenu)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(StatusBarEntry)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(StatusBarEntry)
NS_IMPL_CYCLE_COLLECTING_RELEASE(StatusBarEntry)
StatusBarEntry::StatusBarEntry(Element* aMenu) : mMenu(aMenu), mInitted(false) {
mIconData = {/* cbSize */ sizeof(NOTIFYICONDATA),
/* hWnd */ 0,
@ -111,9 +132,6 @@ nsresult StatusBarEntry::Init() {
mIconLoaderHelper = new IconLoaderHelperWin(this);
nsIntRect rect;
mIconLoader = new IconLoader(mIconLoaderHelper, mMenu, rect);
if (!mIconLoader || !mIconLoaderHelper) {
return NS_ERROR_OUT_OF_MEMORY;
}
if (iconURI) {
rv = mIconLoader->LoadIcon(iconURI);