[gtk+/wip/gmenu] Fix the handling of settings changes



commit 14464044b20cc29b45884f8e221f46b9320247c3
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Dec 3 18:03:00 2011 -0500

    Fix the handling of settings changes
    
    Testing settings changes reveals that the handling of the items-changed
    callback data was problematic. So, move the data either up into the
    GtkApplicationWindow or down into the callback. Now bloatpad survives
    continuous changes of the shows-app-menu and shows-menubar settings.

 gtk/gtkapplicationwindow.c |  161 +++++++++++++++++++-------------------------
 1 files changed, 68 insertions(+), 93 deletions(-)
---
diff --git a/gtk/gtkapplicationwindow.c b/gtk/gtkapplicationwindow.c
index 4a290a3..6886e08 100644
--- a/gtk/gtkapplicationwindow.c
+++ b/gtk/gtkapplicationwindow.c
@@ -66,12 +66,11 @@ struct _GtkApplicationWindowPrivate
 
   gulong menubar_handler;
   gulong menu_handler;
-};
 
-static GtkWidget *
-gtk_application_window_create_menubar (GMenuModel        *model,
-                                       GActionObservable *actions);
+  guint update_idle;
+};
 
+static void gtk_application_window_create_menubar (GtkApplicationWindow *window);
 
 static void
 gtk_application_window_update_menubar (GtkApplicationWindow *window)
@@ -95,23 +94,7 @@ gtk_application_window_update_menubar (GtkApplicationWindow *window)
 
   if (!have_menubar && should_have_menubar)
     {
-      GActionMuxer *muxer;
-      GMenu *combined;
-
-      muxer = g_action_muxer_new ();
-      g_action_muxer_insert (muxer, "app", G_ACTION_GROUP (gtk_window_get_application (GTK_WINDOW (window))));
-      g_action_muxer_insert (muxer, "win", G_ACTION_GROUP (window));
-
-      combined = g_menu_new ();
-      g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->app_menu_section));
-      g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->menubar_section));
-
-      window->priv->menubar = gtk_application_window_create_menubar (G_MENU_MODEL (combined), G_ACTION_OBSERVABLE (muxer));
-      gtk_widget_set_parent (window->priv->menubar, GTK_WIDGET (window));
-      gtk_widget_show_all (window->priv->menubar);
-      g_object_unref (combined);
-      g_object_unref (muxer);
-
+      gtk_application_window_create_menubar (window);
       gtk_widget_queue_resize (GTK_WIDGET (window));
     }
 }
@@ -515,6 +498,7 @@ gtk_application_window_dispose (GObject *object)
                                    window->priv->menubar_handler);
       window->priv->menubar_handler = 0;
     }
+
   if (window->priv->menu_handler)
     {
       g_signal_handler_disconnect (gtk_widget_get_settings (GTK_WIDGET (object)),
@@ -522,6 +506,12 @@ gtk_application_window_dispose (GObject *object)
       window->priv->menu_handler = 0;
     }
 
+  if (window->priv->update_idle)
+    {
+      g_source_remove (window->priv->update_idle);
+      window->priv->update_idle = 0;
+    }
+
   G_OBJECT_CLASS (gtk_application_window_parent_class)->dispose (object);
 }
 
@@ -541,7 +531,6 @@ gtk_application_window_screen_changed (GtkWidget *widget,
         g_signal_handler_disconnect (settings, win->priv->menu_handler);
     }
 
