aboutsummaryrefslogtreecommitdiff
path: root/tests/test-gtk-remove-server.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test-gtk-remove-server.c')
-rw-r--r--tests/test-gtk-remove-server.c118
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;
+}