+ HildonAppMenuPrivate *priv = HILDON_APP_MENU_GET_PRIVATE (menu);
+
+ hildon_app_menu_repack_items (menu, g_list_index (priv->buttons, item));
+}
+
+static void
+filter_visibility_changed (GtkWidget *item,
+ GParamSpec *arg1,
+ HildonAppMenu *menu)
+{
+ hildon_app_menu_repack_filters (menu);
+}
+
+static void
+remove_item_from_list (GList **list,
+ gpointer item)
+{
+ *list = g_list_remove (*list, item);
+}
+
+static void
+hildon_app_menu_show (GtkWidget *widget)
+{
+ HildonAppMenuPrivate *priv = HILDON_APP_MENU_GET_PRIVATE (widget);
+ gboolean show_menu = FALSE;
+ GList *i;
+
+ /* Don't show menu if it doesn't contain visible items */
+ for (i = priv->buttons; i && !show_menu; i = i->next)
+ show_menu = GTK_WIDGET_VISIBLE (i->data);
+
+ for (i = priv->filters; i && !show_menu; i = i->next)
+ show_menu = GTK_WIDGET_VISIBLE (i->data);
+
+ if (show_menu) {
+ GTK_WIDGET_CLASS (hildon_app_menu_parent_class)->show (widget);
+ }
+}
+
+static void
+hildon_app_menu_show_all (GtkWidget *widget)
+{
+ HildonAppMenuPrivate *priv = HILDON_APP_MENU_GET_PRIVATE (widget);
+
+ /* Show children, but not self. */
+ g_list_foreach (priv->buttons, (GFunc) gtk_widget_show_all, NULL);
+ g_list_foreach (priv->filters, (GFunc) gtk_widget_show_all, NULL);
+}
+
+
+static void
+hildon_app_menu_hide_all (GtkWidget *widget)
+{
+ HildonAppMenuPrivate *priv = HILDON_APP_MENU_GET_PRIVATE (widget);
+
+ /* Hide children, but not self. */
+ g_list_foreach (priv->buttons, (GFunc) gtk_widget_hide_all, NULL);
+ g_list_foreach (priv->filters, (GFunc) gtk_widget_hide_all, NULL);
+}
+
+/*
+ * There's a race condition that can freeze the UI if a dialog appears
+ * between a HildonAppMenu and its parent window, see NB#100468
+ */
+static gboolean
+hildon_app_menu_find_intruder (gpointer data)
+{
+ GtkWidget *widget = GTK_WIDGET (data);
+ HildonAppMenuPrivate *priv = HILDON_APP_MENU_GET_PRIVATE (widget);
+
+ /* If there's a window between the menu and its parent window, hide the menu */
+ if (priv->parent_window) {
+ gboolean intruder_found = FALSE;
+ GdkScreen *screen = gtk_widget_get_screen (widget);
+ GList *stack = gdk_screen_get_window_stack (screen);
+ GList *parent_pos = g_list_find (stack, GTK_WIDGET (priv->parent_window)->window);
+ GList *toplevels = gtk_window_list_toplevels ();
+ GList *i;
+
+ for (i = toplevels; i != NULL && !intruder_found; i = i->next) {
+ if (i->data != widget && i->data != priv->parent_window) {
+ if (g_list_find (parent_pos, GTK_WIDGET (i->data)->window)) {
+ intruder_found = TRUE;
+ }
+ }
+ }
+
+ g_list_foreach (stack, (GFunc) g_object_unref, NULL);
+ g_list_free (stack);
+ g_list_free (toplevels);
+
+ if (intruder_found)
+ gtk_widget_hide (widget);
+ }
+
+ return FALSE;