diff options
| author | Kenny Daniel <platypii@gmail.com> | 2026-04-13 00:17:32 -0700 |
|---|---|---|
| committer | Kenny Daniel <platypii@gmail.com> | 2026-04-13 00:21:02 -0700 |
| commit | 8880ce63d6c1c02c08f1ae4e8023ac99a7533810 (patch) | |
| tree | f775961832906a4717b01754b733222ea856f164 /src | |
| parent | 08c5540e36fbd92d48ea3cc5b4ea4e8731c05a96 (diff) | |
| download | libayatana-indicator-8880ce63d6c1c02c08f1ae4e8023ac99a7533810.tar.gz libayatana-indicator-8880ce63d6c1c02c08f1ae4e8023ac99a7533810.tar.bz2 libayatana-indicator-8880ce63d6c1c02c08f1ae4e8023ac99a7533810.zip | |
src/indicator-ng.c: Fix GtkCssProvider memory leak in indicator_ng_set_label
indicator_ng_set_label() created a new GtkCssProvider and added it to
the label's GtkStyleContext on every call, without removing old ones.
gtk_style_context_add_provider() accumulates providers, so each call
leaked a provider (~1 KB).
Since ayatana-indicator-datetime sends action-state-changed once per
second to update the clock label, this leaked ~86,400 providers/day,
causing mate-indicator-applet-complete to accumulate ~1.4 GB RSS over
7 days.
Fix by storing a single GtkCssProvider in the IndicatorNg struct and
reusing it. The provider is created on first use and cleaned up in
dispose.
Test results (100,000 iterations of set_label):
Before fix: +99,692 KB RSS growth
After fix: +0 KB RSS growth
Diffstat (limited to 'src')
| -rw-r--r-- | src/indicator-ng.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/src/indicator-ng.c b/src/indicator-ng.c index a94f57e..0c76df6 100644 --- a/src/indicator-ng.c +++ b/src/indicator-ng.c @@ -53,6 +53,7 @@ struct _IndicatorNg gint64 last_service_restart; GMenuModel *lMenuSections[MENU_SECTIONS]; + GtkCssProvider *label_css_provider; }; static void indicator_ng_initable_iface_init (GInitableIface *initable); @@ -157,6 +158,7 @@ indicator_ng_dispose (GObject *object) indicator_ng_free_actions_and_menu (self); + g_clear_object (&self->label_css_provider); g_clear_object (&self->entry.label); g_clear_object (&self->entry.image); g_clear_object (&self->entry.menu); @@ -561,13 +563,14 @@ static void indicator_ng_set_label(IndicatorNg *self, const gchar *label) } GtkWidget *pParent = gtk_widget_get_parent(GTK_WIDGET(self->entry.label)); - GtkCssProvider *pCssProvider = gtk_css_provider_new(); - GtkStyleContext *pStyleContext = gtk_widget_get_style_context(GTK_WIDGET(self->entry.label)); - gtk_style_context_add_provider(pStyleContext, GTK_STYLE_PROVIDER(pCssProvider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + if (self->label_css_provider == NULL) { + self->label_css_provider = gtk_css_provider_new(); + GtkStyleContext *pStyleContext = gtk_widget_get_style_context(GTK_WIDGET(self->entry.label)); + gtk_style_context_add_provider(pStyleContext, GTK_STYLE_PROVIDER(self->label_css_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + } gchar *sCss = g_strdup_printf("label{padding-left: %ipx;}", nPadding); - gtk_css_provider_load_from_data(pCssProvider, sCss, -1, NULL); + gtk_css_provider_load_from_data(self->label_css_provider, sCss, -1, NULL); g_free(sCss); - g_object_unref(pCssProvider); if (GTK_IS_BOX(pParent)) { gtk_box_set_spacing(GTK_BOX(pParent), nSpacing); |
