From 2a14004fc37c855a762eac3967956acd642407a2 Mon Sep 17 00:00:00 2001 From: David Maciejak Date: Fri, 10 Feb 2023 19:00:00 +0800 Subject: [PATCH] SwitchPanel: make sure WMRetainColor and WMReleaseColor calls are even The number of calls to WMRetainColor for a color in use should the same as the number of calls to WMReleaseColor to free that color. In case of discrepancy, random crashes can happen and memory is not freed properly. To debug that issue I checked the retained colors when the switchpanel is opened and then checked if those colors are properly released once the panel is closed. This patch fixes the issue mentioned at https://github.com/window-maker/wmaker/issues/22 --- WINGs/wcolor.c | 4 ++-- WINGs/wframe.c | 3 +++ src/switchpanel.c | 13 ++++++++----- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/WINGs/wcolor.c b/WINGs/wcolor.c index 9d276da3..6c0d934c 100644 --- a/WINGs/wcolor.c +++ b/WINGs/wcolor.c @@ -91,7 +91,7 @@ WMColor *WMCreateRGBColor(WMScreen * scr, unsigned short red, unsigned short gre color = findCloseColor(scr, red, green, blue, 0xffff); } if (!color) - color = WMBlackColor(scr); + color = scr->black; return color; } @@ -117,7 +117,7 @@ WMColor *WMCreateRGBAColor(WMScreen * scr, unsigned short red, unsigned short gr color = findCloseColor(scr, red, green, blue, alpha); } if (!color) - color = WMBlackColor(scr); + color = scr->black; return color; } diff --git a/WINGs/wframe.c b/WINGs/wframe.c index ad2fc017..1eb3caa2 100644 --- a/WINGs/wframe.c +++ b/WINGs/wframe.c @@ -253,6 +253,9 @@ WMFrame *WMCreateFrame(WMWidget * parent) static void destroyFrame(Frame * fPtr) { + if (fPtr->textColor) + WMReleaseColor(fPtr->textColor); + if (fPtr->caption) wfree(fPtr->caption); diff --git a/src/switchpanel.c b/src/switchpanel.c index 89675b0f..4b333c36 100644 --- a/src/switchpanel.c +++ b/src/switchpanel.c @@ -61,6 +61,7 @@ struct SwitchPanel { WMFont *font; WMColor *white; + WMColor *gray; }; /* these values will be updated whenever the switch panel @@ -154,11 +155,9 @@ static void changeImage(WSwitchPanel *panel, int idecks, int selected, Bool dim, border_space + pos.y, back->width, back->height, 0, 0); } else { RColor color; - WMScreen *wscr = WMWidgetScreen(icon); - color.red = 255; - color.red = WMRedComponentOfColor(WMGrayColor(wscr)) >> 8; - color.green = WMGreenComponentOfColor(WMGrayColor(wscr)) >> 8; - color.blue = WMBlueComponentOfColor(WMGrayColor(wscr)) >> 8; + color.red = WMRedComponentOfColor(panel->gray) >> 8; + color.green = WMGreenComponentOfColor(panel->gray) >> 8; + color.blue = WMBlueComponentOfColor(panel->gray) >> 8; RFillImage(back, &color); } @@ -454,6 +453,7 @@ WSwitchPanel *wInitSwitchPanel(WScreen *scr, WWindow *curwin, Bool class_only) } panel->white = WMWhiteColor(scr->wmscreen); + panel->gray = WMGrayColor(scr->wmscreen); panel->font = WMBoldSystemFontOfSize(scr->wmscreen, WMScaleY(12)); panel->icons = WMCreateArray(count); panel->images = WMCreateArray(count); @@ -589,6 +589,9 @@ void wSwitchPanelDestroy(WSwitchPanel *panel) if (panel->white) WMReleaseColor(panel->white); + if (panel->gray) + WMReleaseColor(panel->gray); + wfree(panel); }