← Back to team overview

ayatana-commits team mailing list archive

[Merge] lp:~bratsche/appmenu-gtk/dynamic-menu-fixes into lp:appmenu-gtk

 

Cody Russell has proposed merging lp:~bratsche/appmenu-gtk/dynamic-menu-fixes into lp:appmenu-gtk.

Requested reviews:
  Canonical Desktop Experience Team (canonical-dx-team)
Related bugs:
  #598311 Missing menus and menu items
  https://bugs.launchpad.net/bugs/598311

-- 
https://code.launchpad.net/~bratsche/appmenu-gtk/dynamic-menu-fixes/+merge/28474
Your team ayatana-commits is subscribed to branch lp:appmenu-gtk.
=== modified file 'src/bridge.c'
--- src/bridge.c	2010-06-24 19:56:12 +0000
+++ src/bridge.c	2010-06-24 23:51:29 +0000
@@ -58,6 +58,8 @@
 static void     toplevel_notify_cb         (GtkWidget         *widget,
                                             GParamSpec        *pspec,
                                             UbuntuMenuProxy   *proxy);
+static void     rebuild_window_items       (AppMenuBridge     *bridge,
+                                            GtkWidget         *toplevel);
 
 typedef struct _AppWindowContext AppWindowContext;
 
@@ -68,11 +70,12 @@
   DbusmenuMenuitem *root;
   gchar            *path;
   gboolean          registered;
+  AppMenuBridge    *bridge;
 };
 
 struct _AppMenuBridgePrivate
 {
-  GHashTable *windows;    /* XID,          AppWindowContext *> */
+  GList *windows;
 
   DBusGConnection  *session_bus;
   DBusGProxy       *dbusproxy;
@@ -108,7 +111,7 @@
 {
   bridge->priv = G_TYPE_INSTANCE_GET_PRIVATE (bridge, APP_MENU_TYPE_BRIDGE, AppMenuBridgePrivate);
 
-  bridge->priv->windows = g_hash_table_new (g_int64_hash, g_int64_equal);
+  bridge->priv->windows = NULL;
 
   bridge->priv->session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
 
@@ -159,43 +162,8 @@
 }
 
 static void
-destroy_window_context (gpointer key,
-                        gpointer value,
-                        gpointer user_data)
-{
-  AppWindowContext *context = (AppWindowContext *)value;
-
-  if (context->root)
-    {
-      g_object_unref (context->root);
-      context->root = NULL;
-    }
-
-  if (context->server)
-    {
-      g_object_unref (context->server);
-      context->server = NULL;
-    }
-
-  if (context->path)
-    {
-      g_free (context->path);
-    }
-}
-
-static void
 app_menu_bridge_finalize (GObject *object)
 {
-  AppMenuBridge *bridge = APP_MENU_BRIDGE (object);
-
-  if (bridge->priv->windows)
-    {
-      g_hash_table_foreach (bridge->priv->windows,
-                            destroy_window_context,
-                            NULL);
-      g_hash_table_destroy (bridge->priv->windows);
-    }
-
   G_OBJECT_CLASS (app_menu_bridge_parent_class)->finalize (object);
 }
 
@@ -225,50 +193,36 @@
 }
 
 static void
-register_application_window (gpointer key,
-                             gpointer value,
-                             gpointer user_data)
-{
-  AppWindowContext *context     = (AppWindowContext *)value;
-  GtkWidget        *widget      = context->window;
-  AppMenuBridge    *bridge     = APP_MENU_BRIDGE (user_data);
-
-  if (!context->registered && context->server != NULL && context->root != NULL && GTK_IS_WINDOW (widget) && bridge->priv->appmenuproxy != NULL)
-    {
-      dbusmenu_server_set_root (context->server, context->root);
-      org_ayatana_WindowMenu_Registrar_register_window (bridge->priv->appmenuproxy,
-                                                        GDK_WINDOW_XID (gtk_widget_get_window (widget)),
-                                                        context->path,
-                                                        NULL);
-
-      context->registered = TRUE;
-    }
-}
-
-static void
 register_application_windows (AppMenuBridge *bridge)
 {
-  g_hash_table_foreach (bridge->priv->windows,
-                        register_application_window,
-                        bridge);
-}
-
-static void
-unregister_application_window (gpointer key,
-                               gpointer value,
-                               gpointer user_data)
-{
-  AppWindowContext *context = (AppWindowContext *)value;
-
-  context->registered = FALSE;
+  GList *tmp = NULL;
+
+  for (tmp = bridge->priv->windows; tmp != NULL; tmp = tmp->next)
+    {
+      AppWindowContext *context = tmp->data;
+      GtkWidget *widget = context->window;
+
+      if (!context->registered && context->server != NULL && context->root != NULL && GTK_IS_WINDOW (widget) && bridge->priv->appmenuproxy != NULL)
+        {
+          org_ayatana_WindowMenu_Registrar_register_window (bridge->priv->appmenuproxy,
+                                                            GDK_WINDOW_XID (gtk_widget_get_window (widget)),
+                                                            context->path,
+                                                            NULL);
+        }
+    }
 }
 
 static void
 unregister_application_windows (AppMenuBridge *bridge)
 {
-  g_hash_table_foreach (bridge->priv->windows,
-                        unregister_application_window,
-                        bridge);
+  GList *tmp = NULL;
+
+  for (tmp = bridge->priv->windows; tmp != NULL; tmp = tmp->next)
+    {
+      AppWindowContext *context = tmp->data;
+
+      context->registered = FALSE;
+    }
 }
 
 static void
