[Xfce4-commits] <garcon:master> Add support for XDG_MENU_PREFIX (bug #5980).

Jannis Pohlmann noreply at xfce.org
Sat Dec 4 13:22:02 CET 2010


Updating branch refs/heads/master
         to ab3d16ac5fb3870d51e1217183a46183427bb218 (commit)
       from b53fe3381f46b0bc824762808af0cfcb710c7c9b (commit)

commit ab3d16ac5fb3870d51e1217183a46183427bb218
Author: Jannis Pohlmann <jannis at xfce.org>
Date:   Sat Dec 4 12:47:13 2010 +0100

    Add support for XDG_MENU_PREFIX (bug #5980).
    
    With this change, we can finally drop the code that tries to guess
    the default application menu file, which makes garcon useful for
    any desktop environment, regardless of the default .menu file they
    decide on.

 NEWS                 |    7 ++
 garcon/garcon-menu.c |  153 ++++++++++++++++++++++++++------------------------
 2 files changed, 86 insertions(+), 74 deletions(-)

diff --git a/NEWS b/NEWS
index 1d6b664..9a90cc5 100644
--- a/NEWS
+++ b/NEWS
@@ -1,9 +1,16 @@
+0.1.x
+=====
+- Add support for XDG_MENU_PREFIX; use applications.menu as a fallback
+  (bug #5980).
+
+
 0.1.3
 =====
 - Merge consecutive file change events using an idle handler.
 - Fix empty charset in Polish translation file (bug #6783).
 - Translation updates (pt, ja, id).
 
+
 0.1.2
 =====
 - Fix license headers (bug #6226).
diff --git a/garcon/garcon-menu.c b/garcon/garcon-menu.c
index 8a4cd30..2cd1a13 100644
--- a/garcon/garcon-menu.c
+++ b/garcon/garcon-menu.c
@@ -63,17 +63,6 @@
 
 
 
-/* Potential root menu files */
-static const gchar GARCON_MENU_ROOT_SPECS[][30] =
-{
-  "menus/applications.menu",
-  "menus/xfce-applications.menu",
-  "menus/gnome-applications.menu",
-  "menus/kde-applications.menu",
-};
-
-
-
 #define GARCON_MENU_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GARCON_TYPE_MENU, GarconMenuPrivate))
 
 
@@ -401,7 +390,8 @@ garcon_menu_finalize (GObject *object)
   garcon_menu_clear (menu);
 
   /* Free file */
-  g_object_unref (menu->priv->file);
+  if (menu->priv->file != NULL)
+    g_object_unref (menu->priv->file);
 
   /* Free item pool */
   g_object_unref (menu->priv->pool);
@@ -667,9 +657,10 @@ garcon_menu_load (GarconMenu   *menu,
   GarconMenuParser *parser;
   GarconMenuMerger *merger;
   GHashTable       *desktop_id_table;
+  const gchar      *prefix;
   gboolean          success = TRUE;
   gchar            *filename;
-  guint             n;
+  gchar            *relative_filename;
 
   g_return_val_if_fail (GARCON_IS_MENU (menu), FALSE);
   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
@@ -687,29 +678,32 @@ garcon_menu_load (GarconMenu   *menu,
           menu->priv->file = NULL;
         }
 
-      /* Search for a usable applications menu file */
-      for (n = 0; 
-           menu->priv->file == NULL && n < G_N_ELEMENTS (GARCON_MENU_ROOT_SPECS);
-           ++n)
-        {
-          /* Search for the applications menu file */
-          filename = garcon_config_lookup (GARCON_MENU_ROOT_SPECS[n]);
-    
-          /* Use the file if it exists */
-          if (filename != NULL)
-            menu->priv->file = _garcon_file_new_for_unknown_input (filename, NULL);
-    
-          /* Free the filename string */
-          g_free (filename);
-        }
+      /* Build the ${XDG_MENU_PREFIX}applications.menu filename */
+      prefix = g_getenv ("XDG_MENU_PREFIX");
+      relative_filename = g_strconcat ("menus", G_DIR_SEPARATOR_S, 
+                                       prefix != NULL ? prefix : "", "applications.menu",
+                                       NULL);
+
+      /* Search for the menu file in user and system config dirs */
+      filename = garcon_config_lookup (relative_filename);
+
+      /* Use the file if it exists */
+      if (filename != NULL)
+        menu->priv->file = _garcon_file_new_for_unknown_input (filename, NULL);
 
       /* Abort with an error if no suitable applications menu file was found */
       if (menu->priv->file == NULL)
         {
           g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT,
-                       _("No suitable application menu file found"));
+                       _("File \"%s\" not found"), relative_filename);
+          g_free (relative_filename);
           return FALSE;
         }
+
+      /* Free the filename strings */
+      g_free (relative_filename);
+      g_free (filename);
+
     }
 
   parser = garcon_menu_parser_new (menu->priv->file);
@@ -1831,10 +1825,11 @@ static void
 garcon_menu_monitor_menu_files (GarconMenu *menu)
 {
   GFileMonitor *monitor;
+  const gchar  *prefix;
   GFile        *file;
+  gchar        *relative_filename;
   gchar       **paths;
-  guint         n;
-  gint          i;
+  gint          n;
 
   g_return_if_fail (GARCON_IS_MENU (menu));
 
@@ -1851,28 +1846,33 @@ garcon_menu_monitor_menu_files (GarconMenu *menu)
     }
   else
     {
+      /* Build ${XDG_MENU_PREFIX}applications.menu filename */
+      prefix = g_getenv ("XDG_MENU_PREFIX");
+      relative_filename = g_strconcat ("menus", G_DIR_SEPARATOR_S, 
+                                       prefix != NULL ? prefix : "", "applications.menu",
+                                       NULL);
+
       /* Monitor all application menu candidates */
-      for (n = 0; n < G_N_ELEMENTS (GARCON_MENU_ROOT_SPECS); ++n)
-        {
-          paths = garcon_config_build_paths (GARCON_MENU_ROOT_SPECS[n]);
+      paths = garcon_config_build_paths (relative_filename);
 
-          for (i = g_strv_length (paths)-1; paths != NULL && i >= 0; --i)
+      for (n = g_strv_length (paths)-1; paths != NULL && n >= 0; --n)
+        {
+          file = g_file_new_for_path (paths[n]);
+          
+          monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, NULL);
+          if (monitor != NULL)
             {
-              file = g_file_new_for_path (paths[i]);
-              
-              monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, NULL);
-              if (monitor != NULL)
-                {
-                  menu->priv->monitors = g_list_prepend (menu->priv->monitors, monitor);
-                  g_signal_connect_swapped (monitor, "changed",
-                                            G_CALLBACK (garcon_menu_file_changed), menu);
-                }
-
-              g_object_unref (file);
+              menu->priv->monitors = g_list_prepend (menu->priv->monitors, monitor);
+              g_signal_connect_swapped (monitor, "changed",
+                                        G_CALLBACK (garcon_menu_file_changed), menu);
             }
 
-          g_strfreev (paths);
+          g_object_unref (file);
         }
+
+      /* clean up strings */
+      g_strfreev (paths);
+      g_free (relative_filename);
     }
 }
 
@@ -2037,12 +2037,13 @@ garcon_menu_file_changed (GarconMenu       *menu,
                           GFileMonitorEvent event_type,
                           GFileMonitor     *monitor)
 {
-  gboolean higher_priority = FALSE;
-  gboolean lower_priority = FALSE;
-  GFile   *menu_file;
-  gchar  **paths;
-  guint    n;
-  guint    i;
+  const gchar *prefix;
+  gboolean     higher_priority = FALSE;
+  gboolean     lower_priority = FALSE;
+  GFile       *menu_file;
+  gchar      **paths;
+  gchar       *relative_filename;
+  guint        n;
 
   g_return_if_fail (GARCON_IS_MENU (menu));
   g_return_if_fail (menu->priv->parent == NULL);
@@ -2054,35 +2055,39 @@ garcon_menu_file_changed (GarconMenu       *menu,
       return;
     }
 
+  /* Build the ${XDG_MENU_PREFIX}applications.menu filename */
+  prefix = g_getenv ("XDG_MENU_PREFIX");
+  relative_filename = g_strconcat ("menus", G_DIR_SEPARATOR_S,
+                                   prefix != NULL ? prefix : "", "applications.menu",
+                                   NULL);
+
+  /* Get XDG config paths for the root spec (e.g. menus/xfce-applications.menu) */
+  paths = garcon_config_build_paths (relative_filename);
+
   /* Check if the event file has higher priority than the file currently being used */
-  for (n = 0; !lower_priority && !higher_priority && n < G_N_ELEMENTS (GARCON_MENU_ROOT_SPECS); ++n)
+  for (n = 0; !lower_priority && !higher_priority && paths != NULL && paths[n] != NULL; ++n) 
     {
-      /* Get XDG config paths for the root spec (e.g. menus/xfce-applications.menu) */
-      paths = garcon_config_build_paths (GARCON_MENU_ROOT_SPECS[n]);
+      menu_file = g_file_new_for_path (paths[n]);
 
-      for (i = 0; !higher_priority && paths != NULL && paths[i] != NULL; ++i) 
+      if (g_file_equal (menu_file, menu->priv->file))
         {
-          menu_file = g_file_new_for_path (paths[i]);
-
-          if (g_file_equal (menu_file, menu->priv->file))
-            {
-              /* the menu's file comes before the changed file in the load
-               * priority order, so the changed file has a lower priority */
-              lower_priority = TRUE;
-            }
-          else if (g_file_equal (menu_file, file))
-            {
-              /* the changed file comes before the menu's file in the load
-               * priority order, so the changed file has a higher priority */
-              higher_priority = TRUE;
-            }
-
-          g_object_unref (menu_file);
+          /* the menu's file comes before the changed file in the load
+           * priority order, so the changed file has a lower priority */
+          lower_priority = TRUE;
+        }
+      else if (g_file_equal (menu_file, file))
+        {
+          /* the changed file comes before the menu's file in the load
+           * priority order, so the changed file has a higher priority */
+          higher_priority = TRUE;
         }
 
-      g_strfreev (paths);
+      g_object_unref (menu_file);
     }
 
+  /* clean up */
+  g_free (relative_filename);
+
   /* If the event file has higher priority, a menu reload is needed */
   if (!lower_priority && higher_priority)
     g_signal_emit (menu, menu_signals[RELOAD_REQUIRED], 0);



More information about the Xfce4-commits mailing list