From 223ea4329f3dd3282de0ba198d36a515a4b20265 Mon Sep 17 00:00:00 2001 From: John Scipione Date: Sun, 8 Jan 2017 11:00:53 -0800 Subject: [PATCH] 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. --- src/apps/deskbar/BarMenuTitle.cpp | 29 ++++++++++++++++++++++++----- src/apps/deskbar/BarMenuTitle.h | 3 +++ 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/apps/deskbar/BarMenuTitle.cpp b/src/apps/deskbar/BarMenuTitle.cpp index bd589f496c..c45fb21fea 100644 --- a/src/apps/deskbar/BarMenuTitle.cpp +++ b/src/apps/deskbar/BarMenuTitle.cpp @@ -37,6 +37,7 @@ All rights reserved. #include "BarMenuTitle.h" #include +#include #include #include @@ -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; } diff --git a/src/apps/deskbar/BarMenuTitle.h b/src/apps/deskbar/BarMenuTitle.h index a4f68cd14d..7522283ffb 100644 --- a/src/apps/deskbar/BarMenuTitle.h +++ b/src/apps/deskbar/BarMenuTitle.h @@ -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();