-g_print ("screen changed\n");
   settings = gtk_widget_get_settings (widget);
   win->priv->menu_handler =
     g_signal_connect_object (settings, "notify::gtk-shell-shows-app-menu",
@@ -738,50 +727,23 @@ populate_menu_from_model (GtkMenuShell      *menu,
   append_items_from_model (menu, model, actions, &need_separator, NULL);
 }
 
-typedef struct {
-  GActionObservable *actions;
-  GMenuModel        *model;
-  GtkMenuShell      *menu;
-  guint              update_idle;
-  GHashTable        *connected;
-} ItemsChangedData;
+static gboolean repopulate_menu          (gpointer data);
+static void     connect_to_items_changed (GMenuModel *model,
+                                          GCallback   callback,
+                                          gpointer    data);
 
 static void
-free_items_changed_data (gpointer data)
-{
-  ItemsChangedData *d = data;
-
-  g_object_unref (d->actions);
-  g_object_unref (d->model);
-
-  if (d->update_idle != 0)
-    g_source_remove (d->update_idle);
-
-  g_hash_table_unref (d->connected);
-
-  g_free (d);
-}
-
-static gboolean
-repopulate_menu (gpointer data)
+items_changed (GMenuModel *model,
+               gint        position,
+               gint        removed,
+               gint        added,
+               gpointer    data)
 {
-  ItemsChangedData *d = data;
-  GList *children, *l;
-  GtkWidget *child;
-
-  /* remove current children */
-  children = gtk_container_get_children (GTK_CONTAINER (d->menu));
-  for (l = children; l; l = l->next)
-    {
-      child = l->data;
-      gtk_container_remove (GTK_CONTAINER (d->menu), child);
-    }
-  g_list_free (children);
-
-  populate_menu_from_model (d->menu, d->model, d->actions);
-  d->update_idle = 0;
+  GtkApplicationWindow *window = data;
 
-  return FALSE;
+  if (window->priv->update_idle == 0)
+    window->priv->update_idle = gdk_threads_add_idle (repopulate_menu, window);
+  connect_to_items_changed (model, G_CALLBACK (items_changed), window);
 }
 
 static void
@@ -789,15 +751,15 @@ connect_to_items_changed (GMenuModel *model,
                           GCallback   callback,
                           gpointer    data)
 {
-  ItemsChangedData *d = data;
   gint i;
   GMenuModel *m;
   GMenuLinkIter *iter;
 
-  if (!g_hash_table_lookup (d->connected, model))
+  if (!g_object_get_data (G_OBJECT (model), "gtk-application-window-changed-handler"))
     {
       g_signal_connect (model, "items-changed", callback, data);
-      g_hash_table_insert (d->connected, model, model);
+      g_object_set_data (G_OBJECT (model), "gtk-application-window-changed-handler",
+                         GINT_TO_POINTER (TRUE));
     }
 
   for (i = 0; i < g_menu_model_get_n_items (model); i++)
@@ -813,41 +775,54 @@ connect_to_items_changed (GMenuModel *model,
     }
 }
 
-static void
-items_changed (GMenuModel *model,
-               gint        position,
-               gint        removed,
-               gint        added,
-               gpointer    data)
+static gboolean
+repopulate_menu (gpointer data)
 {
-  ItemsChangedData *d = data;
+  GtkApplicationWindow *window = data;
+  GtkWidget *menubar;
+  GActionMuxer *muxer;
+  GMenu *combined;
+  GList *children, *l;
+
+  menubar = window->priv->menubar;
+  if (menubar)
+    {
+      /* remove current children */
+      children = gtk_container_get_children (GTK_CONTAINER (menubar));
+      for (l = children; l; l = l->next)
+        gtk_container_remove (GTK_CONTAINER (menubar), GTK_WIDGET (l->data));
+      g_list_free (children);
+
+      muxer = g_action_muxer_new ();
+      g_action_muxer_insert (muxer, "app", G_ACTION_GROUP (gtk_window_get_application (GTK_WINDOW (window))));
+      g_action_muxer_insert (muxer, "win", G_ACTION_GROUP (window));
 
-  if (d->update_idle == 0)
-    d->update_idle = gdk_threads_add_idle (repopulate_menu, data);
-  connect_to_items_changed (model, G_CALLBACK (items_changed), data);
+      combined = g_menu_new ();
+      g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->app_menu_section));
+      g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->menubar_section));
+
+      connect_to_items_changed (G_MENU_MODEL (combined), G_CALLBACK (items_changed), data);
+      populate_menu_from_model (GTK_MENU_SHELL (menubar), G_MENU_MODEL (combined), G_ACTION_OBSERVABLE (muxer));
+
+      g_object_unref (muxer);
+      g_object_unref (combined);
+    }
+
+  window->priv->update_idle = 0;
+
+  return FALSE;
 }
 
-static GtkWidget *
-gtk_application_window_create_menubar (GMenuModel        *model,
-                                       GActionObservable *actions)
+static void
+gtk_application_window_create_menubar (GtkApplicationWindow *window)
 {
-  ItemsChangedData *data;
   GtkWidget *menubar;
 
-  menubar = gtk_menu_bar_new ();
-
-  data = g_new (ItemsChangedData, 1);
-  data->model = g_object_ref (model);
-  data->actions = g_object_ref (actions);
-  data->menu = GTK_MENU_SHELL (menubar);
-  data->update_idle = 0;
-  data->connected = g_hash_table_new (NULL, NULL);
-
-  g_object_set_data_full (G_OBJECT (menubar), "gtk-application-menu-data",
-                          data, free_items_changed_data);
+  menubar = (GtkWidget *)gtk_menu_bar_new ();
+  gtk_widget_set_parent (menubar, GTK_WIDGET (window));
+  window->priv->menubar = menubar;
 
-  connect_to_items_changed (model, G_CALLBACK (items_changed), data);
-  repopulate_menu (data);
+  repopulate_menu (window);
 
-  return menubar;
+  gtk_widget_show_all (menubar);
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]