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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user