Deskbar: Avoid leaking leaf bitmap's memory

In the vector case we are creating a bitmap, in the non-vector
case we are grabbing the bitmap from a resource.

The vector case we have to create a bitmap to rasterize.
The non-vector case we just grab the bitmap pointer.

We have to create new bitmaps from the vector icon at
different sizes, when we do that we were leaking the memory
occupied by the previous icon.

So make and use SetIcon() setter method which deletes the old
bitmap before setting the new one. In the non-vector case this
means we need to make a copy of the bitmap we grab from the
resources that we can safely delete.

Also delete bitmap on destructor.

For all other TBarMenuTitle's (meaning the team menu item),
we are grabbing a bitmap from resource, so don't delete the
bitmap as it is owned by resource set, we just use the pointer.
This commit is contained in:
John Scipione
2017-01-08 11:00:53 -08:00
parent ba7f14caec
commit 223ea4329f
2 changed files with 27 additions and 5 deletions
+24 -5
View File
@@ -37,6 +37,7 @@ All rights reserved.
#include "BarMenuTitle.h"
#include <algorithm>
#include <new>
#include <Bitmap.h>
#include <ControlLook.h>
@@ -155,7 +156,6 @@ TBarMenuTitle::Invoke(BMessage* message)
void
TBarMenuTitle::SetIcon(const BBitmap* icon)
{
delete fIcon;
fIcon = icon;
}
@@ -177,6 +177,20 @@ TDeskbarMenuTitle::TDeskbarMenuTitle(float width, float height,
}
TDeskbarMenuTitle::~TDeskbarMenuTitle()
{
delete fIcon;
}
void
TDeskbarMenuTitle::SetIcon(const BBitmap* icon)
{
delete fIcon;
fIcon = icon;
}
void
TDeskbarMenuTitle::DrawContent()
{
@@ -212,16 +226,21 @@ TDeskbarMenuTitle::FetchIcon()
}
float width = CalcIconWidth();
BBitmap* icon = new BBitmap(BRect(0, 0, width - 1, width - 1),
BBitmap* icon = new(std::nothrow) BBitmap(BRect(0, 0, width - 1, width - 1),
B_RGBA32);
if (fVectorIconData != NULL && fVectorIconSize > 0
if (fVectorIconData != NULL && fVectorIconSize > 0 && icon != NULL
&& BIconUtils::GetVectorIcon(fVectorIconData, fVectorIconSize, icon)
== B_OK) {
// rasterized vector icon into a bitmap
fIcon = icon;
SetIcon(icon);
} else {
// fetched bitmap instead
fIcon = AppResSet()->FindBitmap(B_MESSAGE_TYPE, R_LeafLogoBitmap);
const BBitmap* leaf = AppResSet()->FindBitmap(B_MESSAGE_TYPE,
R_LeafLogoBitmap);
// make a copy of the leaf bitmap that we can safely delete
BBitmap* leafCopy = new BBitmap(leaf->Bounds(), leaf->ColorSpace());
leafCopy->ImportBits(leaf);
SetIcon(leafCopy);
// TODO: scale the bitmap into icon
delete icon;
}
+3
View File
@@ -76,6 +76,9 @@ class TDeskbarMenuTitle : public TBarMenuTitle {
public:
TDeskbarMenuTitle(float width, float height,
const BBitmap* icon, BMenu* menu);
virtual ~TDeskbarMenuTitle();
virtual void SetIcon(const BBitmap* icon);
virtual void DrawContent();