[Xfce4-commits] <xfce4-panel:master> Fix handling of custom menu items.

Nick Schermer noreply at xfce.org
Sun Mar 7 13:26:02 CET 2010


Updating branch refs/heads/master
         to 99127d1d3cd31ba138c0f94ccd35a92c8163f936 (commit)
       from 3548ff0b90d94b8c6b654660043ba30654f3c38a (commit)

commit 99127d1d3cd31ba138c0f94ccd35a92c8163f936
Author: Nick Schermer <nick at xfce.org>
Date:   Sun Mar 7 13:22:36 2010 +0100

    Fix handling of custom menu items.
    
    Custom menu items were destroyed before they were shown. Store
    the menu items in an internal list and take ownership until
    the plugin is closed.

 libxfce4panel/xfce-panel-plugin.c |   82 +++++++++++++++++++++++++++++++-----
 1 files changed, 70 insertions(+), 12 deletions(-)

diff --git a/libxfce4panel/xfce-panel-plugin.c b/libxfce4panel/xfce-panel-plugin.c
index 8d6cdf2..2c64550 100644
--- a/libxfce4panel/xfce-panel-plugin.c
+++ b/libxfce4panel/xfce-panel-plugin.c
@@ -100,6 +100,8 @@ static void          xfce_panel_plugin_set_locked             (XfcePanelPluginPr
                                                                gboolean                          locked);
 static void          xfce_panel_plugin_take_window_notify     (gpointer                          data,
                                                                GObject                          *where_the_object_was);
+static void          xfce_panel_plugin_menu_item_destroy      (GtkWidget                        *item,
+                                                               XfcePanelPlugin                  *plugin);
 
 
 
@@ -155,6 +157,7 @@ struct _XfcePanelPluginPrivate
   GtkOrientation       orientation;
   XfceScreenPosition   screen_position;
   guint                locked : 1;
+  GSList              *menu_items;
 
   /* flags for rembering states */
   PluginFlags          flags;
@@ -575,6 +578,7 @@ xfce_panel_plugin_init (XfcePanelPlugin *plugin)
   plugin->priv->panel_lock = 0;
   plugin->priv->flags = 0;
   plugin->priv->locked = TRUE;
+  plugin->priv->menu_items = NULL;
 
   /* hide the event box window to make the plugin transparent */
   gtk_event_box_set_visible_window (GTK_EVENT_BOX (plugin), FALSE);
@@ -731,10 +735,25 @@ static void
 xfce_panel_plugin_finalize (GObject *object)
 {
   XfcePanelPlugin *plugin = XFCE_PANEL_PLUGIN (object);
+  GSList          *li;
 
   /* destroy the menu */
-  if (plugin->priv->menu)
-    gtk_widget_destroy (GTK_WIDGET (plugin->priv->menu));
+  if (plugin->priv->menu != NULL)
+    {
+      gtk_widget_destroy (GTK_WIDGET (plugin->priv->menu));
+      panel_assert (plugin->priv->menu_items == NULL);
+    }
+  else
+    {
+      /* release custom menu items */
+      for (li = plugin->priv->menu_items; li != NULL; li = li->next)
+        {
+          g_signal_handlers_disconnect_by_func (G_OBJECT (li->data),
+              G_CALLBACK (xfce_panel_plugin_menu_item_destroy), plugin);
+          g_object_unref (G_OBJECT (li->data));
+        }
+      g_slist_free (plugin->priv->menu_items);
+    }
 
   g_free (plugin->priv->name);
   g_free (plugin->priv->display_name);
@@ -947,6 +966,26 @@ xfce_panel_plugin_menu_panel_help (XfcePanelPlugin *plugin)
 
 
 
+static void
+xfce_panel_plugin_menu_destroy (XfcePanelPlugin *plugin)
+{
+  GSList *li;
+
+  panel_return_if_fail (XFCE_IS_PANEL_PLUGIN (plugin));
+
+  if (plugin->priv->menu != NULL)
+    {
+      /* remove custom items before they get destroyed */
+      for (li = plugin->priv->menu_items; li != NULL; li = li->next)
+        gtk_container_remove (GTK_CONTAINER (plugin->priv->menu), GTK_WIDGET (li->data));
+
+      gtk_widget_destroy (GTK_WIDGET (plugin->priv->menu));
+      plugin->priv->menu = NULL;
+    }
+}
+
+
+
 static GtkMenu *
 xfce_panel_plugin_menu_get (XfcePanelPlugin *plugin)
 {
@@ -954,6 +993,7 @@ xfce_panel_plugin_menu_get (XfcePanelPlugin *plugin)
   GtkWidget *item;
   GtkWidget *image;
   gboolean   locked;
+  GSList    *li;
 
   panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN (plugin), NULL);
 
@@ -1006,6 +1046,10 @@ xfce_panel_plugin_menu_get (XfcePanelPlugin *plugin)
           gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
           gtk_widget_show (image);
 
+          /* add custom menu items */
+          for (li = plugin->priv->menu_items; li != NULL; li = li->next)
+            gtk_menu_shell_append (GTK_MENU_SHELL (menu), GTK_WIDGET (li->data));
+
           /* separator */
           item = gtk_separator_menu_item_new ();
           gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
@@ -1331,11 +1375,7 @@ xfce_panel_plugin_set_locked (XfcePanelPluginProvider *provider,
       plugin->priv->locked = locked;
 
       /* destroy the menu if it exists */
-      if (plugin->priv->menu != NULL)
-        {
-          gtk_widget_destroy (GTK_WIDGET (plugin->priv->menu));
-          plugin->priv->menu = NULL;
-        }
+      xfce_panel_plugin_menu_destroy (plugin);
     }
 }
 
@@ -1358,6 +1398,21 @@ xfce_panel_plugin_take_window_notify (gpointer  data,
 
 
 
+static void
+xfce_panel_plugin_menu_item_destroy (GtkWidget       *item,
+                                     XfcePanelPlugin *plugin)
+{
+  panel_return_if_fail (XFCE_IS_PANEL_PLUGIN (plugin));
+  panel_return_if_fail (GTK_IS_MENU_ITEM (item));
+  panel_return_if_fail (g_slist_find (plugin->priv->menu_items, item) != NULL);
+
+  /* remote the item from the list and release it */
+  plugin->priv->menu_items = g_slist_remove (plugin->priv->menu_items, item);
+  g_object_unref (G_OBJECT (item));
+}
+
+
+
 /**
  * xfce_panel_plugin_get_name:
  * @plugin : an #XfcePanelPlugin.
@@ -1674,14 +1729,17 @@ void
 xfce_panel_plugin_menu_insert_item (XfcePanelPlugin *plugin,
                                     GtkMenuItem     *item)
 {
-  GtkMenu *menu;
-
   g_return_if_fail (XFCE_IS_PANEL_PLUGIN (plugin));
   g_return_if_fail (GTK_IS_MENU_ITEM (item));
 
-  /* insert the new item below the move entry */
-  menu = xfce_panel_plugin_menu_get (plugin);
-  gtk_menu_shell_insert (GTK_MENU_SHELL (menu), GTK_WIDGET (item), 5);
+  /* take the item and add to internal list */
+  plugin->priv->menu_items = g_slist_prepend (plugin->priv->menu_items,
+                                              g_object_ref_sink (item));
+  g_signal_connect (G_OBJECT (item), "destroy",
+      G_CALLBACK (xfce_panel_plugin_menu_item_destroy), plugin);
+
+  /* destroy the menu */
+  xfce_panel_plugin_menu_destroy (plugin);
 }
 
 



More information about the Xfce4-commits mailing list