diff options
Diffstat (limited to 'tests/test-gtk-remove-server.c')
-rw-r--r-- | tests/test-gtk-remove-server.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/tests/test-gtk-remove-server.c b/tests/test-gtk-remove-server.c new file mode 100644 index 0000000..0655fc0 --- /dev/null +++ b/tests/test-gtk-remove-server.c @@ -0,0 +1,118 @@ +/* + Confirm that no warnings/criticals get generated by including + multiple add/removes in a match w/o waiting on the mainloop to iterate. + + Copyright 2013 Canonical Ltd. + + Original sample code by Drew Bliss <drewb@valvesoftware.com> + Modified for automatic testing by Charles Kerr <charles.kerr@canonical.com> + */ + +#include <stdlib.h> /* exit() */ +#include <gtk/gtk.h> +#include <libdbusmenu-glib/server.h> +#include <libdbusmenu-gtk/menu.h> +#include <libdbusmenu-gtk/parser.h> + +static GMainLoop * loop = NULL; +static GtkWidget * top_gtk = NULL; +static DbusmenuMenuitem * top_dbusmenu = NULL; +static DbusmenuServer * menuservice = NULL; + +static void +rebuild_menu (void) +{ + GList * l; + GList * children; + int i; + const int n = 10; + static int count = 0; + + if (top_gtk == NULL) + { + top_gtk = gtk_menu_new (); + gtk_widget_show (top_gtk); + top_dbusmenu = dbusmenu_gtk_parse_menu_structure (top_gtk); + menuservice = dbusmenu_server_new ("/org/ayatana/NotificationItem/test/Menu"); + dbusmenu_server_set_root (menuservice, top_dbusmenu); + } + + // remove all the previous children + children = gtk_container_get_children (GTK_CONTAINER(top_gtk)); + for (l=children; l!=NULL; l=l->next) + gtk_widget_destroy (GTK_WIDGET (l->data)); + + // add a handful of new children + for (i=0; i<n; ++i) + { + char buf[80]; + GtkWidget * child; + + g_snprintf (buf, sizeof(buf), "Test item %d", ++count); + child = gtk_menu_item_new_with_label (buf); + gtk_menu_shell_append (GTK_MENU_SHELL(top_gtk), child); + gtk_widget_show (child); + } +} + +/* + * Periodically rebuild the menu. + * + * After we've looped a couple of times with only one rebuild, + * attempt to reproduce the bug Drew reported by rebuilding multiple + * times before returning control to the main loop. + * + * If we survive doing this a handful of times without encountering + * a g_warning or g_critical, pass the test. + */ +static gint +on_timer (gpointer unused G_GNUC_UNUSED) +{ + static int iteration = 0; + + ++iteration; + + if (iteration > 5) + { + g_main_loop_quit (loop); + return G_SOURCE_REMOVE; + } + + if (iteration <= 2) + { + rebuild_menu (); + } + else + { + int i; + + for (i=0; i<iteration; ++i) + rebuild_menu (); + } + + return G_SOURCE_CONTINUE; +} + +static void +warning_counter (const gchar * log_domain, + GLogLevelFlags log_level G_GNUC_UNUSED, + const gchar * message, + gpointer user_data G_GNUC_UNUSED) +{ + g_message ("Failing the test due to warning: %s %s", log_domain, message); + exit (EXIT_FAILURE); +} + +int +main (int argc, char ** argv) +{ + g_log_set_handler ("LIBDBUSMENU-GLIB", G_LOG_LEVEL_WARNING|G_LOG_LEVEL_CRITICAL, warning_counter, NULL); + + + gtk_init (&argc, &argv); + loop = g_main_loop_new (NULL, FALSE); + g_timeout_add (200, on_timer, NULL); + g_main_loop_run (loop); + + return 0; +} |