diff options
| -rw-r--r-- | AUTHORS | 94 | ||||
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | ChangeLog | 71 | ||||
| -rw-r--r-- | NEWS | 12 | ||||
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | debian/changelog | 7 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/indicator-desktop-shortcuts.c | 1 | ||||
| -rw-r--r-- | src/indicator-ng.c | 13 | ||||
| -rw-r--r-- | tests/CMakeLists.txt | 27 | ||||
| -rw-r--r-- | tests/test-css-provider-leak.c | 128 | ||||
| -rw-r--r-- | tests/test-indicator-ng.c | 4 | ||||
| -rw-r--r-- | tools/CMakeLists.txt | 2 |
13 files changed, 304 insertions, 61 deletions
@@ -1,46 +1,48 @@ -Alexander Schlarb <alexander@ninetailed.ninja> -Allan LeSage <allanlesage@gmail.com> -Aurelien Gateau <aurelien.gateau@canonical.com> -Charles Kerr <charles.kerr@canonical.com> -Cody Russell <crussell@canonical.com> -Colin Watson <cjwatson@canonical.com> -Daniel d'Andrada <daniel.dandrada@canonical.com> -Dani Llewellyn <diddledani@ubuntu.com> -Didier Roche <didier.roche@canonical.com> -Didier Roche <didrocks@ubuntu.com> -Eitan Isaacson <eitan@ascender.com> -Evgeni Golov <evgeni@debian.org> -György Balló <ballogy@freestart.hu> -Hernando Torque <sirius@sonnenkinder.org> -Iain Lane <iain.lane@canonical.com> -Iain Lane <iain@orangesquash.org.uk> -Javier Jardón <javier.jardon@codethink.co.uk> -Jonathan Riddell <jriddell@canonical.com> -Karl <karl@karl-desktop> -Ken VanDine <ken.vandine@canonical.com> -Lars Uebernickel <lars.uebernickel@canonical.com> -Łukasz 'sil2100' Zemczak <lukasz.zemczak@canonical.com> -Luke Yelavich <luke.yelavich@canonical.com> -Marco Trevisan (Treviño) <mail@3v1n0.net> -Marius Gripsgard <marius@ubports.com> -Martin Pitt <martin.pitt@canonical.com> -Mathieu Trudel-Lapierre <mathieu-tl@ubuntu.com> -Michael Terry <michael.terry@canonical.com> -Michael Terry <mike@mterry.name> -Mike Gabriel <mike.gabriel@das-netzwerkteam.de> -Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com> -Neil Jagdish Patel <neil.patel@canonical.com> -Robert Ancell <robert.ancell@canonical.com> -Robert Carr <racarr@ender> -Robert Collins <robertc@robertcollins.net> -Robert Tari <robert@tari.in> -seb128 <seb128@seb128-desktop> -Sebastien Bacher <seb128@ubuntu.com> -Steve Langasek <steve.langasek@canonical.com> -Ted Gould <ted@canonical.com> -Ted Gould <ted@gould.cx> -Ted Gould <ted@ubuntu.com> -Till Maas <opensource@till.name> -Timo Jyrinki <timo.jyrinki@canonical.com> -unknown <robert.ancell@canonical.com> -William Hua <william.hua@canonical.com> +Alessandro Astone +Alexander Schlarb +Allan LeSage +Aurelien Gateau +Charles Kerr +Cody Russell +Colin Watson +Daniel D'Andrada +Dani Llewellyn +Didier Roche +Eitan Isaacson +Evgeni Golov +Florian Märkl +György Balló +Hernando Torque +Iain Lane +Javier Jardón +Jonathan Riddell +Karl +Kenny Daniel +Ken VanDine +Lars Uebernickel +Łukasz 'sil2100' Zemczak +Luke Yelavich +Marco Trevisan (Treviño) +Marius Gripsgard +Martin Pitt +Mathieu Trudel-Lapierre +Michael Terry +Mike Gabriel +Mikkel Kamstrup Erlandsen +Neil Jagdish Patel +Robert Ancell +Robert Carr +Robert Collins +Robert Tari +Seb128 +Sebastien Bacher +Sergey Fedorov +Shahriar Heidrich +Steve Langasek +Ted Gould +Thomas Klausner +Till Maas +Timo Jyrinki +Triallax +Unknown +William Hua diff --git a/CMakeLists.txt b/CMakeLists.txt index 8af6ff5..4126e52 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,7 +83,7 @@ endif (HAVE_LIB_M) include(GNUInstallDirs) set(ABI_VERSION "7") set(API_VERSION "4") -set(PROJECT_VERSION "0.9.4") +set(PROJECT_VERSION "0.9.5") set(PROJECT_NAME "libayatana-indicator") # Make everything @@ -1,6 +1,75 @@ +2026-06-12 Mike Gabriel + + * Release 0.9.5 (HEAD -> main, tag: 0.9.5) + +2026-06-10 Mike Gabriel + + * Merge branch 'thestr4ng3r-gdesktopappinfo' (4587086) + +2025-05-09 Florian Märkl + + * Remove unnecessary gio/gdesktopappinfo.h include (f22e86c) + +2026-06-09 Mike Gabriel + + * Merge branch 'thestr4ng3r-pkgconfig' (7093307) + +2025-05-09 Florian Märkl + + * Fix linking against libs in non-standard paths (80c8c7c) + +2026-06-09 Mike Gabriel + + * Merge branch 'smheidrich-fix-broken-readme-link' (6be6bff) + +2025-05-29 Shahriar Heidrich + + * Fix broken homepage link in README (3162487) + +2026-06-09 Mike Gabriel + + * Merge branch 'aleasto-failing-gtk-tests' (013054c) + +2025-10-06 Alessandro Astone + + * tests: Avoid more GDBusConnection leaks (95ca978) + +2026-06-09 Mike Gabriel + + * Merge branch 'platypii-fix/css-provider-memory-leak' (dac009d) + +2026-04-13 Kenny Daniel + + * src/indicator-ng.c: Fix GtkCssProvider memory leak in + indicator_ng_set_label (8880ce6) + +2024-07-03 Mike Gabriel + + * Merge branch 'triallax-bash-tests' (08c5540) + +2024-05-06 triallax + + * Use /bin/sh instead of /bin/bash for tests (804fe3c) + +2024-07-03 Mike Gabriel + + * Merge branch 'barracuda156-apple' (0be5f03) + +2024-06-17 Sergey Fedorov + + * Fix build on macOS (8b4fc71) + +2024-04-25 Mike Gabriel + + * Merge branch '0-wiz-0-main' (fded0d3) + +2024-04-22 Thomas Klausner + + * Add missing -L argument to pkg-config .pc files. (63593be) + 2023-10-13 Mike Gabriel - * release 0.9.4 (HEAD -> main, tag: 0.9.4) + * release 0.9.4 (611bb38) (tag: 0.9.4) 2023-09-06 Robert Tari @@ -1,3 +1,15 @@ +Overview of changes in libayatana-indicator 0.9.5 + + - Remove unnecessary gio/gdesktopappinfo.h include. + - Fix linking against libs in non-standard paths. + - Fix broken homepage link in README. + - tests: Avoid more GDBusConnection leaks. + - src/indicator-ng.c: Fix GtkCssProvider memory leak in + indicator_ng_set_label. + - Use /bin/sh instead of /bin/bash for tests. + - Fix build on macOS. + - Add missing -L argument to pkg-config .pc files. + Overview of changes in libayatana-indicator 0.9.4 - src/indicator-service.c: Fix Robert's lastname in license header. @@ -30,7 +30,7 @@ area and the [UBports](https://ubports.com) project is a core contributor to the Ayatana Indicators project. For further info, please visit: -https://ayatana-indicators.org +https://ayatanaindicators.github.io ## About this Software Component diff --git a/debian/changelog b/debian/changelog index ecfb6ff..a48b081 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +libayatana-indicator (0.9.5) unstable; urgency=medium + + * Upstream-provided Debian package for libayatana-indicator. See + upstream ChangeLog for recent changes. + + -- Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Fri, 12 Jun 2026 09:37:42 +0200 + libayatana-indicator (0.9.4-0) unstable; urgency=medium * Upstream-provided Debian package for libayatana-indicator. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 400f91a..b638165 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -142,6 +142,6 @@ target_include_directories("${ayatana_indicator_gtkver}" PUBLIC ${CMAKE_CURRENT_ if(NOT APPLE) target_link_options("${ayatana_indicator_gtkver}" PRIVATE "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/indicator.symbols") endif() -target_link_libraries("${ayatana_indicator_gtkver}" ${PROJECT_DEPS_LIBRARIES} ${EXTRA_LIBS}) +target_link_libraries("${ayatana_indicator_gtkver}" ${PROJECT_DEPS_LINK_LIBRARIES} ${EXTRA_LIBS}) add_dependencies("${ayatana_indicator_gtkver}" "src-generated") install(TARGETS "${ayatana_indicator_gtkver}" LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}") diff --git a/src/indicator-desktop-shortcuts.c b/src/indicator-desktop-shortcuts.c index be1d632..99a687a 100644 --- a/src/indicator-desktop-shortcuts.c +++ b/src/indicator-desktop-shortcuts.c @@ -25,7 +25,6 @@ License along with this library. If not, see #include "config.h" #endif -#include <gio/gdesktopappinfo.h> #include "indicator-desktop-shortcuts.h" #define ACTIONS_KEY "Actions" 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); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a461dab..b2a3ab4 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -13,7 +13,7 @@ function(add_test_library_by_name name) add_library("${TEST_LIBRARY_NAME}" SHARED ${TEST_LIBRARY_NAME}.c) target_include_directories("${TEST_LIBRARY_NAME}" PUBLIC ${PROJECT_DEPS_INCLUDE_DIRS}) target_include_directories("${TEST_LIBRARY_NAME}" PUBLIC "${CMAKE_SOURCE_DIR}/src") - target_link_libraries("${TEST_LIBRARY_NAME}" ${PROJECT_DEPS_LIBRARIES} -l${ayatana_indicator_gtkver}) + target_link_libraries("${TEST_LIBRARY_NAME}" ${PROJECT_DEPS_LINK_LIBRARIES} -l${ayatana_indicator_gtkver}) target_link_directories("${TEST_LIBRARY_NAME}" PUBLIC "${CMAKE_BINARY_DIR}/src") add_dependencies("${TEST_LIBRARY_NAME}" "${ayatana_indicator_gtkver}") endfunction() @@ -25,7 +25,7 @@ function(add_test_executable_by_name name) target_compile_definitions("${TEST_EXECUTABLE_NAME}" PUBLIC SRCDIR="${CMAKE_CURRENT_SOURCE_DIR}") target_include_directories("${TEST_EXECUTABLE_NAME}" PUBLIC ${PROJECT_DEPS_INCLUDE_DIRS}) target_include_directories("${TEST_EXECUTABLE_NAME}" PUBLIC "${CMAKE_SOURCE_DIR}/src") - target_link_libraries("${TEST_EXECUTABLE_NAME}" ${PROJECT_DEPS_LIBRARIES} -l${ayatana_indicator_gtkver}) + target_link_libraries("${TEST_EXECUTABLE_NAME}" ${PROJECT_DEPS_LINK_LIBRARIES} -l${ayatana_indicator_gtkver}) target_link_directories("${TEST_EXECUTABLE_NAME}" PUBLIC "${CMAKE_BINARY_DIR}/src") add_dependencies("${TEST_EXECUTABLE_NAME}" "${ayatana_indicator_gtkver}") endfunction() @@ -195,6 +195,26 @@ add_custom_command( ) add_test("test-desktop-shortcuts-tester" "test-desktop-shortcuts-tester") +# test-css-provider-leak +add_test_executable_by_name(test-css-provider-leak) + +# test-css-provider-leak-tester +add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/test-css-provider-leak-tester" + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/test-css-provider-leak" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + VERBATIM + COMMAND + echo "#!/bin/sh" > "${CMAKE_CURRENT_BINARY_DIR}/test-css-provider-leak-tester" + COMMAND + echo ". ${CMAKE_CURRENT_SOURCE_DIR}/run-xvfb.sh" >> "${CMAKE_CURRENT_BINARY_DIR}/test-css-provider-leak-tester" + COMMAND + echo "gtester -k --verbose -o=${CMAKE_CURRENT_BINARY_DIR}/loader-check-results.xml ${CMAKE_CURRENT_BINARY_DIR}/test-css-provider-leak" >> "${CMAKE_CURRENT_BINARY_DIR}/test-css-provider-leak-tester" + COMMAND + chmod +x "${CMAKE_CURRENT_BINARY_DIR}/test-css-provider-leak-tester" +) +add_test("test-css-provider-leak-tester" "test-css-provider-leak-tester") + if (FLAVOUR_GTK3 AND ENABLE_IDO) # test-indicator-ng add_test_executable_by_name(test-indicator-ng) @@ -257,7 +277,7 @@ add_test("loader-tester" "loader-tester") # indicator-test-service add_executable("indicator-test-service" indicator-test-service.c) target_include_directories("indicator-test-service" PUBLIC ${PROJECT_DEPS_INCLUDE_DIRS}) -target_link_libraries("indicator-test-service" ${PROJECT_DEPS_LIBRARIES}) +target_link_libraries("indicator-test-service" ${PROJECT_DEPS_LINK_LIBRARIES}) set (ALL_TESTERS "service-manager-connect-tester" @@ -267,6 +287,7 @@ set (ALL_TESTERS "service-version-tester" "service-version-multiwatch-tester" "test-desktop-shortcuts-tester" + "test-css-provider-leak-tester" "loader-tester" ) diff --git a/tests/test-css-provider-leak.c b/tests/test-css-provider-leak.c new file mode 100644 index 0000000..aeb7d49 --- /dev/null +++ b/tests/test-css-provider-leak.c @@ -0,0 +1,128 @@ +/* + * Test that demonstrates the GtkCssProvider memory leak in + * indicator_ng_set_label (before fix) and validates the fix. + * + * Before the fix, every call to indicator_ng_set_label() created a new + * GtkCssProvider and added it to the label's GtkStyleContext without + * removing the old one. Since the datetime indicator updates the label + * once per second, this leaked ~2 KB/sec (~170 MB/day). + * + * This test calls set_label in a loop and measures heap growth via + * /proc/self/statm to show the leak is real and the fix works. + */ + +#include <gtk/gtk.h> +#include <stdio.h> + +static long +get_rss_kb (void) +{ + long rss = 0; + FILE *f = fopen ("/proc/self/statm", "r"); + if (f) { + long size, resident; + if (fscanf (f, "%ld %ld", &size, &resident) == 2) + rss = resident * (sysconf (_SC_PAGESIZE) / 1024); + fclose (f); + } + return rss; +} + +/* + * Simulate what indicator_ng_set_label does using the UNFIXED code: + * creates and adds a new GtkCssProvider every call. + */ +static void +set_label_leaky (GtkLabel *label, guint nPadding) +{ + GtkCssProvider *pCssProvider = gtk_css_provider_new (); + GtkStyleContext *pStyleContext = gtk_widget_get_style_context (GTK_WIDGET (label)); + gtk_style_context_add_provider (pStyleContext, GTK_STYLE_PROVIDER (pCssProvider), + 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); + g_free (sCss); + g_object_unref (pCssProvider); +} + +/* + * Simulate what indicator_ng_set_label does AFTER the fix: + * reuse a single provider, only reload its CSS data. + */ +static void +set_label_fixed (GtkLabel *label, guint nPadding, GtkCssProvider **cached) +{ + if (*cached == NULL) { + *cached = gtk_css_provider_new (); + GtkStyleContext *pStyleContext = gtk_widget_get_style_context (GTK_WIDGET (label)); + gtk_style_context_add_provider (pStyleContext, GTK_STYLE_PROVIDER (*cached), + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + } + gchar *sCss = g_strdup_printf ("label{padding-left: %ipx;}", nPadding); + gtk_css_provider_load_from_data (*cached, sCss, -1, NULL); + g_free (sCss); +} + +#define ITERATIONS 100000 + +static void +test_leaky_set_label (void) +{ + GtkWidget *label = gtk_label_new ("12:00:00"); + g_object_ref_sink (label); + + long rss_before = get_rss_kb (); + + for (int i = 0; i < ITERATIONS; i++) { + set_label_leaky (GTK_LABEL (label), 6); + } + + long rss_after = get_rss_kb (); + long growth_kb = rss_after - rss_before; + + g_test_message ("leaky: RSS before=%ld KB, after=%ld KB, growth=%ld KB over %d iterations", + rss_before, rss_after, growth_kb, ITERATIONS); + + /* 100k leaked providers should use at least 50 MB. + If we see significant growth, the leak is confirmed. */ + g_assert_cmpint (growth_kb, >, 50000); + + g_object_unref (label); +} + +static void +test_fixed_set_label (void) +{ + GtkWidget *label = gtk_label_new ("12:00:00"); + g_object_ref_sink (label); + + long rss_before = get_rss_kb (); + + GtkCssProvider *cached = NULL; + for (int i = 0; i < ITERATIONS; i++) { + set_label_fixed (GTK_LABEL (label), 6, &cached); + } + + long rss_after = get_rss_kb (); + long growth_kb = rss_after - rss_before; + + g_test_message ("fixed: RSS before=%ld KB, after=%ld KB, growth=%ld KB over %d iterations", + rss_before, rss_after, growth_kb, ITERATIONS); + + /* With the fix, memory growth should be negligible (< 5 MB). */ + g_assert_cmpint (growth_kb, <, 5000); + + g_object_unref (cached); + g_object_unref (label); +} + +int +main (int argc, char **argv) +{ + gtk_test_init (&argc, &argv); + + g_test_add_func ("/indicator-ng/css-provider-leak/leaky", test_leaky_set_label); + g_test_add_func ("/indicator-ng/css-provider-leak/fixed", test_fixed_set_label); + + return g_test_run (); +} diff --git a/tests/test-indicator-ng.c b/tests/test-indicator-ng.c index 774b000..2b93236 100644 --- a/tests/test-indicator-ng.c +++ b/tests/test-indicator-ng.c @@ -174,11 +174,13 @@ test_menu (void) int main (int argc, char **argv) { - /* gvfs, dconf, and appmenu-gtk leak GDbusConnections, which confuses + /* gvfs, dconf, appmenu-gtk, atk-bridge and gdk-wayland leak GDbusConnections, which confuses * g_test_dbus_down. Make sure we're not using any of those. */ g_setenv ("GIO_USE_VFS", "local", TRUE); g_setenv ("GSETTINGS_BACKEND", "memory", TRUE); + g_setenv ("NO_AT_BRIDGE", "1", TRUE); + g_setenv ("GDK_BACKEND", "x11", TRUE); g_unsetenv ("UBUNTU_MENUPROXY"); g_test_init (&argc, &argv, NULL); diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 14ce777..18bf429 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -4,7 +4,7 @@ if (FLAVOUR_GTK3 AND ENABLE_IDO) add_executable("ayatana-indicator-loader3" indicator-loader.c) target_include_directories("ayatana-indicator-loader3" PUBLIC ${PROJECT_DEPS_INCLUDE_DIRS}) target_include_directories("ayatana-indicator-loader3" PUBLIC "${CMAKE_SOURCE_DIR}/src") - target_link_libraries("ayatana-indicator-loader3" ${PROJECT_DEPS_LIBRARIES} "-L${CMAKE_BINARY_DIR}/src" -layatana-indicator3) + target_link_libraries("ayatana-indicator-loader3" ${PROJECT_DEPS_LINK_LIBRARIES} "-L${CMAKE_BINARY_DIR}/src" -layatana-indicator3) add_dependencies("ayatana-indicator-loader3" "ayatana-indicator3") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ayatana-indicator-loader3" DESTINATION "${CMAKE_INSTALL_FULL_LIBEXECDIR}/${PROJECT_NAME}") |