@@ -398,6 +352,32 @@
 }
 
 static void
+menuitem_notify_cb (GtkWidget  *widget,
+                    GParamSpec *pspec,
+                    gpointer    data)
+{
+  if (pspec->name == g_intern_static_string ("visible"))
+    {
+      AppWindowContext *context = (AppWindowContext *)data;
+      GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
+      GtkWidget *window = context->window;
+
+      /*
+      g_print ("VISIBLE: %p %s %s, window: %p %s %s, toplevel: %p %s %s\n",
+               widget, G_OBJECT_TYPE_NAME (widget), get_menu_label_text (widget),
+               window, G_OBJECT_TYPE_NAME (window), get_menu_label_text (window),
+               toplevel, G_OBJECT_TYPE_NAME (toplevel), get_menu_label_text (toplevel)
+               );
+      */
+
+      if (toplevel == window)
+        {
+          rebuild_window_items (context->bridge, window);
+        }
+    }
+}
+
+static void
 checkbox_toggled (GtkWidget *widget, DbusmenuMenuitem *mi)
 {
   dbusmenu_menuitem_property_set_int (mi,
@@ -511,6 +491,15 @@
               skip = TRUE;
             }
 
+          if (!gtk_widget_get_visible (widget))
+            {
+              g_signal_connect (G_OBJECT (widget),
+                                "notify",
+                                G_CALLBACK (menuitem_notify_cb),
+                                recurse->context);
+              skip = TRUE;
+            }
+
           if (!skip)
             {
               recurse->stack[recurse->count] = construct_dbusmenu_for_widget (widget);
@@ -551,7 +540,7 @@
                       GtkWidget     *toplevel)
 {
   XID xid;
-  AppWindowContext *context;
+  AppWindowContext *context = NULL;
   RecurseContext recurse;
 
   memset (&recurse, 0, sizeof (RecurseContext));
@@ -591,12 +580,28 @@
     }
 
   xid = GDK_WINDOW_XID (gtk_widget_get_window (toplevel));
-  context = g_hash_table_lookup (bridge->priv->windows, &xid);
-
-  if (!context)
+
+  GList *tmp;
+  gboolean found = FALSE;
+
+  for (tmp = bridge->priv->windows; tmp != NULL; tmp = tmp->next)
+    {
+      context = tmp->data;
+
+      XID xid2 = GDK_WINDOW_XID (gtk_widget_get_window (context->window));
+
+      if (xid == xid2)
+        {
+          found = TRUE;
+          break;
+        }
+    }
+
+  if (!found)
     {
       context = g_new0 (AppWindowContext, 1);
-      g_hash_table_insert (bridge->priv->windows, &xid, context);
+      context->bridge = bridge;
+      bridge->priv->windows = g_list_prepend (bridge->priv->windows, context);
     }
 
   context->window = toplevel;
@@ -686,9 +691,9 @@
   priv = bridge->priv;
 
   /*
-  g_print ("INSERT (parent %s %p, child %s %p\n",
+  g_print ("INSERT (parent %s %p, child %s %p %s\n",
            G_OBJECT_TYPE_NAME (parent), parent,
-           G_OBJECT_TYPE_NAME (child), child);
+           G_OBJECT_TYPE_NAME (child), child, get_menu_label_text (child));
   */
 
   toplevel = gtk_widget_get_toplevel (parent);


Follow ups