[Xfce4-commits] [apps/xfce4-screensaver] 398/425: Port to garcon, drop xfcemenu-tree.{c, h}
noreply at xfce.org
noreply at xfce.org
Mon Oct 15 01:54:05 CEST 2018
This is an automated email from the git hooks/post-receive script.
b l u e s a b r e p u s h e d a c o m m i t t o b r a n c h m a s t e r
in repository apps/xfce4-screensaver.
commit 32d287dcb017be4cfcffbf98825db2218cffe074
Author: Sean Davis <smd.seandavis at gmail.com>
Date: Thu Oct 11 22:39:32 2018 -0400
Port to garcon, drop xfcemenu-tree.{c,h}
---
configure.ac | 5 +-
src/Makefile.am | 4 -
src/gs-theme-manager.c | 108 +-
src/xfcemenu-tree.c | 4142 ------------------------------------------------
src/xfcemenu-tree.h | 92 --
5 files changed, 44 insertions(+), 4307 deletions(-)
diff --git a/configure.ac b/configure.ac
index 62a3500..42302de 100644
--- a/configure.ac
+++ b/configure.ac
@@ -52,6 +52,7 @@ XRANDR_REQUIRED=1.3
LIBXFCONF_REQUIRED=4.12.1
LIBXFCE4UI_REQUIRED=4.12.1
LIBXFCE4UTIL_REQUIRED=4.12.1
+LIBGARCON_REQUIRED=0.5.0
AC_CHECK_HEADERS(unistd.h)
AC_CHECK_HEADERS(crypt.h sys/select.h)
@@ -86,6 +87,7 @@ PKG_CHECK_MODULES(XFCE_SCREENSAVER,
gio-2.0 >= $GLIB_REQUIRED_VERSION
libxklavier >= $LIBXKLAVIER_REQUIRED
libxfconf-0 >= $LIBXFCONF_REQUIRED
+ garcon-gtk3-1 >= $LIBGARCON_REQUIRED
$RANDR_PACKAGE)
AC_SUBST(XFCE_SCREENSAVER_CFLAGS)
AC_SUBST(XFCE_SCREENSAVER_LIBS)
@@ -102,7 +104,8 @@ PKG_CHECK_MODULES(XFCE_SCREENSAVER_CAPPLET,
gtk+-3.0 >= $GTK_REQUIRED_VERSION
libxklavier >= $LIBXKLAVIER_REQUIRED
libxfce4ui-2 >= $LIBXFCE4UI_REQUIRED
- libxfconf-0 >= $LIBXFCONF_REQUIRED)
+ libxfconf-0 >= $LIBXFCONF_REQUIRED
+ garcon-gtk3-1 >= $LIBGARCON_REQUIRED)
AC_SUBST(XFCE_SCREENSAVER_CAPPLET_CFLAGS)
AC_SUBST(XFCE_SCREENSAVER_CAPPLET_LIBS)
diff --git a/src/Makefile.am b/src/Makefile.am
index 939d6f8..1061a58 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -264,8 +264,6 @@ xfce4_screensaver_SOURCES = \
xfcekbd-desktop-config.h \
xfcekbd-keyboard-config.c \
xfcekbd-keyboard-config.h \
- xfcemenu-tree.c \
- xfcemenu-tree.h \
desktop-entries.c \
desktop-entries.h \
menu-layout.c \
@@ -323,8 +321,6 @@ xfce4_screensaver_preferences_SOURCES = \
xfcekbd-desktop-config.h \
xfcekbd-keyboard-config.c \
xfcekbd-keyboard-config.h \
- xfcemenu-tree.c \
- xfcemenu-tree.h \
canonicalize.c \
canonicalize.h \
entry-directories.c \
diff --git a/src/gs-theme-manager.c b/src/gs-theme-manager.c
index 050ea75..f8f63b5 100644
--- a/src/gs-theme-manager.c
+++ b/src/gs-theme-manager.c
@@ -31,7 +31,7 @@
#endif /* HAVE_UNISTD_H */
#include <glib-object.h>
-#include <xfcemenu-tree.h>
+#include <garcon/garcon.h>
#include "gs-theme-manager.h"
#include "gs-debug.h"
@@ -50,7 +50,7 @@ struct _GSThemeInfo
struct GSThemeManagerPrivate
{
- XfceMenuTree *menu_tree;
+ GarconMenu *menu;
};
G_DEFINE_TYPE_WITH_PRIVATE (GSThemeManager, gs_theme_manager, G_TYPE_OBJECT)
@@ -230,7 +230,7 @@ gs_theme_info_get_exec (GSThemeInfo *info)
}
static GSThemeInfo *
-gs_theme_info_new_from_xfcemenu_tree_entry (XfceMenuTreeEntry *entry)
+gs_theme_info_new_from_garcon_menu_item(GarconMenuItem *item)
{
GSThemeInfo *info;
const char *str;
@@ -239,11 +239,11 @@ gs_theme_info_new_from_xfcemenu_tree_entry (XfceMenuTreeEntry *entry)
info = g_new0 (GSThemeInfo, 1);
info->refcount = 1;
- info->name = g_strdup (xfcemenu_tree_entry_get_name (entry));
- info->exec = g_strdup (xfcemenu_tree_entry_get_exec (entry));
+ info->name = g_strdup (garcon_menu_item_get_name (item));
+ info->exec = g_strdup (garcon_menu_item_get_command (item));
/* remove the .desktop suffix */
- str = xfcemenu_tree_entry_get_desktop_file_id (entry);
+ str = garcon_menu_item_get_desktop_id (item);
pos = g_strrstr (str, ".desktop");
if (pos)
{
@@ -258,44 +258,33 @@ gs_theme_info_new_from_xfcemenu_tree_entry (XfceMenuTreeEntry *entry)
}
static GSThemeInfo *
-find_info_for_id (XfceMenuTree *tree,
+find_info_for_id (GarconMenu *menu,
const char *id)
{
GSThemeInfo *info;
- XfceMenuTreeDirectory *root;
- GSList *items;
- GSList *l;
+ GList *items;
+ GList *l;
- root = xfcemenu_tree_get_root_directory (tree);
- if (root == NULL)
- {
- return NULL;
- }
-
- items = xfcemenu_tree_directory_get_contents (root);
+ items = garcon_menu_get_items (menu);
info = NULL;
for (l = items; l; l = l->next)
{
- if (info == NULL
- && xfcemenu_tree_item_get_type (l->data) == XFCEMENU_TREE_ITEM_ENTRY)
+ if (info == NULL)
{
- XfceMenuTreeEntry *entry = l->data;
+ GarconMenuItem *item = l->data;
const char *file_id;
- file_id = xfcemenu_tree_entry_get_desktop_file_id (entry);
+ file_id = garcon_menu_item_get_desktop_id (item);
if (file_id && id && strcmp (file_id, id) == 0)
{
- info = gs_theme_info_new_from_xfcemenu_tree_entry (entry);
+ info = gs_theme_info_new_from_garcon_menu_item (item);
}
}
-
- xfcemenu_tree_item_unref (l->data);
}
- g_slist_free (items);
- xfcemenu_tree_item_unref (root);
+ g_list_free (items);
return info;
}
@@ -311,53 +300,38 @@ gs_theme_manager_lookup_theme_info (GSThemeManager *theme_manager,
g_return_val_if_fail (name != NULL, NULL);
id = g_strdup_printf ("%s.desktop", name);
- info = find_info_for_id (theme_manager->priv->menu_tree, id);
+ info = find_info_for_id (theme_manager->priv->menu, id);
g_free (id);
return info;
}
static void
-theme_prepend_entry (GSList **parent_list,
- XfceMenuTreeEntry *entry,
- const char *filename)
+theme_prepend_item (GSList **parent_list,
+ GarconMenuItem *item)
{
GSThemeInfo *info;
- info = gs_theme_info_new_from_xfcemenu_tree_entry (entry);
+ info = gs_theme_info_new_from_garcon_menu_item (item);
*parent_list = g_slist_prepend (*parent_list, info);
}
static void
-make_theme_list (GSList **parent_list,
- XfceMenuTreeDirectory *directory,
- const char *filename)
+make_theme_list (GSList **parent_list,
+ GarconMenu *menu)
{
- GSList *items;
- GSList *l;
+ GList *items;
+ GList *l;
- items = xfcemenu_tree_directory_get_contents (directory);
+ items = garcon_menu_get_items (menu);
for (l = items; l; l = l->next)
{
- switch (xfcemenu_tree_item_get_type (l->data))
- {
-
- case XFCEMENU_TREE_ITEM_ENTRY:
- theme_prepend_entry (parent_list, l->data, filename);
- break;
-
- case XFCEMENU_TREE_ITEM_ALIAS:
- case XFCEMENU_TREE_ITEM_DIRECTORY:
- default:
- break;
- }
-
- xfcemenu_tree_item_unref (l->data);
+ theme_prepend_item (parent_list, l->data);
}
- g_slist_free (items);
+ g_list_free (items);
*parent_list = g_slist_reverse (*parent_list);
}
@@ -366,17 +340,10 @@ GSList *
gs_theme_manager_get_info_list (GSThemeManager *theme_manager)
{
GSList *l = NULL;
- XfceMenuTreeDirectory *root;
g_return_val_if_fail (GS_IS_THEME_MANAGER (theme_manager), NULL);
- root = xfcemenu_tree_get_root_directory (theme_manager->priv->menu_tree);
-
- if (root != NULL)
- {
- make_theme_list (&l, root, "xfce4-screensavers.menu");
- xfcemenu_tree_item_unref (root);
- }
+ make_theme_list (&l, theme_manager->priv->menu);
return l;
}
@@ -389,18 +356,23 @@ gs_theme_manager_class_init (GSThemeManagerClass *klass)
object_class->finalize = gs_theme_manager_finalize;
}
-static XfceMenuTree *
-get_themes_tree (void)
+static GarconMenu *
+get_themes_menu (void)
{
- XfceMenuTree *themes_tree = NULL;
+ GarconMenu *menu = NULL;
+ gchar *menu_file = g_strconcat(SYSCONFDIR, "/xdg/menus/xfce4-screensavers.menu", NULL);
/* we only need to add the locations to the path once
and since this is only run once we'll do it here */
add_known_engine_locations_to_path ();
- themes_tree = xfcemenu_tree_lookup ("xfce4-screensavers.menu", XFCEMENU_TREE_FLAGS_NONE);
+ menu = garcon_menu_new_for_path (menu_file);
+ if (!garcon_menu_load (menu, NULL, NULL))
+ {
+ g_warning("Failed to load menu.");
+ }
- return themes_tree;
+ return menu;
}
static void
@@ -408,7 +380,7 @@ gs_theme_manager_init (GSThemeManager *theme_manager)
{
theme_manager->priv = gs_theme_manager_get_instance_private (theme_manager);
- theme_manager->priv->menu_tree = get_themes_tree ();
+ theme_manager->priv->menu = get_themes_menu ();
}
static void
@@ -423,9 +395,9 @@ gs_theme_manager_finalize (GObject *object)
g_return_if_fail (theme_manager->priv != NULL);
- if (theme_manager->priv->menu_tree != NULL)
+ if (theme_manager->priv->menu != NULL)
{
- xfcemenu_tree_unref (theme_manager->priv->menu_tree);
+ g_object_unref (G_OBJECT(theme_manager->priv->menu));
}
G_OBJECT_CLASS (gs_theme_manager_parent_class)->finalize (object);
diff --git a/src/xfcemenu-tree.c b/src/xfcemenu-tree.c
deleted file mode 100644
index fbfdcd2..0000000
--- a/src/xfcemenu-tree.c
+++ /dev/null
@@ -1,4142 +0,0 @@
-/*
- * Copyright (C) 2003, 2004 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include <config.h>
-
-#include "xfcemenu-tree.h"
-
-#include <gio/gio.h>
-#include <string.h>
-#include <errno.h>
-
-#include "menu-layout.h"
-#include "menu-monitor.h"
-#include "menu-util.h"
-#include "canonicalize.h"
-
-/*
- * FIXME: it might be useful to be able to construct a menu
- * tree from a traditional directory based menu hierarchy
- * too.
- */
-
-typedef enum
-{
- XFCEMENU_TREE_ABSOLUTE = 0,
- XFCEMENU_TREE_BASENAME = 1
-} XfceMenuTreeType;
-
-struct XfceMenuTree
-{
- XfceMenuTreeType type;
- guint refcount;
-
- char *basename;
- char *absolute_path;
- char *canonical_path;
-
- XfceMenuTreeFlags flags;
- XfceMenuTreeSortKey sort_key;
-
- GSList *menu_file_monitors;
-
- MenuLayoutNode *layout;
- XfceMenuTreeDirectory *root;
-
- GSList *monitors;
-
- gpointer user_data;
- GDestroyNotify dnotify;
-
- guint canonical : 1;
-};
-
-typedef struct
-{
- XfceMenuTreeChangedFunc callback;
- gpointer user_data;
-} XfceMenuTreeMonitor;
-
-struct XfceMenuTreeItem
-{
- XfceMenuTreeItemType type;
-
- XfceMenuTreeDirectory *parent;
-
- gpointer user_data;
- GDestroyNotify dnotify;
-
- guint refcount;
-};
-
-struct XfceMenuTreeDirectory
-{
- XfceMenuTreeItem item;
-
- DesktopEntry *directory_entry;
- char *name;
-
- GSList *entries;
- GSList *subdirs;
-
- MenuLayoutValues default_layout_values;
- GSList *default_layout_info;
- GSList *layout_info;
- GSList *contents;
-
- guint only_unallocated : 1;
- guint is_root : 1;
- guint is_nodisplay : 1;
- guint layout_pending_separator : 1;
- guint preprocessed : 1;
-
- /* 16 bits should be more than enough; G_MAXUINT16 means no inline header */
- guint will_inline_header : 16;
-};
-
-typedef struct
-{
- XfceMenuTreeDirectory directory;
-
- XfceMenuTree *tree;
-} XfceMenuTreeDirectoryRoot;
-
-struct XfceMenuTreeEntry
-{
- XfceMenuTreeItem item;
-
- DesktopEntry *desktop_entry;
- char *desktop_file_id;
-
- guint is_excluded : 1;
- guint is_nodisplay : 1;
-};
-
-struct XfceMenuTreeSeparator
-{
- XfceMenuTreeItem item;
-};
-
-struct XfceMenuTreeHeader
-{
- XfceMenuTreeItem item;
-
- XfceMenuTreeDirectory *directory;
-};
-
-struct XfceMenuTreeAlias
-{
- XfceMenuTreeItem item;
-
- XfceMenuTreeDirectory *directory;
- XfceMenuTreeItem *aliased_item;
-};
-
-static XfceMenuTree *xfcemenu_tree_new (XfceMenuTreeType type,
- const char *menu_file,
- gboolean canonical,
- XfceMenuTreeFlags flags);
-static void xfcemenu_tree_load_layout (XfceMenuTree *tree);
-static void xfcemenu_tree_force_reload (XfceMenuTree *tree);
-static void xfcemenu_tree_build_from_layout (XfceMenuTree *tree);
-static void xfcemenu_tree_force_rebuild (XfceMenuTree *tree);
-static void xfcemenu_tree_resolve_files (XfceMenuTree *tree,
- GHashTable *loaded_menu_files,
- MenuLayoutNode *layout);
-static void xfcemenu_tree_force_recanonicalize (XfceMenuTree *tree);
-static void xfcemenu_tree_invoke_monitors (XfceMenuTree *tree);
-
-static XfceMenuTree *xfcemenu_tree_ref (XfceMenuTree *tree);
-gpointer xfcemenu_tree_item_ref (gpointer itemp);
-
-static void xfcemenu_tree_item_unref_and_unset_parent(gpointer itemp);
-
-/*
- * The idea is that we cache the menu tree for either a given
- * menu basename or an absolute menu path.
- * If no files exist in $XDG_DATA_DIRS for the basename or the
- * absolute path doesn't exist we just return (and cache) the
- * empty menu tree.
- * We also add a file monitor for the basename in each dir in
- * $XDG_DATA_DIRS, or the absolute path to the menu file, and
- * re-compute if there are any changes.
- */
-
-static GHashTable *xfcemenu_tree_cache = NULL;
-
-static inline char *
-get_cache_key (XfceMenuTree *tree,
- XfceMenuTreeFlags flags)
-{
- const char *tree_name;
-
- switch (tree->type)
- {
- case XFCEMENU_TREE_ABSOLUTE:
- tree_name = tree->canonical ? tree->canonical_path : tree->absolute_path;
- break;
-
- case XFCEMENU_TREE_BASENAME:
- tree_name = tree->basename;
- break;
-
- default:
- g_assert_not_reached ();
- break;
- }
-
- return g_strdup_printf ("%s:0x%x", tree_name, flags);
-}
-
-static void
-xfcemenu_tree_add_to_cache (XfceMenuTree *tree,
- XfceMenuTreeFlags flags)
-{
- char *cache_key;
-
- if (xfcemenu_tree_cache == NULL)
- {
- xfcemenu_tree_cache =
- g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
- }
-
- cache_key = get_cache_key (tree, flags);
-
- menu_verbose ("Adding menu tree to cache: %s\n", cache_key);
-
- g_hash_table_replace (xfcemenu_tree_cache, cache_key, tree);
-}
-
-static void
-xfcemenu_tree_remove_from_cache (XfceMenuTree *tree,
- XfceMenuTreeFlags flags)
-{
- char *cache_key;
-
- cache_key = get_cache_key (tree, flags);
-
- menu_verbose ("Removing menu tree from cache: %s\n", cache_key);
-
- g_hash_table_remove (xfcemenu_tree_cache, cache_key);
-
- g_free (cache_key);
-
- if (g_hash_table_size (xfcemenu_tree_cache) == 0)
- {
- g_hash_table_destroy (xfcemenu_tree_cache);
- xfcemenu_tree_cache = NULL;
-
- _entry_directory_list_empty_desktop_cache ();
- }
-}
-
-static XfceMenuTree *
-xfcemenu_tree_lookup_from_cache (const char *tree_name,
- XfceMenuTreeFlags flags)
-{
- XfceMenuTree *retval;
- char *cache_key;
-
- if (xfcemenu_tree_cache == NULL)
- return NULL;
-
- cache_key = g_strdup_printf ("%s:0x%x", tree_name, flags);
-
- menu_verbose ("Looking up '%s' from menu cache\n", cache_key);
-
- retval = g_hash_table_lookup (xfcemenu_tree_cache, cache_key);
-
- g_free (cache_key);
-
- return retval ? xfcemenu_tree_ref (retval) : NULL;
-}
-
-typedef enum
-{
- MENU_FILE_MONITOR_INVALID = 0,
- MENU_FILE_MONITOR_FILE,
- MENU_FILE_MONITOR_NONEXISTENT_FILE,
- MENU_FILE_MONITOR_DIRECTORY
-} MenuFileMonitorType;
-
-typedef struct
-{
- MenuFileMonitorType type;
- MenuMonitor *monitor;
-} MenuFileMonitor;
-
-static void
-handle_nonexistent_menu_file_changed (MenuMonitor *monitor,
- MenuMonitorEvent event,
- const char *path,
- XfceMenuTree *tree)
-{
- if (event == MENU_MONITOR_EVENT_CHANGED ||
- event == MENU_MONITOR_EVENT_CREATED)
- {
- menu_verbose ("\"%s\" %s, marking tree for recanonicalization\n",
- path,
- event == MENU_MONITOR_EVENT_CREATED ? "created" : "changed");
-
- xfcemenu_tree_force_recanonicalize (tree);
- xfcemenu_tree_invoke_monitors (tree);
- }
-}
-
-static void
-handle_menu_file_changed (MenuMonitor *monitor,
- MenuMonitorEvent event,
- const char *path,
- XfceMenuTree *tree)
-{
- menu_verbose ("\"%s\" %s, marking tree for recanicalization\n",
- path,
- event == MENU_MONITOR_EVENT_CREATED ? "created" :
- event == MENU_MONITOR_EVENT_CHANGED ? "changed" : "deleted");
-
- xfcemenu_tree_force_recanonicalize (tree);
- xfcemenu_tree_invoke_monitors (tree);
-}
-
-static void
-handle_menu_file_directory_changed (MenuMonitor *monitor,
- MenuMonitorEvent event,
- const char *path,
- XfceMenuTree *tree)
-{
- if (!g_str_has_suffix (path, ".menu"))
- return;
-
- menu_verbose ("\"%s\" %s, marking tree for recanicalization\n",
- path,
- event == MENU_MONITOR_EVENT_CREATED ? "created" :
- event == MENU_MONITOR_EVENT_CHANGED ? "changed" : "deleted");
-
- xfcemenu_tree_force_recanonicalize (tree);
- xfcemenu_tree_invoke_monitors (tree);
-}
-
-static void
-xfcemenu_tree_add_menu_file_monitor (XfceMenuTree *tree,
- const char *path,
- MenuFileMonitorType type)
-{
- MenuFileMonitor *monitor;
-
- monitor = g_new0 (MenuFileMonitor, 1);
-
- monitor->type = type;
-
- switch (type)
- {
- case MENU_FILE_MONITOR_FILE:
- menu_verbose ("Adding a menu file monitor for \"%s\"\n", path);
-
- monitor->monitor = menu_get_file_monitor (path);
- menu_monitor_add_notify (monitor->monitor,
- (MenuMonitorNotifyFunc) handle_menu_file_changed,
- tree);
- break;
-
- case MENU_FILE_MONITOR_NONEXISTENT_FILE:
- menu_verbose ("Adding a menu file monitor for non-existent \"%s\"\n", path);
-
- monitor->monitor = menu_get_file_monitor (path);
- menu_monitor_add_notify (monitor->monitor,
- (MenuMonitorNotifyFunc) handle_nonexistent_menu_file_changed,
- tree);
- break;
-
- case MENU_FILE_MONITOR_DIRECTORY:
- menu_verbose ("Adding a menu directory monitor for \"%s\"\n", path);
-
- monitor->monitor = menu_get_directory_monitor (path);
- menu_monitor_add_notify (monitor->monitor,
- (MenuMonitorNotifyFunc) handle_menu_file_directory_changed,
- tree);
- break;
-
- default:
- g_assert_not_reached ();
- break;
- }
-
- tree->menu_file_monitors = g_slist_prepend (tree->menu_file_monitors, monitor);
-}
-
-static void
-remove_menu_file_monitor (MenuFileMonitor *monitor,
- XfceMenuTree *tree)
-{
- switch (monitor->type)
- {
- case MENU_FILE_MONITOR_FILE:
- menu_monitor_remove_notify (monitor->monitor,
- (MenuMonitorNotifyFunc) handle_menu_file_changed,
- tree);
- break;
-
- case MENU_FILE_MONITOR_NONEXISTENT_FILE:
- menu_monitor_remove_notify (monitor->monitor,
- (MenuMonitorNotifyFunc) handle_nonexistent_menu_file_changed,
- tree);
- break;
-
- case MENU_FILE_MONITOR_DIRECTORY:
- menu_monitor_remove_notify (monitor->monitor,
- (MenuMonitorNotifyFunc) handle_menu_file_directory_changed,
- tree);
- break;
-
- default:
- g_assert_not_reached ();
- break;
- }
-
- menu_monitor_unref (monitor->monitor);
- monitor->monitor = NULL;
-
- monitor->type = MENU_FILE_MONITOR_INVALID;
-
- g_free (monitor);
-}
-
-static void
-xfcemenu_tree_remove_menu_file_monitors (XfceMenuTree *tree)
-{
- menu_verbose ("Removing all menu file monitors\n");
-
- g_slist_foreach (tree->menu_file_monitors,
- (GFunc) remove_menu_file_monitor,
- tree);
- g_slist_free (tree->menu_file_monitors);
- tree->menu_file_monitors = NULL;
-}
-
-static XfceMenuTree *
-xfcemenu_tree_lookup_absolute (const char *absolute,
- XfceMenuTreeFlags flags)
-{
- XfceMenuTree *tree;
- gboolean canonical;
- const char *canonical_path;
- char *freeme;
-
- menu_verbose ("Looking up absolute path in tree cache: \"%s\"\n", absolute);
-
- if ((tree = xfcemenu_tree_lookup_from_cache (absolute, flags)) != NULL)
- return tree;
-
- canonical = TRUE;
- canonical_path = freeme = menu_canonicalize_file_name (absolute, FALSE);
- if (canonical_path == NULL)
- {
- menu_verbose ("Failed to canonicalize absolute menu path \"%s\": %s\n",
- absolute, g_strerror (errno));
- canonical = FALSE;
- canonical_path = absolute;
- }
-
- if ((tree = xfcemenu_tree_lookup_from_cache (canonical_path, flags)) != NULL)
- return tree;
-
- tree = xfcemenu_tree_new (XFCEMENU_TREE_ABSOLUTE, canonical_path, canonical, flags);
-
- g_free (freeme);
-
- return tree;
-}
-
-static XfceMenuTree *
-xfcemenu_tree_lookup_basename (const char *basename,
- XfceMenuTreeFlags flags)
-{
- XfceMenuTree *tree;
-
- menu_verbose ("Looking up menu file in tree cache: \"%s\"\n", basename);
-
- if ((tree = xfcemenu_tree_lookup_from_cache (basename, flags)) != NULL)
- return tree;
-
- return xfcemenu_tree_new (XFCEMENU_TREE_BASENAME, basename, FALSE, flags);
-}
-
-static gboolean
-canonicalize_basename_with_config_dir (XfceMenuTree *tree,
- const char *basename,
- const char *config_dir)
-{
- char *path;
-
- path = g_build_filename (config_dir, "menus", basename, NULL);
-
- tree->canonical_path = menu_canonicalize_file_name (path, FALSE);
- if (tree->canonical_path)
- {
- tree->canonical = TRUE;
- xfcemenu_tree_add_menu_file_monitor (tree,
- tree->canonical_path,
- MENU_FILE_MONITOR_FILE);
- }
- else
- {
- xfcemenu_tree_add_menu_file_monitor (tree,
- path,
- MENU_FILE_MONITOR_NONEXISTENT_FILE);
- }
-
- g_free (path);
-
- return tree->canonical;
-}
-
-static void
-canonicalize_basename (XfceMenuTree *tree,
- const char *basename)
-{
- if (!canonicalize_basename_with_config_dir (tree,
- basename,
- g_get_user_config_dir ()))
- {
- const char * const *system_config_dirs;
- int i;
-
- system_config_dirs = g_get_system_config_dirs ();
-
- i = 0;
- while (system_config_dirs[i] != NULL)
- {
- if (canonicalize_basename_with_config_dir (tree,
- basename,
- system_config_dirs[i]))
- break;
-
- ++i;
- }
- }
-}
-
-static gboolean xfcemenu_tree_canonicalize_path(XfceMenuTree* tree)
-{
- if (tree->canonical)
- return TRUE;
-
- g_assert(tree->canonical_path == NULL);
-
- if (tree->type == XFCEMENU_TREE_BASENAME)
- {
- xfcemenu_tree_remove_menu_file_monitors (tree);
-
- if (strcmp(tree->basename, "xfce-applications.menu") == 0 && g_getenv("XDG_MENU_PREFIX"))
- {
- char* prefixed_basename;
- prefixed_basename = g_strdup_printf("%s%s", g_getenv("XDG_MENU_PREFIX"), tree->basename);
- canonicalize_basename(tree, prefixed_basename);
- g_free(prefixed_basename);
- }
-
- if (!tree->canonical)
- canonicalize_basename(tree, tree->basename);
-
- if (tree->canonical)
- menu_verbose("Successfully looked up menu_file for \"%s\": %s\n", tree->basename, tree->canonical_path);
- else
- menu_verbose("Failed to look up menu_file for \"%s\"\n", tree->basename);
- }
- else /* if (tree->type == XFCEMENU_TREE_ABSOLUTE) */
- {
- tree->canonical_path = menu_canonicalize_file_name(tree->absolute_path, FALSE);
-
- if (tree->canonical_path != NULL)
- {
- menu_verbose("Successfully looked up menu_file for \"%s\": %s\n", tree->absolute_path, tree->canonical_path);
-
- /*
- * Replace the cache entry with the canonicalized version
- */
- xfcemenu_tree_remove_from_cache (tree, tree->flags);
-
- xfcemenu_tree_remove_menu_file_monitors(tree);
- xfcemenu_tree_add_menu_file_monitor(tree, tree->canonical_path, MENU_FILE_MONITOR_FILE);
-
- tree->canonical = TRUE;
-
- xfcemenu_tree_add_to_cache (tree, tree->flags);
- }
- else
- {
- menu_verbose("Failed to look up menu_file for \"%s\"\n", tree->absolute_path);
- }
- }
-
- return tree->canonical;
-}
-
-static void
-xfcemenu_tree_force_recanonicalize (XfceMenuTree *tree)
-{
- xfcemenu_tree_remove_menu_file_monitors (tree);
-
- if (tree->canonical)
- {
- xfcemenu_tree_force_reload (tree);
-
- g_free (tree->canonical_path);
- tree->canonical_path = NULL;
-
- tree->canonical = FALSE;
- }
-}
-
-XfceMenuTree* xfcemenu_tree_lookup(const char* menu_file, XfceMenuTreeFlags flags)
-{
- XfceMenuTree *retval;
-
- g_return_val_if_fail (menu_file != NULL, NULL);
-
- flags &= XFCEMENU_TREE_FLAGS_MASK;
-
- if (g_path_is_absolute (menu_file))
- retval = xfcemenu_tree_lookup_absolute (menu_file, flags);
- else
- retval = xfcemenu_tree_lookup_basename (menu_file, flags);
-
- g_assert (retval != NULL);
-
- return retval;
-}
-
-static XfceMenuTree *
-xfcemenu_tree_new (XfceMenuTreeType type,
- const char *menu_file,
- gboolean canonical,
- XfceMenuTreeFlags flags)
-{
- XfceMenuTree *tree;
-
- tree = g_new0 (XfceMenuTree, 1);
-
- tree->type = type;
- tree->flags = flags;
- tree->refcount = 1;
-
- tree->sort_key = XFCEMENU_TREE_SORT_NAME;
-
- if (tree->type == XFCEMENU_TREE_BASENAME)
- {
- g_assert (canonical == FALSE);
- tree->basename = g_strdup (menu_file);
- }
- else
- {
- tree->canonical = canonical != FALSE;
- tree->absolute_path = g_strdup (menu_file);
-
- if (tree->canonical)
- {
- tree->canonical_path = g_strdup (menu_file);
- xfcemenu_tree_add_menu_file_monitor (tree,
- tree->canonical_path,
- MENU_FILE_MONITOR_FILE);
- }
- else
- {
- xfcemenu_tree_add_menu_file_monitor (tree,
- tree->absolute_path,
- MENU_FILE_MONITOR_NONEXISTENT_FILE);
- }
- }
-
- xfcemenu_tree_add_to_cache (tree, tree->flags);
-
- return tree;
-}
-
-XfceMenuTree *
-xfcemenu_tree_ref (XfceMenuTree *tree)
-{
- g_return_val_if_fail (tree != NULL, NULL);
- g_return_val_if_fail (tree->refcount > 0, NULL);
-
- tree->refcount++;
-
- return tree;
-}
-
-void
-xfcemenu_tree_unref (XfceMenuTree *tree)
-{
- g_return_if_fail (tree != NULL);
- g_return_if_fail (tree->refcount >= 1);
-
- if (--tree->refcount > 0)
- return;
-
- if (tree->dnotify)
- tree->dnotify (tree->user_data);
- tree->user_data = NULL;
- tree->dnotify = NULL;
-
- xfcemenu_tree_remove_from_cache (tree, tree->flags);
-
- xfcemenu_tree_force_recanonicalize (tree);
-
- if (tree->basename != NULL)
- g_free (tree->basename);
- tree->basename = NULL;
-
- if (tree->absolute_path != NULL)
- g_free (tree->absolute_path);
- tree->absolute_path = NULL;
-
- g_slist_foreach (tree->monitors, (GFunc) g_free, NULL);
- g_slist_free (tree->monitors);
- tree->monitors = NULL;
-
- g_free (tree);
-}
-
-XfceMenuTreeDirectory *
-xfcemenu_tree_get_root_directory (XfceMenuTree *tree)
-{
- g_return_val_if_fail (tree != NULL, NULL);
-
- if (!tree->root)
- {
- xfcemenu_tree_build_from_layout (tree);
-
- if (!tree->root)
- return NULL;
- }
-
- return xfcemenu_tree_item_ref (tree->root);
-}
-
-static void
-xfcemenu_tree_invoke_monitors (XfceMenuTree *tree)
-{
- GSList *tmp;
-
- tmp = tree->monitors;
- while (tmp != NULL)
- {
- XfceMenuTreeMonitor *monitor = tmp->data;
- GSList *next = tmp->next;
-
- monitor->callback (tree, monitor->user_data);
-
- tmp = next;
- }
-}
-
-XfceMenuTreeItemType
-xfcemenu_tree_item_get_type (XfceMenuTreeItem *item)
-{
- g_return_val_if_fail (item != NULL, 0);
-
- return item->type;
-}
-
-static void
-xfcemenu_tree_item_set_parent (XfceMenuTreeItem *item,
- XfceMenuTreeDirectory *parent)
-{
- g_return_if_fail (item != NULL);
-
- item->parent = parent;
-}
-
-GSList *
-xfcemenu_tree_directory_get_contents (XfceMenuTreeDirectory *directory)
-{
- GSList *retval;
- GSList *tmp;
-
- g_return_val_if_fail (directory != NULL, NULL);
-
- retval = NULL;
-
- tmp = directory->contents;
- while (tmp != NULL)
- {
- retval = g_slist_prepend (retval,
- xfcemenu_tree_item_ref (tmp->data));
-
- tmp = tmp->next;
- }
-
- return g_slist_reverse (retval);
-}
-
-static const char *
-xfcemenu_tree_directory_get_name (XfceMenuTreeDirectory *directory)
-{
- g_return_val_if_fail (directory != NULL, NULL);
-
- if (!directory->directory_entry)
- return directory->name;
-
- return desktop_entry_get_name (directory->directory_entry);
-}
-
-static void
-xfcemenu_tree_directory_set_tree (XfceMenuTreeDirectory *directory,
- XfceMenuTree *tree)
-{
- XfceMenuTreeDirectoryRoot *root;
-
- g_assert (directory != NULL);
- g_assert (directory->is_root);
-
- root = (XfceMenuTreeDirectoryRoot *) directory;
-
- root->tree = tree;
-}
-
-const char *
-xfcemenu_tree_entry_get_name (XfceMenuTreeEntry *entry)
-{
- g_return_val_if_fail (entry != NULL, NULL);
-
- return desktop_entry_get_name (entry->desktop_entry);
-}
-
-static const char *
-xfcemenu_tree_entry_get_display_name (XfceMenuTreeEntry *entry)
-{
- const char *display_name;
-
- g_return_val_if_fail (entry != NULL, NULL);
-
- display_name = desktop_entry_get_full_name (entry->desktop_entry);
- if (!display_name || display_name[0] == '\0')
- display_name = desktop_entry_get_name (entry->desktop_entry);
-
- return display_name;
-}
-
-const char* xfcemenu_tree_entry_get_exec(XfceMenuTreeEntry* entry)
-{
- g_return_val_if_fail(entry != NULL, NULL);
-
- return desktop_entry_get_exec(entry->desktop_entry);
-}
-
-const char* xfcemenu_tree_entry_get_desktop_file_id(XfceMenuTreeEntry* entry)
-{
- g_return_val_if_fail(entry != NULL, NULL);
-
- return entry->desktop_file_id;
-}
-
-static XfceMenuTreeItem *
-xfcemenu_tree_alias_get_item (XfceMenuTreeAlias *alias)
-{
- g_return_val_if_fail (alias != NULL, NULL);
-
- return xfcemenu_tree_item_ref (alias->aliased_item);
-}
-
-static XfceMenuTreeDirectory *
-xfcemenu_tree_directory_new (XfceMenuTreeDirectory *parent,
- const char *name,
- gboolean is_root)
-{
- XfceMenuTreeDirectory *retval;
-
- if (!is_root)
- {
- retval = g_new0 (XfceMenuTreeDirectory, 1);
- }
- else
- {
- XfceMenuTreeDirectoryRoot *root;
-
- root = g_new0 (XfceMenuTreeDirectoryRoot, 1);
-
- retval = XFCEMENU_TREE_DIRECTORY (root);
-
- retval->is_root = TRUE;
- }
-
-
- retval->item.type = XFCEMENU_TREE_ITEM_DIRECTORY;
- retval->item.parent = parent;
- retval->item.refcount = 1;
-
- retval->name = g_strdup (name);
- retval->directory_entry = NULL;
- retval->entries = NULL;
- retval->subdirs = NULL;
- retval->default_layout_info = NULL;
- retval->layout_info = NULL;
- retval->contents = NULL;
- retval->only_unallocated = FALSE;
- retval->is_nodisplay = FALSE;
- retval->layout_pending_separator = FALSE;
- retval->preprocessed = FALSE;
- retval->will_inline_header = G_MAXUINT16;
-
- retval->default_layout_values.mask = MENU_LAYOUT_VALUES_NONE;
- retval->default_layout_values.show_empty = FALSE;
- retval->default_layout_values.inline_menus = FALSE;
- retval->default_layout_values.inline_limit = 4;
- retval->default_layout_values.inline_header = FALSE;
- retval->default_layout_values.inline_alias = FALSE;
-
- return retval;
-}
-
-static void
-xfcemenu_tree_directory_finalize (XfceMenuTreeDirectory *directory)
-{
- g_assert (directory->item.refcount == 0);
-
- g_slist_foreach (directory->contents,
- (GFunc) xfcemenu_tree_item_unref_and_unset_parent,
- NULL);
- g_slist_free (directory->contents);
- directory->contents = NULL;
-
- g_slist_foreach (directory->default_layout_info,
- (GFunc) menu_layout_node_unref,
- NULL);
- g_slist_free (directory->default_layout_info);
- directory->default_layout_info = NULL;
-
- g_slist_foreach (directory->layout_info,
- (GFunc) menu_layout_node_unref,
- NULL);
- g_slist_free (directory->layout_info);
- directory->layout_info = NULL;
-
- g_slist_foreach (directory->subdirs,
- (GFunc) xfcemenu_tree_item_unref_and_unset_parent,
- NULL);
- g_slist_free (directory->subdirs);
- directory->subdirs = NULL;
-
- g_slist_foreach (directory->entries,
- (GFunc) xfcemenu_tree_item_unref_and_unset_parent,
- NULL);
- g_slist_free (directory->entries);
- directory->entries = NULL;
-
- if (directory->directory_entry)
- desktop_entry_unref (directory->directory_entry);
- directory->directory_entry = NULL;
-
- g_free (directory->name);
- directory->name = NULL;
-}
-
-static XfceMenuTreeSeparator *
-xfcemenu_tree_separator_new (XfceMenuTreeDirectory *parent)
-{
- XfceMenuTreeSeparator *retval;
-
- retval = g_new0 (XfceMenuTreeSeparator, 1);
-
- retval->item.type = XFCEMENU_TREE_ITEM_SEPARATOR;
- retval->item.parent = parent;
- retval->item.refcount = 1;
-
- return retval;
-}
-
-static XfceMenuTreeHeader *
-xfcemenu_tree_header_new (XfceMenuTreeDirectory *parent,
- XfceMenuTreeDirectory *directory)
-{
- XfceMenuTreeHeader *retval;
-
- retval = g_new0 (XfceMenuTreeHeader, 1);
-
- retval->item.type = XFCEMENU_TREE_ITEM_HEADER;
- retval->item.parent = parent;
- retval->item.refcount = 1;
-
- retval->directory = xfcemenu_tree_item_ref (directory);
-
- xfcemenu_tree_item_set_parent (XFCEMENU_TREE_ITEM (retval->directory), NULL);
-
- return retval;
-}
-
-static void
-xfcemenu_tree_header_finalize (XfceMenuTreeHeader *header)
-{
- g_assert (header->item.refcount == 0);
-
- if (header->directory != NULL)
- xfcemenu_tree_item_unref (header->directory);
- header->directory = NULL;
-}
-
-static XfceMenuTreeAlias *
-xfcemenu_tree_alias_new (XfceMenuTreeDirectory *parent,
- XfceMenuTreeDirectory *directory,
- XfceMenuTreeItem *item)
-{
- XfceMenuTreeAlias *retval;
-
- retval = g_new0 (XfceMenuTreeAlias, 1);
-
- retval->item.type = XFCEMENU_TREE_ITEM_ALIAS;
- retval->item.parent = parent;
- retval->item.refcount = 1;
-
- retval->directory = xfcemenu_tree_item_ref (directory);
- if (item->type != XFCEMENU_TREE_ITEM_ALIAS)
- retval->aliased_item = xfcemenu_tree_item_ref (item);
- else
- retval->aliased_item = xfcemenu_tree_item_ref (xfcemenu_tree_alias_get_item (XFCEMENU_TREE_ALIAS (item)));
-
- xfcemenu_tree_item_set_parent (XFCEMENU_TREE_ITEM (retval->directory), NULL);
- xfcemenu_tree_item_set_parent (retval->aliased_item, NULL);
-
- return retval;
-}
-
-static void
-xfcemenu_tree_alias_finalize (XfceMenuTreeAlias *alias)
-{
- g_assert (alias->item.refcount == 0);
-
- if (alias->directory != NULL)
- xfcemenu_tree_item_unref (alias->directory);
- alias->directory = NULL;
-
- if (alias->aliased_item != NULL)
- xfcemenu_tree_item_unref (alias->aliased_item);
- alias->aliased_item = NULL;
-}
-
-static XfceMenuTreeEntry *
-xfcemenu_tree_entry_new (XfceMenuTreeDirectory *parent,
- DesktopEntry *desktop_entry,
- const char *desktop_file_id,
- gboolean is_excluded,
- gboolean is_nodisplay)
-{
- XfceMenuTreeEntry *retval;
-
- retval = g_new0 (XfceMenuTreeEntry, 1);
-
- retval->item.type = XFCEMENU_TREE_ITEM_ENTRY;
- retval->item.parent = parent;
- retval->item.refcount = 1;
-
- retval->desktop_entry = desktop_entry_ref (desktop_entry);
- retval->desktop_file_id = g_strdup (desktop_file_id);
- retval->is_excluded = is_excluded != FALSE;
- retval->is_nodisplay = is_nodisplay != FALSE;
-
- return retval;
-}
-
-static void
-xfcemenu_tree_entry_finalize (XfceMenuTreeEntry *entry)
-{
- g_assert (entry->item.refcount == 0);
-
- g_free (entry->desktop_file_id);
- entry->desktop_file_id = NULL;
-
- if (entry->desktop_entry)
- desktop_entry_unref (entry->desktop_entry);
- entry->desktop_entry = NULL;
-}
-
-static int
-xfcemenu_tree_entry_compare_by_id (XfceMenuTreeItem *a,
- XfceMenuTreeItem *b)
-{
- if (a->type == XFCEMENU_TREE_ITEM_ALIAS)
- a = XFCEMENU_TREE_ALIAS (a)->aliased_item;
-
- if (b->type == XFCEMENU_TREE_ITEM_ALIAS)
- b = XFCEMENU_TREE_ALIAS (b)->aliased_item;
-
- return strcmp (XFCEMENU_TREE_ENTRY (a)->desktop_file_id,
- XFCEMENU_TREE_ENTRY (b)->desktop_file_id);
-}
-
-gpointer xfcemenu_tree_item_ref(gpointer itemp)
-{
- XfceMenuTreeItem* item = (XfceMenuTreeItem*) itemp;
-
- g_return_val_if_fail(item != NULL, NULL);
- g_return_val_if_fail(item->refcount > 0, NULL);
-
- item->refcount++;
-
- return item;
-}
-
-void
-xfcemenu_tree_item_unref (gpointer itemp)
-{
- XfceMenuTreeItem *item;
-
- item = (XfceMenuTreeItem *) itemp;
-
- g_return_if_fail (item != NULL);
- g_return_if_fail (item->refcount > 0);
-
- if (--item->refcount == 0)
- {
- switch (item->type)
- {
- case XFCEMENU_TREE_ITEM_DIRECTORY:
- xfcemenu_tree_directory_finalize (XFCEMENU_TREE_DIRECTORY (item));
- break;
-
- case XFCEMENU_TREE_ITEM_ENTRY:
- xfcemenu_tree_entry_finalize (XFCEMENU_TREE_ENTRY (item));
- break;
-
- case XFCEMENU_TREE_ITEM_SEPARATOR:
- break;
-
- case XFCEMENU_TREE_ITEM_HEADER:
- xfcemenu_tree_header_finalize (XFCEMENU_TREE_HEADER (item));
- break;
-
- case XFCEMENU_TREE_ITEM_ALIAS:
- xfcemenu_tree_alias_finalize (XFCEMENU_TREE_ALIAS (item));
- break;
-
- default:
- g_assert_not_reached ();
- break;
- }
-
- if (item->dnotify)
- item->dnotify (item->user_data);
- item->user_data = NULL;
- item->dnotify = NULL;
-
- item->parent = NULL;
-
- g_free (item);
- }
-}
-
-static void
-xfcemenu_tree_item_unref_and_unset_parent (gpointer itemp)
-{
- XfceMenuTreeItem *item;
-
- item = (XfceMenuTreeItem *) itemp;
-
- g_return_if_fail (item != NULL);
-
- xfcemenu_tree_item_set_parent (item, NULL);
- xfcemenu_tree_item_unref (item);
-}
-
-static inline const char *
-xfcemenu_tree_item_compare_get_name_helper (XfceMenuTreeItem *item,
- XfceMenuTreeSortKey sort_key)
-{
- const char *name;
-
- name = NULL;
-
- switch (item->type)
- {
- case XFCEMENU_TREE_ITEM_DIRECTORY:
- if (XFCEMENU_TREE_DIRECTORY (item)->directory_entry)
- name = desktop_entry_get_name (XFCEMENU_TREE_DIRECTORY (item)->directory_entry);
- else
- name = XFCEMENU_TREE_DIRECTORY (item)->name;
- break;
-
- case XFCEMENU_TREE_ITEM_ENTRY:
- switch (sort_key)
- {
- case XFCEMENU_TREE_SORT_NAME:
- name = desktop_entry_get_name (XFCEMENU_TREE_ENTRY (item)->desktop_entry);
- break;
- case XFCEMENU_TREE_SORT_DISPLAY_NAME:
- name = xfcemenu_tree_entry_get_display_name (XFCEMENU_TREE_ENTRY (item));
- break;
- default:
- g_assert_not_reached ();
- break;
- }
- break;
-
- case XFCEMENU_TREE_ITEM_ALIAS:
- {
- XfceMenuTreeItem *dir;
- dir = XFCEMENU_TREE_ITEM (XFCEMENU_TREE_ALIAS (item)->directory);
- name = xfcemenu_tree_item_compare_get_name_helper (dir, sort_key);
- }
- break;
-
- case XFCEMENU_TREE_ITEM_SEPARATOR:
- case XFCEMENU_TREE_ITEM_HEADER:
- default:
- g_assert_not_reached ();
- break;
- }
-
- return name;
-}
-
-static int
-xfcemenu_tree_item_compare (XfceMenuTreeItem *a,
- XfceMenuTreeItem *b,
- gpointer sort_key_p)
-{
- const char *name_a;
- const char *name_b;
- XfceMenuTreeSortKey sort_key;
-
- sort_key = GPOINTER_TO_INT (sort_key_p);
-
- name_a = xfcemenu_tree_item_compare_get_name_helper (a, sort_key);
- name_b = xfcemenu_tree_item_compare_get_name_helper (b, sort_key);
-
- return g_utf8_collate (name_a, name_b);
-}
-
-static MenuLayoutNode *
-find_menu_child (MenuLayoutNode *layout)
-{
- MenuLayoutNode *child;
-
- child = menu_layout_node_get_children (layout);
- while (child && menu_layout_node_get_type (child) != MENU_LAYOUT_NODE_MENU)
- child = menu_layout_node_get_next (child);
-
- return child;
-}
-
-static void
-merge_resolved_children (XfceMenuTree *tree,
- GHashTable *loaded_menu_files,
- MenuLayoutNode *where,
- MenuLayoutNode *from)
-{
- MenuLayoutNode *insert_after;
- MenuLayoutNode *menu_child;
- MenuLayoutNode *from_child;
-
- xfcemenu_tree_resolve_files (tree, loaded_menu_files, from);
-
- insert_after = where;
- g_assert (menu_layout_node_get_type (insert_after) != MENU_LAYOUT_NODE_ROOT);
- g_assert (menu_layout_node_get_parent (insert_after) != NULL);
-
- /* skip root node */
- menu_child = find_menu_child (from);
- g_assert (menu_child != NULL);
- g_assert (menu_layout_node_get_type (menu_child) == MENU_LAYOUT_NODE_MENU);
-
- /* merge children of toplevel <Menu> */
- from_child = menu_layout_node_get_children (menu_child);
- while (from_child != NULL)
- {
- MenuLayoutNode *next;
-
- next = menu_layout_node_get_next (from_child);
-
- menu_verbose ("Merging ");
- menu_debug_print_layout (from_child, FALSE);
- menu_verbose (" after ");
- menu_debug_print_layout (insert_after, FALSE);
-
- switch (menu_layout_node_get_type (from_child))
- {
- case MENU_LAYOUT_NODE_NAME:
- menu_layout_node_unlink (from_child); /* delete this */
- break;
-
- default:
- menu_layout_node_steal (from_child);
- menu_layout_node_insert_after (insert_after, from_child);
- menu_layout_node_unref (from_child);
-
- insert_after = from_child;
- break;
- }
-
- from_child = next;
- }
-}
-
-static gboolean
-load_merge_file (XfceMenuTree *tree,
- GHashTable *loaded_menu_files,
- const char *filename,
- gboolean is_canonical,
- gboolean add_monitor,
- MenuLayoutNode *where)
-{
- MenuLayoutNode *to_merge;
- const char *canonical;
- char *freeme;
- gboolean retval;
-
- freeme = NULL;
- retval = FALSE;
-
- if (!is_canonical)
- {
- canonical = freeme = menu_canonicalize_file_name (filename, FALSE);
- if (canonical == NULL)
- {
- if (add_monitor)
- xfcemenu_tree_add_menu_file_monitor (tree,
- filename,
- MENU_FILE_MONITOR_NONEXISTENT_FILE);
-
- menu_verbose ("Failed to canonicalize merge file path \"%s\": %s\n",
- filename, g_strerror (errno));
- goto out;
- }
- }
- else
- {
- canonical = filename;
- }
-
- if (g_hash_table_lookup (loaded_menu_files, canonical) != NULL)
- {
- g_warning ("Not loading \"%s\": recursive loop detected in .menu files",
- canonical);
- retval = TRUE;
- goto out;
- }
-
- menu_verbose ("Merging file \"%s\"\n", canonical);
-
- to_merge = menu_layout_load (canonical, NULL, NULL);
- if (to_merge == NULL)
- {
- menu_verbose ("No menu for file \"%s\" found when merging\n",
- canonical);
- goto out;
- }
-
- retval = TRUE;
-
- g_hash_table_insert (loaded_menu_files, (char *) canonical, GUINT_TO_POINTER (TRUE));
-
- if (add_monitor)
- xfcemenu_tree_add_menu_file_monitor (tree,
- canonical,
- MENU_FILE_MONITOR_FILE);
-
- merge_resolved_children (tree, loaded_menu_files, where, to_merge);
-
- g_hash_table_remove (loaded_menu_files, canonical);
-
- menu_layout_node_unref (to_merge);
-
- out:
- if (freeme)
- g_free (freeme);
-
- return retval;
-}
-
-static gboolean
-load_merge_file_with_config_dir (XfceMenuTree *tree,
- GHashTable *loaded_menu_files,
- const char *menu_file,
- const char *config_dir,
- MenuLayoutNode *where)
-{
- char *merge_file;
- gboolean loaded;
-
- loaded = FALSE;
-
- merge_file = g_build_filename (config_dir, "menus", menu_file, NULL);
-
- if (load_merge_file (tree, loaded_menu_files, merge_file, FALSE, TRUE, where))
- loaded = TRUE;
-
- g_free (merge_file);
-
- return loaded;
-}
-
-static gboolean
-compare_basedir_to_config_dir (const char *canonical_basedir,
- const char *config_dir)
-{
- char *dirname;
- char *canonical_menus_dir;
- gboolean retval;
-
- menu_verbose ("Checking to see if basedir '%s' is in '%s'\n",
- canonical_basedir, config_dir);
-
- dirname = g_build_filename (config_dir, "menus", NULL);
-
- retval = FALSE;
-
- canonical_menus_dir = menu_canonicalize_file_name (dirname, FALSE);
- if (canonical_menus_dir != NULL &&
- strcmp (canonical_basedir, canonical_menus_dir) == 0)
- {
- retval = TRUE;
- }
-
- g_free (canonical_menus_dir);
- g_free (dirname);
-
- return retval;
-}
-
-static gboolean
-load_parent_merge_file_from_basename (XfceMenuTree *tree,
- GHashTable *loaded_menu_files,
- MenuLayoutNode *layout,
- const char *menu_file,
- const char *canonical_basedir)
-{
- gboolean found_basedir;
- const char * const *system_config_dirs;
- int i;
-
- /* We're not interested in menu files that are in directories which are not a
- * parent of the base directory of this menu file */
- found_basedir = compare_basedir_to_config_dir (canonical_basedir,
- g_get_user_config_dir ());
-
- system_config_dirs = g_get_system_config_dirs ();
-
- i = 0;
- while (system_config_dirs[i] != NULL)
- {
- if (!found_basedir)
- {
- found_basedir = compare_basedir_to_config_dir (canonical_basedir,
- system_config_dirs[i]);
- }
- else
- {
- menu_verbose ("Looking for parent menu file '%s' in '%s'\n",
- menu_file, system_config_dirs[i]);
-
- if (load_merge_file_with_config_dir (tree,
- loaded_menu_files,
- menu_file,
- system_config_dirs[i],
- layout))
- {
- break;
- }
- }
-
- ++i;
- }
-
- return system_config_dirs[i] != NULL;
-}
-
-static gboolean load_parent_merge_file(XfceMenuTree* tree, GHashTable* loaded_menu_files, MenuLayoutNode* layout)
-{
- MenuLayoutNode* root;
- const char* basedir;
- const char* menu_name;
- char* canonical_basedir;
- char* menu_file;
- gboolean found;
-
- root = menu_layout_node_get_root(layout);
-
- basedir = menu_layout_node_root_get_basedir(root);
- menu_name = menu_layout_node_root_get_name(root);
-
- canonical_basedir = menu_canonicalize_file_name(basedir, FALSE);
-
- if (canonical_basedir == NULL)
- {
- menu_verbose("Menu basedir '%s' no longer exists, not merging parent\n", basedir);
- return FALSE;
- }
-
- found = FALSE;
- menu_file = g_strconcat(menu_name, ".menu", NULL);
-
- if (strcmp(menu_file, "xfce-applications.menu") == 0 && g_getenv("XDG_MENU_PREFIX"))
- {
- char* prefixed_basename;
- prefixed_basename = g_strdup_printf("%s%s", g_getenv("XDG_MENU_PREFIX"), menu_file);
- found = load_parent_merge_file_from_basename(tree, loaded_menu_files, layout, prefixed_basename, canonical_basedir);
- g_free(prefixed_basename);
- }
-
- if (!found)
- {
- found = load_parent_merge_file_from_basename(tree, loaded_menu_files, layout, menu_file, canonical_basedir);
- }
-
- g_free(menu_file);
- g_free(canonical_basedir);
-
- return found;
-}
-
-static void
-load_merge_dir (XfceMenuTree *tree,
- GHashTable *loaded_menu_files,
- const char *dirname,
- MenuLayoutNode *where)
-{
- GDir *dir;
- const char *menu_file;
-
- menu_verbose ("Loading merge dir \"%s\"\n", dirname);
-
- xfcemenu_tree_add_menu_file_monitor (tree,
- dirname,
- MENU_FILE_MONITOR_DIRECTORY);
-
- if ((dir = g_dir_open (dirname, 0, NULL)) == NULL)
- return;
-
- while ((menu_file = g_dir_read_name (dir)))
- {
- if (g_str_has_suffix (menu_file, ".menu"))
- {
- char *full_path;
-
- full_path = g_build_filename (dirname, menu_file, NULL);
-
- load_merge_file (tree, loaded_menu_files, full_path, TRUE, FALSE, where);
-
- g_free (full_path);
- }
- }
-
- g_dir_close (dir);
-}
-
-static void
-load_merge_dir_with_config_dir (XfceMenuTree *tree,
- GHashTable *loaded_menu_files,
- const char *config_dir,
- const char *dirname,
- MenuLayoutNode *where)
-{
- char *path;
-
- path = g_build_filename (config_dir, "menus", dirname, NULL);
-
- load_merge_dir (tree, loaded_menu_files, path, where);
-
- g_free (path);
-}
-
-static void
-resolve_merge_file (XfceMenuTree *tree,
- GHashTable *loaded_menu_files,
- MenuLayoutNode *layout)
-{
- char *filename;
-
- if (menu_layout_node_merge_file_get_type (layout) == MENU_MERGE_FILE_TYPE_PARENT)
- {
- if (load_parent_merge_file (tree, loaded_menu_files, layout))
- return;
- }
-
- filename = menu_layout_node_get_content_as_path (layout);
- if (filename == NULL)
- {
- menu_verbose ("didn't get node content as a path, not merging file\n");
- }
- else
- {
- load_merge_file (tree, loaded_menu_files, filename, FALSE, TRUE, layout);
-
- g_free (filename);
- }
-
- /* remove the now-replaced node */
- menu_layout_node_unlink (layout);
-}
-
-static void
-resolve_merge_dir (XfceMenuTree *tree,
- GHashTable *loaded_menu_files,
- MenuLayoutNode *layout)
-{
- char *path;
-
- path = menu_layout_node_get_content_as_path (layout);
- if (path == NULL)
- {
- menu_verbose ("didn't get layout node content as a path, not merging dir\n");
- }
- else
- {
- load_merge_dir (tree, loaded_menu_files, path, layout);
-
- g_free (path);
- }
-
- /* remove the now-replaced node */
- menu_layout_node_unlink (layout);
-}
-
-static MenuLayoutNode *
-add_app_dir (XfceMenuTree *tree,
- MenuLayoutNode *before,
- const char *data_dir)
-{
- MenuLayoutNode *tmp;
- char *dirname;
-
- tmp = menu_layout_node_new (MENU_LAYOUT_NODE_APP_DIR);
- dirname = g_build_filename (data_dir, "applications", NULL);
- menu_layout_node_set_content (tmp, dirname);
- menu_layout_node_insert_before (before, tmp);
- menu_layout_node_unref (before);
-
- menu_verbose ("Adding <AppDir>%s</AppDir> in <DefaultAppDirs/>\n",
- dirname);
-
- g_free (dirname);
-
- return tmp;
-}
-
-static void
-resolve_default_app_dirs (XfceMenuTree *tree,
- MenuLayoutNode *layout)
-{
- MenuLayoutNode *before;
- const char * const *system_data_dirs;
- int i;
-
- system_data_dirs = g_get_system_data_dirs ();
-
- before = add_app_dir (tree,
- menu_layout_node_ref (layout),
- g_get_user_data_dir ());
-
- i = 0;
- while (system_data_dirs[i] != NULL)
- {
- before = add_app_dir (tree, before, system_data_dirs[i]);
-
- ++i;
- }
-
- menu_layout_node_unref (before);
-
- /* remove the now-replaced node */
- menu_layout_node_unlink (layout);
-}
-
-static MenuLayoutNode* add_directory_dir(XfceMenuTree* tree, MenuLayoutNode* before, const char* data_dir)
-{
- MenuLayoutNode* tmp;
- char* dirname;
-
- tmp = menu_layout_node_new(MENU_LAYOUT_NODE_DIRECTORY_DIR);
- dirname = g_build_filename(data_dir, "desktop-directories", NULL);
- menu_layout_node_set_content(tmp, dirname);
- menu_layout_node_insert_before(before, tmp);
- menu_layout_node_unref(before);
-
- menu_verbose("Adding <DirectoryDir>%s</DirectoryDir> in <DefaultDirectoryDirs/>\n", dirname);
-
- g_free(dirname);
-
- return tmp;
-}
-
-/* According to desktop spec, since our menu file is called 'xfce-applications', our
- * merged menu folders need to be called 'xfce-applications-merged'. We'll setup the folder
- * 'applications-merged' if it doesn't exist yet, and a symlink pointing to it in the
- * ~/.config/menus directory
- */
-static void
-setup_merge_dir_symlink(void)
-{
- gchar *user_config = (gchar *) g_get_user_config_dir();
- gchar *merge_path = g_build_filename (user_config, "menus", "applications-merged", NULL);
- GFile *merge_file = g_file_new_for_path (merge_path);
- gchar *sym_path;
- GFile *sym_file;
-
- g_file_make_directory_with_parents (merge_file, NULL, NULL);
-
- sym_path = g_build_filename (user_config, "menus", "xfce-applications-merged", NULL);
- sym_file = g_file_new_for_path (sym_path);
- if (!g_file_query_exists (sym_file, NULL)) {
- g_file_make_symbolic_link (sym_file, merge_path, NULL, NULL);
- }
-
- g_free (merge_path);
- g_free (sym_path);
- g_object_unref (merge_file);
- g_object_unref (sym_file);
-}
-
-static void
-resolve_default_directory_dirs (XfceMenuTree *tree,
- MenuLayoutNode *layout)
-{
- MenuLayoutNode *before;
- const char * const *system_data_dirs;
- int i;
-
- system_data_dirs = g_get_system_data_dirs ();
-
- before = add_directory_dir (tree,
- menu_layout_node_ref (layout),
- g_get_user_data_dir ());
-
- i = 0;
- while (system_data_dirs[i] != NULL)
- {
- /* Parche para tomar las carpetas /xfce/ */
- char* path = g_build_filename(system_data_dirs[i], "xfce", NULL);
- before = add_directory_dir(tree, before, path);
- g_free(path);
- /* /fin parche */
- before = add_directory_dir (tree, before, system_data_dirs[i]);
-
- ++i;
- }
-
- menu_layout_node_unref (before);
-
- /* remove the now-replaced node */
- menu_layout_node_unlink (layout);
-}
-
-static void
-resolve_default_merge_dirs (XfceMenuTree *tree,
- GHashTable *loaded_menu_files,
- MenuLayoutNode *layout)
-{
- MenuLayoutNode *root;
- const char *menu_name;
- char *merge_name;
- const char * const *system_config_dirs;
- int i;
-
- setup_merge_dir_symlink();
-
- root = menu_layout_node_get_root (layout);
- menu_name = menu_layout_node_root_get_name (root);
-
- merge_name = g_strconcat (menu_name, "-merged", NULL);
-
- system_config_dirs = g_get_system_config_dirs ();
-
- /* Merge in reverse order */
- i = 0;
- while (system_config_dirs[i] != NULL) i++;
- while (i > 0)
- {
- i--;
- load_merge_dir_with_config_dir (tree,
- loaded_menu_files,
- system_config_dirs[i],
- merge_name,
- layout);
- }
-
- load_merge_dir_with_config_dir (tree,
- loaded_menu_files,
- g_get_user_config_dir (),
- merge_name,
- layout);
-
- g_free (merge_name);
-
- /* remove the now-replaced node */
- menu_layout_node_unlink (layout);
-}
-
-static void
-add_filename_include (const char *desktop_file_id,
- DesktopEntry *entry,
- MenuLayoutNode *include)
-{
- if (!desktop_entry_has_categories (entry))
- {
- MenuLayoutNode *node;
-
- node = menu_layout_node_new (MENU_LAYOUT_NODE_FILENAME);
- menu_layout_node_set_content (node, desktop_file_id);
-
- menu_layout_node_append_child (include, node);
- menu_layout_node_unref (node);
- }
-}
-
-static void
-is_dot_directory (const char *basename,
- DesktopEntry *entry,
- gboolean *has_dot_directory)
-{
- if (!strcmp (basename, ".directory"))
- *has_dot_directory = TRUE;
-}
-
-static gboolean
-add_menu_for_legacy_dir (MenuLayoutNode *parent,
- const char *legacy_dir,
- const char *relative_path,
- const char *legacy_prefix,
- const char *menu_name)
-{
- EntryDirectory *ed;
- DesktopEntrySet *desktop_entries;
- DesktopEntrySet *directory_entries;
- GSList *subdirs;
- gboolean menu_added;
- gboolean has_dot_directory;
-
- ed = entry_directory_new_legacy (DESKTOP_ENTRY_INVALID, legacy_dir, legacy_prefix);
- if (!ed)
- return FALSE;
-
- subdirs = NULL;
- desktop_entries = desktop_entry_set_new ();
- directory_entries = desktop_entry_set_new ();
-
- entry_directory_get_flat_contents (ed,
- desktop_entries,
- directory_entries,
- &subdirs);
- entry_directory_unref (ed);
-
- has_dot_directory = FALSE;
- desktop_entry_set_foreach (directory_entries,
- (DesktopEntrySetForeachFunc) is_dot_directory,
- &has_dot_directory);
- desktop_entry_set_unref (directory_entries);
-
- menu_added = FALSE;
- if (desktop_entry_set_get_count (desktop_entries) > 0 || subdirs)
- {
- MenuLayoutNode *menu;
- MenuLayoutNode *node;
- GString *subdir_path;
- GString *subdir_relative;
- GSList *tmp;
- int legacy_dir_len;
- int relative_path_len;
-
- menu = menu_layout_node_new (MENU_LAYOUT_NODE_MENU);
- menu_layout_node_append_child (parent, menu);
-
- menu_added = TRUE;
-
- g_assert (menu_name != NULL);
-
- node = menu_layout_node_new (MENU_LAYOUT_NODE_NAME);
- menu_layout_node_set_content (node, menu_name);
- menu_layout_node_append_child (menu, node);
- menu_layout_node_unref (node);
-
- if (has_dot_directory)
- {
- node = menu_layout_node_new (MENU_LAYOUT_NODE_DIRECTORY);
- if (relative_path != NULL)
- {
- char *directory_entry_path;
-
- directory_entry_path = g_strdup_printf ("%s/.directory", relative_path);
- menu_layout_node_set_content (node, directory_entry_path);
- g_free (directory_entry_path);
- }
- else
- {
- menu_layout_node_set_content (node, ".directory");
- }
- menu_layout_node_append_child (menu, node);
- menu_layout_node_unref (node);
- }
-
- if (desktop_entry_set_get_count (desktop_entries) > 0)
- {
- MenuLayoutNode *include;
-
- include = menu_layout_node_new (MENU_LAYOUT_NODE_INCLUDE);
- menu_layout_node_append_child (menu, include);
-
- desktop_entry_set_foreach (desktop_entries,
- (DesktopEntrySetForeachFunc) add_filename_include,
- include);
-
- menu_layout_node_unref (include);
- }
-
- subdir_path = g_string_new (legacy_dir);
- legacy_dir_len = strlen (legacy_dir);
-
- subdir_relative = g_string_new (relative_path);
- relative_path_len = relative_path ? strlen (relative_path) : 0;
-
- tmp = subdirs;
- while (tmp != NULL)
- {
- const char *subdir = tmp->data;
-
- g_string_append_c (subdir_path, G_DIR_SEPARATOR);
- g_string_append (subdir_path, subdir);
-
- if (relative_path_len)
- {
- g_string_append_c (subdir_relative, G_DIR_SEPARATOR);
- }
- g_string_append (subdir_relative, subdir);
-
- add_menu_for_legacy_dir (menu,
- subdir_path->str,
- subdir_relative->str,
- legacy_prefix,
- subdir);
-
- g_string_truncate (subdir_relative, relative_path_len);
- g_string_truncate (subdir_path, legacy_dir_len);
-
- tmp = tmp->next;
- }
-
- g_string_free (subdir_path, TRUE);
- g_string_free (subdir_relative, TRUE);
-
- menu_layout_node_unref (menu);
- }
-
- desktop_entry_set_unref (desktop_entries);
-
- g_slist_foreach (subdirs, (GFunc) g_free, NULL);
- g_slist_free (subdirs);
-
- return menu_added;
-}
-
-static void
-resolve_legacy_dir (XfceMenuTree *tree,
- GHashTable *loaded_menu_files,
- MenuLayoutNode *legacy)
-{
- MenuLayoutNode *to_merge;
- MenuLayoutNode *menu;
-
- to_merge = menu_layout_node_new (MENU_LAYOUT_NODE_ROOT);
-
- menu = menu_layout_node_get_parent (legacy);
- g_assert (menu_layout_node_get_type (menu) == MENU_LAYOUT_NODE_MENU);
-
- if (add_menu_for_legacy_dir (to_merge,
- menu_layout_node_get_content (legacy),
- NULL,
- menu_layout_node_legacy_dir_get_prefix (legacy),
- menu_layout_node_menu_get_name (menu)))
- {
- merge_resolved_children (tree, loaded_menu_files, legacy, to_merge);
- }
-
- menu_layout_node_unref (to_merge);
-}
-
-static MenuLayoutNode *
-add_legacy_dir (XfceMenuTree *tree,
- GHashTable *loaded_menu_files,
- MenuLayoutNode *before,
- const char *data_dir)
-{
- MenuLayoutNode *legacy;
- char *dirname;
-
- dirname = g_build_filename (data_dir, "applnk", NULL);
-
- legacy = menu_layout_node_new (MENU_LAYOUT_NODE_LEGACY_DIR);
- menu_layout_node_set_content (legacy, dirname);
- menu_layout_node_legacy_dir_set_prefix (legacy, "kde");
- menu_layout_node_insert_before (before, legacy);
- menu_layout_node_unref (before);
-
- menu_verbose ("Adding <LegacyDir>%s</LegacyDir> in <KDELegacyDirs/>\n",
- dirname);
-
- resolve_legacy_dir (tree, loaded_menu_files, legacy);
-
- g_free (dirname);
-
- return legacy;
-}
-
-static void
-resolve_kde_legacy_dirs (XfceMenuTree *tree,
- GHashTable *loaded_menu_files,
- MenuLayoutNode *layout)
-{
- MenuLayoutNode *before;
- const char * const *system_data_dirs;
- int i;
-
- system_data_dirs = g_get_system_data_dirs ();
-
- before = add_legacy_dir (tree,
- loaded_menu_files,
- menu_layout_node_ref (layout),
- g_get_user_data_dir ());
-
- i = 0;
- while (system_data_dirs[i] != NULL)
- {
- before = add_legacy_dir (tree, loaded_menu_files, before, system_data_dirs[i]);
-
- ++i;
- }
-
- menu_layout_node_unref (before);
-
- /* remove the now-replaced node */
- menu_layout_node_unlink (layout);
-}
-
-static void
-xfcemenu_tree_resolve_files (XfceMenuTree *tree,
- GHashTable *loaded_menu_files,
- MenuLayoutNode *layout)
-{
- MenuLayoutNode *child;
-
- menu_verbose ("Resolving files in: ");
- menu_debug_print_layout (layout, TRUE);
-
- switch (menu_layout_node_get_type (layout))
- {
- case MENU_LAYOUT_NODE_MERGE_FILE:
- resolve_merge_file (tree, loaded_menu_files, layout);
- break;
-
- case MENU_LAYOUT_NODE_MERGE_DIR:
- resolve_merge_dir (tree, loaded_menu_files, layout);
- break;
-
- case MENU_LAYOUT_NODE_DEFAULT_APP_DIRS:
- resolve_default_app_dirs (tree, layout);
- break;
-
- case MENU_LAYOUT_NODE_DEFAULT_DIRECTORY_DIRS:
- resolve_default_directory_dirs (tree, layout);
- break;
-
- case MENU_LAYOUT_NODE_DEFAULT_MERGE_DIRS:
- resolve_default_merge_dirs (tree, loaded_menu_files, layout);
- break;
-
- case MENU_LAYOUT_NODE_LEGACY_DIR:
- resolve_legacy_dir (tree, loaded_menu_files, layout);
- break;
-
- case MENU_LAYOUT_NODE_KDE_LEGACY_DIRS:
- resolve_kde_legacy_dirs (tree, loaded_menu_files, layout);
- break;
-
- case MENU_LAYOUT_NODE_PASSTHROUGH:
- /* Just get rid of these, we don't need the memory usage */
- menu_layout_node_unlink (layout);
- break;
-
- default:
- /* Recurse */
- child = menu_layout_node_get_children (layout);
- while (child != NULL)
- {
- MenuLayoutNode *next = menu_layout_node_get_next (child);
-
- xfcemenu_tree_resolve_files (tree, loaded_menu_files, child);
-
- child = next;
- }
- break;
- }
-}
-
-static void
-move_children (MenuLayoutNode *from,
- MenuLayoutNode *to)
-{
- MenuLayoutNode *from_child;
- MenuLayoutNode *insert_before;
-
- insert_before = menu_layout_node_get_children (to);
- from_child = menu_layout_node_get_children (from);
-
- while (from_child != NULL)
- {
- MenuLayoutNode *next;
-
- next = menu_layout_node_get_next (from_child);
-
- menu_layout_node_steal (from_child);
-
- if (menu_layout_node_get_type (from_child) == MENU_LAYOUT_NODE_NAME)
- {
- ; /* just drop the Name in the old <Menu> */
- }
- else if (insert_before)
- {
- menu_layout_node_insert_before (insert_before, from_child);
- g_assert (menu_layout_node_get_next (from_child) == insert_before);
- }
- else
- {
- menu_layout_node_append_child (to, from_child);
- }
-
- menu_layout_node_unref (from_child);
-
- from_child = next;
- }
-}
-
-static int
-null_safe_strcmp (const char *a,
- const char *b)
-{
- if (a == NULL && b == NULL)
- return 0;
- else if (a == NULL)
- return -1;
- else if (b == NULL)
- return 1;
- else
- return strcmp (a, b);
-}
-
-static int
-node_compare_func (const void *a,
- const void *b)
-{
- MenuLayoutNode *node_a = (MenuLayoutNode*) a;
- MenuLayoutNode *node_b = (MenuLayoutNode*) b;
- MenuLayoutNodeType t_a = menu_layout_node_get_type (node_a);
- MenuLayoutNodeType t_b = menu_layout_node_get_type (node_b);
-
- if (t_a < t_b)
- return -1;
- else if (t_a > t_b)
- return 1;
- else
- {
- const char *c_a = menu_layout_node_get_content (node_a);
- const char *c_b = menu_layout_node_get_content (node_b);
-
- return null_safe_strcmp (c_a, c_b);
- }
-}
-
-static int
-node_menu_compare_func (const void *a,
- const void *b)
-{
- MenuLayoutNode *node_a = (MenuLayoutNode*) a;
- MenuLayoutNode *node_b = (MenuLayoutNode*) b;
- MenuLayoutNode *parent_a = menu_layout_node_get_parent (node_a);
- MenuLayoutNode *parent_b = menu_layout_node_get_parent (node_b);
-
- if (parent_a < parent_b)
- return -1;
- else if (parent_a > parent_b)
- return 1;
- else
- return null_safe_strcmp (menu_layout_node_menu_get_name (node_a),
- menu_layout_node_menu_get_name (node_b));
-}
-
-static void
-xfcemenu_tree_strip_duplicate_children (XfceMenuTree *tree,
- MenuLayoutNode *layout)
-{
- MenuLayoutNode *child;
- GSList *simple_nodes;
- GSList *menu_layout_nodes;
- GSList *prev;
- GSList *tmp;
-
- /* to strip dups, we find all the child nodes where
- * we want to kill dups, sort them,
- * then nuke the adjacent nodes that are equal
- */
-
- simple_nodes = NULL;
- menu_layout_nodes = NULL;
-
- child = menu_layout_node_get_children (layout);
- while (child != NULL)
- {
- switch (menu_layout_node_get_type (child))
- {
- /* These are dups if their content is the same */
- case MENU_LAYOUT_NODE_APP_DIR:
- case MENU_LAYOUT_NODE_DIRECTORY_DIR:
- case MENU_LAYOUT_NODE_DIRECTORY:
- simple_nodes = g_slist_prepend (simple_nodes, child);
- break;
-
- /* These have to be merged in a more complicated way,
- * and then recursed
- */
- case MENU_LAYOUT_NODE_MENU:
- menu_layout_nodes = g_slist_prepend (menu_layout_nodes, child);
- break;
-
- default:
- break;
- }
-
- child = menu_layout_node_get_next (child);
- }
-
- /* Note that the lists are all backward. So we want to keep
- * the items that are earlier in the list, because they were
- * later in the file
- */
-
- /* stable sort the simple nodes */
- simple_nodes = g_slist_sort (simple_nodes,
- node_compare_func);
-
- prev = NULL;
- tmp = simple_nodes;
- while (tmp != NULL)
- {
- GSList *next = tmp->next;
-
- if (prev)
- {
- MenuLayoutNode *p = prev->data;
- MenuLayoutNode *n = tmp->data;
-
- if (node_compare_func (p, n) == 0)
- {
- /* nuke it! */
- menu_layout_node_unlink (n);
- simple_nodes = g_slist_delete_link (simple_nodes, tmp);
- tmp = prev;
- }
- }
-
- prev = tmp;
- tmp = next;
- }
-
- g_slist_free (simple_nodes);
- simple_nodes = NULL;
-
- /* stable sort the menu nodes (the sort includes the
- * parents of the nodes in the comparison). Remember
- * the list is backward.
- */
- menu_layout_nodes = g_slist_sort (menu_layout_nodes,
- node_menu_compare_func);
-
- prev = NULL;
- tmp = menu_layout_nodes;
- while (tmp != NULL)
- {
- GSList *next = tmp->next;
-
- if (prev)
- {
- MenuLayoutNode *p = prev->data;
- MenuLayoutNode *n = tmp->data;
-
- if (node_menu_compare_func (p, n) == 0)
- {
- /* Move children of first menu to the start of second
- * menu and nuke the first menu
- */
- move_children (n, p);
- menu_layout_node_unlink (n);
- menu_layout_nodes = g_slist_delete_link (menu_layout_nodes, tmp);
- tmp = prev;
- }
- }
-
- prev = tmp;
- tmp = next;
- }
-
- g_slist_free (menu_layout_nodes);
- menu_layout_nodes = NULL;
-
- /* Recursively clean up all children */
- child = menu_layout_node_get_children (layout);
- while (child != NULL)
- {
- if (menu_layout_node_get_type (child) == MENU_LAYOUT_NODE_MENU)
- xfcemenu_tree_strip_duplicate_children (tree, child);
-
- child = menu_layout_node_get_next (child);
- }
-}
-
-static MenuLayoutNode *
-find_submenu (MenuLayoutNode *layout,
- const char *path,
- gboolean create_if_not_found)
-{
- MenuLayoutNode *child;
- const char *slash;
- const char *next_path;
- char *name;
-
- menu_verbose (" (splitting \"%s\")\n", path);
-
- if (path[0] == '\0' || path[0] == G_DIR_SEPARATOR)
- return NULL;
-
- slash = strchr (path, G_DIR_SEPARATOR);
- if (slash != NULL)
- {
- name = g_strndup (path, slash - path);
- next_path = slash + 1;
- if (*next_path == '\0')
- next_path = NULL;
- }
- else
- {
- name = g_strdup (path);
- next_path = NULL;
- }
-
- child = menu_layout_node_get_children (layout);
- while (child != NULL)
- {
- switch (menu_layout_node_get_type (child))
- {
- case MENU_LAYOUT_NODE_MENU:
- {
- if (strcmp (name, menu_layout_node_menu_get_name (child)) == 0)
- {
- menu_verbose ("MenuNode %p found for path component \"%s\"\n",
- child, name);
-
- g_free (name);
-
- if (!next_path)
- {
- menu_verbose (" Found menu node %p parent is %p\n",
- child, layout);
- return child;
- }
-
- return find_submenu (child, next_path, create_if_not_found);
- }
- }
- break;
-
- default:
- break;
- }
-
- child = menu_layout_node_get_next (child);
- }
-
- if (create_if_not_found)
- {
- MenuLayoutNode *name_node;
-
- child = menu_layout_node_new (MENU_LAYOUT_NODE_MENU);
- menu_layout_node_append_child (layout, child);
-
- name_node = menu_layout_node_new (MENU_LAYOUT_NODE_NAME);
- menu_layout_node_set_content (name_node, name);
- menu_layout_node_append_child (child, name_node);
- menu_layout_node_unref (name_node);
-
- menu_verbose (" Created menu node %p parent is %p\n",
- child, layout);
-
- menu_layout_node_unref (child);
- g_free (name);
-
- if (!next_path)
- return child;
-
- return find_submenu (child, next_path, create_if_not_found);
- }
- else
- {
- g_free (name);
- return NULL;
- }
-}
-
-/* To call this you first have to strip duplicate children once,
- * otherwise when you move a menu Foo to Bar then you may only
- * move one of Foo, not all the merged Foo.
- */
-static void
-xfcemenu_tree_execute_moves (XfceMenuTree *tree,
- MenuLayoutNode *layout,
- gboolean *need_remove_dups_p)
-{
- MenuLayoutNode *child;
- gboolean need_remove_dups;
- GSList *move_nodes;
- GSList *tmp;
-
- need_remove_dups = FALSE;
-
- move_nodes = NULL;
-
- child = menu_layout_node_get_children (layout);
- while (child != NULL)
- {
- switch (menu_layout_node_get_type (child))
- {
- case MENU_LAYOUT_NODE_MENU:
- /* Recurse - we recurse first and process the current node
- * second, as the spec dictates.
- */
- xfcemenu_tree_execute_moves (tree, child, &need_remove_dups);
- break;
-
- case MENU_LAYOUT_NODE_MOVE:
- move_nodes = g_slist_prepend (move_nodes, child);
- break;
-
- default:
- break;
- }
-
- child = menu_layout_node_get_next (child);
- }
-
- /* We need to execute the move operations in the order that they appear */
- move_nodes = g_slist_reverse (move_nodes);
-
- tmp = move_nodes;
- while (tmp != NULL)
- {
- MenuLayoutNode *move_node = tmp->data;
- MenuLayoutNode *old_node;
- GSList *next = tmp->next;
- const char *old;
- const char *new;
-
- old = menu_layout_node_move_get_old (move_node);
- new = menu_layout_node_move_get_new (move_node);
- g_assert (old != NULL && new != NULL);
-
- menu_verbose ("executing <Move> old = \"%s\" new = \"%s\"\n",
- old, new);
-
- old_node = find_submenu (layout, old, FALSE);
- if (old_node != NULL)
- {
- MenuLayoutNode *new_node;
-
- /* here we can create duplicates anywhere below the
- * node
- */
- need_remove_dups = TRUE;
-
- /* look up new node creating it and its parents if
- * required
- */
- new_node = find_submenu (layout, new, TRUE);
- g_assert (new_node != NULL);
-
- move_children (old_node, new_node);
-
- menu_layout_node_unlink (old_node);
- }
-
- menu_layout_node_unlink (move_node);
-
- tmp = next;
- }
-
- g_slist_free (move_nodes);
-
- /* This oddness is to ensure we only remove dups once,
- * at the root, instead of recursing the tree over
- * and over.
- */
- if (need_remove_dups_p)
- *need_remove_dups_p = need_remove_dups;
- else if (need_remove_dups)
- xfcemenu_tree_strip_duplicate_children (tree, layout);
-}
-
-static void
-xfcemenu_tree_load_layout (XfceMenuTree *tree)
-{
- GHashTable *loaded_menu_files;
- GError *error;
-
- if (tree->layout)
- return;
-
- if (!xfcemenu_tree_canonicalize_path (tree))
- return;
-
- menu_verbose ("Loading menu layout from \"%s\"\n",
- tree->canonical_path);
-
- error = NULL;
- tree->layout = menu_layout_load (tree->canonical_path,
- tree->type == XFCEMENU_TREE_BASENAME ?
- tree->basename : NULL,
- &error);
- if (tree->layout == NULL)
- {
- g_warning ("Error loading menu layout from \"%s\": %s",
- tree->canonical_path, error->message);
- g_error_free (error);
- return;
- }
-
- loaded_menu_files = g_hash_table_new (g_str_hash, g_str_equal);
- g_hash_table_insert (loaded_menu_files, tree->canonical_path, GUINT_TO_POINTER (TRUE));
- xfcemenu_tree_resolve_files (tree, loaded_menu_files, tree->layout);
- g_hash_table_destroy (loaded_menu_files);
-
- xfcemenu_tree_strip_duplicate_children (tree, tree->layout);
- xfcemenu_tree_execute_moves (tree, tree->layout, NULL);
-}
-
-static void
-xfcemenu_tree_force_reload (XfceMenuTree *tree)
-{
- xfcemenu_tree_force_rebuild (tree);
-
- if (tree->layout)
- menu_layout_node_unref (tree->layout);
- tree->layout = NULL;
-}
-
-typedef struct
-{
- DesktopEntrySet *set;
- const char *category;
-} GetByCategoryForeachData;
-
-static void
-get_by_category_foreach (const char *file_id,
- DesktopEntry *entry,
- GetByCategoryForeachData *data)
-{
- if (desktop_entry_has_category (entry, data->category))
- desktop_entry_set_add_entry (data->set, entry, file_id);
-}
-
-static void
-get_by_category (DesktopEntrySet *entry_pool,
- DesktopEntrySet *set,
- const char *category)
-{
- GetByCategoryForeachData data;
-
- data.set = set;
- data.category = category;
-
- desktop_entry_set_foreach (entry_pool,
- (DesktopEntrySetForeachFunc) get_by_category_foreach,
- &data);
-}
-
-static DesktopEntrySet *
-process_include_rules (MenuLayoutNode *layout,
- DesktopEntrySet *entry_pool)
-{
- DesktopEntrySet *set = NULL;
-
- switch (menu_layout_node_get_type (layout))
- {
- case MENU_LAYOUT_NODE_AND:
- {
- MenuLayoutNode *child;
-
- menu_verbose ("Processing <And>\n");
-
- child = menu_layout_node_get_children (layout);
- while (child != NULL)
- {
- DesktopEntrySet *child_set;
-
- child_set = process_include_rules (child, entry_pool);
-
- if (set == NULL)
- {
- set = child_set;
- }
- else
- {
- desktop_entry_set_intersection (set, child_set);
- desktop_entry_set_unref (child_set);
- }
-
- /* as soon as we get empty results, we can bail,
- * because it's an AND
- */
- if (desktop_entry_set_get_count (set) == 0)
- break;
-
- child = menu_layout_node_get_next (child);
- }
- menu_verbose ("Processed <And>\n");
- }
- break;
-
- case MENU_LAYOUT_NODE_OR:
- {
- MenuLayoutNode *child;
-
- menu_verbose ("Processing <Or>\n");
-
- child = menu_layout_node_get_children (layout);
- while (child != NULL)
- {
- DesktopEntrySet *child_set;
-
- child_set = process_include_rules (child, entry_pool);
-
- if (set == NULL)
- {
- set = child_set;
- }
- else
- {
- desktop_entry_set_union (set, child_set);
- desktop_entry_set_unref (child_set);
- }
-
- child = menu_layout_node_get_next (child);
- }
- menu_verbose ("Processed <Or>\n");
- }
- break;
-
- case MENU_LAYOUT_NODE_NOT:
- {
- /* First get the OR of all the rules */
- MenuLayoutNode *child;
-
- menu_verbose ("Processing <Not>\n");
-
- child = menu_layout_node_get_children (layout);
- while (child != NULL)
- {
- DesktopEntrySet *child_set;
-
- child_set = process_include_rules (child, entry_pool);
-
- if (set == NULL)
- {
- set = child_set;
- }
- else
- {
- desktop_entry_set_union (set, child_set);
- desktop_entry_set_unref (child_set);
- }
-
- child = menu_layout_node_get_next (child);
- }
-
- if (set != NULL)
- {
- DesktopEntrySet *inverted;
-
- /* Now invert the result */
- inverted = desktop_entry_set_new ();
- desktop_entry_set_union (inverted, entry_pool);
- desktop_entry_set_subtract (inverted, set);
- desktop_entry_set_unref (set);
- set = inverted;
- }
- menu_verbose ("Processed <Not>\n");
- }
- break;
-
- case MENU_LAYOUT_NODE_ALL:
- menu_verbose ("Processing <All>\n");
- set = desktop_entry_set_new ();
- desktop_entry_set_union (set, entry_pool);
- menu_verbose ("Processed <All>\n");
- break;
-
- case MENU_LAYOUT_NODE_FILENAME:
- {
- DesktopEntry *entry;
-
- menu_verbose ("Processing <Filename>%s</Filename>\n",
- menu_layout_node_get_content (layout));
-
- entry = desktop_entry_set_lookup (entry_pool,
- menu_layout_node_get_content (layout));
- if (entry != NULL)
- {
- set = desktop_entry_set_new ();
- desktop_entry_set_add_entry (set,
- entry,
- menu_layout_node_get_content (layout));
- }
- menu_verbose ("Processed <Filename>%s</Filename>\n",
- menu_layout_node_get_content (layout));
- }
- break;
-
- case MENU_LAYOUT_NODE_CATEGORY:
- menu_verbose ("Processing <Category>%s</Category>\n",
- menu_layout_node_get_content (layout));
- set = desktop_entry_set_new ();
- get_by_category (entry_pool, set, menu_layout_node_get_content (layout));
- menu_verbose ("Processed <Category>%s</Category>\n",
- menu_layout_node_get_content (layout));
- break;
-
- default:
- break;
- }
-
- if (set == NULL)
- set = desktop_entry_set_new (); /* create an empty set */
-
- menu_verbose ("Matched %d entries\n", desktop_entry_set_get_count (set));
-
- return set;
-}
-
-static void
-collect_layout_info (MenuLayoutNode *layout,
- GSList **layout_info)
-{
- MenuLayoutNode *iter;
-
- g_slist_foreach (*layout_info,
- (GFunc) menu_layout_node_unref,
- NULL);
- g_slist_free (*layout_info);
- *layout_info = NULL;
-
- iter = menu_layout_node_get_children (layout);
- while (iter != NULL)
- {
- switch (menu_layout_node_get_type (iter))
- {
- case MENU_LAYOUT_NODE_MENUNAME:
- case MENU_LAYOUT_NODE_FILENAME:
- case MENU_LAYOUT_NODE_SEPARATOR:
- case MENU_LAYOUT_NODE_MERGE:
- *layout_info = g_slist_prepend (*layout_info,
- menu_layout_node_ref (iter));
- break;
-
- default:
- break;
- }
-
- iter = menu_layout_node_get_next (iter);
- }
-
- *layout_info = g_slist_reverse (*layout_info);
-}
-
-static void
-entries_listify_foreach (const char *desktop_file_id,
- DesktopEntry *desktop_entry,
- XfceMenuTreeDirectory *directory)
-{
- directory->entries =
- g_slist_prepend (directory->entries,
- xfcemenu_tree_entry_new (directory,
- desktop_entry,
- desktop_file_id,
- FALSE,
- desktop_entry_get_no_display (desktop_entry)));
-}
-
-static void
-excluded_entries_listify_foreach (const char *desktop_file_id,
- DesktopEntry *desktop_entry,
- XfceMenuTreeDirectory *directory)
-{
- directory->entries =
- g_slist_prepend (directory->entries,
- xfcemenu_tree_entry_new (directory,
- desktop_entry,
- desktop_file_id,
- TRUE,
- desktop_entry_get_no_display (desktop_entry)));
-}
-
-static void
-set_default_layout_values (XfceMenuTreeDirectory *parent,
- XfceMenuTreeDirectory *child)
-{
- GSList *tmp;
-
- /* if the child has a defined default layout, we don't want to override its
- * values. The parent might have a non-defined layout info (ie, no child of
- * the DefaultLayout node) but it doesn't meant the default layout values
- * (ie, DefaultLayout attributes) aren't different from the global defaults.
- */
- if (child->default_layout_info != NULL ||
- child->default_layout_values.mask != MENU_LAYOUT_VALUES_NONE)
- return;
-
- child->default_layout_values = parent->default_layout_values;
-
- tmp = child->subdirs;
- while (tmp != NULL)
- {
- XfceMenuTreeDirectory *subdir = tmp->data;
-
- set_default_layout_values (child, subdir);
-
- tmp = tmp->next;
- }
-}
-
-static XfceMenuTreeDirectory *
-process_layout (XfceMenuTree *tree,
- XfceMenuTreeDirectory *parent,
- MenuLayoutNode *layout,
- DesktopEntrySet *allocated)
-{
- MenuLayoutNode *layout_iter;
- XfceMenuTreeDirectory *directory;
- DesktopEntrySet *entry_pool;
- DesktopEntrySet *entries;
- DesktopEntrySet *allocated_set;
- DesktopEntrySet *excluded_set;
- gboolean deleted;
- gboolean only_unallocated;
- GSList *tmp;
-
- g_assert (menu_layout_node_get_type (layout) == MENU_LAYOUT_NODE_MENU);
- g_assert (menu_layout_node_menu_get_name (layout) != NULL);
-
- directory = xfcemenu_tree_directory_new (parent,
- menu_layout_node_menu_get_name (layout),
- parent == NULL);
-
- menu_verbose ("=== Menu name = %s ===\n", directory->name);
-
-
- deleted = FALSE;
- only_unallocated = FALSE;
-
- entries = desktop_entry_set_new ();
- allocated_set = desktop_entry_set_new ();
-
- if (tree->flags & XFCEMENU_TREE_FLAGS_INCLUDE_EXCLUDED)
- excluded_set = desktop_entry_set_new ();
- else
- excluded_set = NULL;
-
- entry_pool = _entry_directory_list_get_all_desktops (menu_layout_node_menu_get_app_dirs (layout));
-
- layout_iter = menu_layout_node_get_children (layout);
- while (layout_iter != NULL)
- {
- switch (menu_layout_node_get_type (layout_iter))
- {
- case MENU_LAYOUT_NODE_MENU:
- /* recurse */
- {
- XfceMenuTreeDirectory *child_dir;
-
- menu_verbose ("Processing <Menu>\n");
-
- child_dir = process_layout (tree,
- directory,
- layout_iter,
- allocated);
- if (child_dir)
- directory->subdirs = g_slist_prepend (directory->subdirs,
- child_dir);
-
- menu_verbose ("Processed <Menu>\n");
- }
- break;
-
- case MENU_LAYOUT_NODE_INCLUDE:
- {
- /* The match rule children of the <Include> are
- * independent (logical OR) so we can process each one by
- * itself
- */
- MenuLayoutNode *rule;
-
- menu_verbose ("Processing <Include> (%d entries)\n",
- desktop_entry_set_get_count (entries));
-
- rule = menu_layout_node_get_children (layout_iter);
- while (rule != NULL)
- {
- DesktopEntrySet *rule_set;
-
- rule_set = process_include_rules (rule, entry_pool);
- if (rule_set != NULL)
- {
- desktop_entry_set_union (entries, rule_set);
- desktop_entry_set_union (allocated_set, rule_set);
- if (excluded_set != NULL)
- desktop_entry_set_subtract (excluded_set, rule_set);
- desktop_entry_set_unref (rule_set);
- }
-
- rule = menu_layout_node_get_next (rule);
- }
-
- menu_verbose ("Processed <Include> (%d entries)\n",
- desktop_entry_set_get_count (entries));
- }
- break;
-
- case MENU_LAYOUT_NODE_EXCLUDE:
- {
- /* The match rule children of the <Exclude> are
- * independent (logical OR) so we can process each one by
- * itself
- */
- MenuLayoutNode *rule;
-
- menu_verbose ("Processing <Exclude> (%d entries)\n",
- desktop_entry_set_get_count (entries));
-
- rule = menu_layout_node_get_children (layout_iter);
- while (rule != NULL)
- {
- DesktopEntrySet *rule_set;
-
- rule_set = process_include_rules (rule, entry_pool);
- if (rule_set != NULL)
- {
- if (excluded_set != NULL)
- desktop_entry_set_union (excluded_set, rule_set);
- desktop_entry_set_subtract (entries, rule_set);
- desktop_entry_set_unref (rule_set);
- }
-
- rule = menu_layout_node_get_next (rule);
- }
-
- menu_verbose ("Processed <Exclude> (%d entries)\n",
- desktop_entry_set_get_count (entries));
- }
- break;
-
- case MENU_LAYOUT_NODE_DIRECTORY:
- {
- DesktopEntry *entry;
-
- menu_verbose ("Processing <Directory>%s</Directory>\n",
- menu_layout_node_get_content (layout_iter));
-
- /*
- * The last <Directory> to exist wins, so we always try overwriting
- */
- entry = entry_directory_list_get_directory (menu_layout_node_menu_get_directory_dirs (layout),
- menu_layout_node_get_content (layout_iter));
-
- if (entry != NULL)
- {
- if (!desktop_entry_get_hidden (entry))
- {
- if (directory->directory_entry)
- desktop_entry_unref (directory->directory_entry);
- directory->directory_entry = entry; /* pass ref ownership */
- }
- else
- {
- desktop_entry_unref (entry);
- }
- }
-
- menu_verbose ("Processed <Directory> new directory entry = %p (%s)\n",
- directory->directory_entry,
- directory->directory_entry? desktop_entry_get_path (directory->directory_entry) : "null");
- }
- break;
-
- case MENU_LAYOUT_NODE_DELETED:
- menu_verbose ("Processed <Deleted/>\n");
- deleted = TRUE;
- break;
-
- case MENU_LAYOUT_NODE_NOT_DELETED:
- menu_verbose ("Processed <NotDeleted/>\n");
- deleted = FALSE;
- break;
-
- case MENU_LAYOUT_NODE_ONLY_UNALLOCATED:
- menu_verbose ("Processed <OnlyUnallocated/>\n");
- only_unallocated = TRUE;
- break;
-
- case MENU_LAYOUT_NODE_NOT_ONLY_UNALLOCATED:
- menu_verbose ("Processed <NotOnlyUnallocated/>\n");
- only_unallocated = FALSE;
- break;
-
- case MENU_LAYOUT_NODE_DEFAULT_LAYOUT:
- menu_layout_node_default_layout_get_values (layout_iter,
- &directory->default_layout_values);
- collect_layout_info (layout_iter, &directory->default_layout_info);
- menu_verbose ("Processed <DefaultLayout/>\n");
- break;
-
- case MENU_LAYOUT_NODE_LAYOUT:
- collect_layout_info (layout_iter, &directory->layout_info);
- menu_verbose ("Processed <Layout/>\n");
- break;
-
- default:
- break;
- }
-
- layout_iter = menu_layout_node_get_next (layout_iter);
- }
-
- desktop_entry_set_unref (entry_pool);
-
- directory->only_unallocated = only_unallocated;
-
- if (!directory->only_unallocated)
- desktop_entry_set_union (allocated, allocated_set);
-
- desktop_entry_set_unref (allocated_set);
-
- if (directory->directory_entry)
- {
- if (desktop_entry_get_no_display (directory->directory_entry))
- {
- directory->is_nodisplay = TRUE;
-
- if (!(tree->flags & XFCEMENU_TREE_FLAGS_INCLUDE_NODISPLAY))
- {
- menu_verbose ("Not showing menu %s because NoDisplay=true\n",
- desktop_entry_get_name (directory->directory_entry));
- deleted = TRUE;
- }
- }
-
- if (!desktop_entry_get_show_in_xfce (directory->directory_entry))
- {
- menu_verbose ("Not showing menu %s because OnlyShowIn!=XFCE or NotShowIn=XFCE\n",
- desktop_entry_get_name (directory->directory_entry));
- deleted = TRUE;
- }
- }
-
- if (deleted)
- {
- if (excluded_set != NULL)
- desktop_entry_set_unref (excluded_set);
- desktop_entry_set_unref (entries);
- xfcemenu_tree_item_unref (directory);
- return NULL;
- }
-
- desktop_entry_set_foreach (entries,
- (DesktopEntrySetForeachFunc) entries_listify_foreach,
- directory);
- desktop_entry_set_unref (entries);
-
- if (excluded_set != NULL)
- {
- desktop_entry_set_foreach (excluded_set,
- (DesktopEntrySetForeachFunc) excluded_entries_listify_foreach,
- directory);
- desktop_entry_set_unref (excluded_set);
- }
-
- tmp = directory->subdirs;
- while (tmp != NULL)
- {
- XfceMenuTreeDirectory *subdir = tmp->data;
-
- set_default_layout_values (directory, subdir);
-
- tmp = tmp->next;
- }
-
- tmp = directory->entries;
- while (tmp != NULL)
- {
- XfceMenuTreeEntry *entry = tmp->data;
- GSList *next = tmp->next;
- gboolean delete = FALSE;
-
- if (desktop_entry_get_hidden (entry->desktop_entry))
- {
- menu_verbose ("Deleting %s because Hidden=true\n",
- desktop_entry_get_name (entry->desktop_entry));
- delete = TRUE;
- }
-
- if (!(tree->flags & XFCEMENU_TREE_FLAGS_INCLUDE_NODISPLAY) &&
- desktop_entry_get_no_display (entry->desktop_entry))
- {
- menu_verbose ("Deleting %s because NoDisplay=true\n",
- desktop_entry_get_name (entry->desktop_entry));
- delete = TRUE;
- }
-
- if (!desktop_entry_get_show_in_xfce (entry->desktop_entry))
- {
- menu_verbose ("Deleting %s because OnlyShowIn!=XFCE or NotShowIn=XFCE\n",
- desktop_entry_get_name (entry->desktop_entry));
- delete = TRUE;
- }
-
- if (desktop_entry_get_tryexec_failed (entry->desktop_entry))
- {
- menu_verbose ("Deleting %s because TryExec failed\n",
- desktop_entry_get_name (entry->desktop_entry));
- delete = TRUE;
- }
-
- if (delete)
- {
- directory->entries = g_slist_delete_link (directory->entries,
- tmp);
- xfcemenu_tree_item_unref_and_unset_parent (entry);
- }
-
- tmp = next;
- }
-
- g_assert (directory->name != NULL);
-
- return directory;
-}
-
-static void
-process_only_unallocated (XfceMenuTree *tree,
- XfceMenuTreeDirectory *directory,
- DesktopEntrySet *allocated)
-{
- GSList *tmp;
-
- /* For any directory marked only_unallocated, we have to remove any
- * entries that were in fact allocated.
- */
-
- if (directory->only_unallocated)
- {
- tmp = directory->entries;
- while (tmp != NULL)
- {
- XfceMenuTreeEntry *entry = tmp->data;
- GSList *next = tmp->next;
-
- if (desktop_entry_set_lookup (allocated, entry->desktop_file_id))
- {
- directory->entries = g_slist_delete_link (directory->entries,
- tmp);
- xfcemenu_tree_item_unref_and_unset_parent (entry);
- }
-
- tmp = next;
- }
- }
-
- tmp = directory->subdirs;
- while (tmp != NULL)
- {
- XfceMenuTreeDirectory *subdir = tmp->data;
-
- process_only_unallocated (tree, subdir, allocated);
-
- tmp = tmp->next;
- }
-}
-
-static void preprocess_layout_info (XfceMenuTree *tree,
- XfceMenuTreeDirectory *directory);
-
-static GSList *
-get_layout_info (XfceMenuTreeDirectory *directory,
- gboolean *is_default_layout)
-{
- XfceMenuTreeDirectory *iter;
-
- if (directory->layout_info != NULL)
- {
- if (is_default_layout)
- {
- *is_default_layout = FALSE;
- }
- return directory->layout_info;
- }
-
- /* Even if there's no layout information at all, the result will be an
- * implicit default layout */
- if (is_default_layout)
- {
- *is_default_layout = TRUE;
- }
-
- iter = directory;
- while (iter != NULL)
- {
- /* FIXME: this is broken: we might skip real parent in the
- * XML structure, that are hidden because of inlining. */
- if (iter->default_layout_info != NULL)
- {
- return iter->default_layout_info;
- }
-
- iter = XFCEMENU_TREE_ITEM (iter)->parent;
- }
-
- return NULL;
-}
-
-static void
-get_values_with_defaults (MenuLayoutNode *node,
- MenuLayoutValues *layout_values,
- MenuLayoutValues *default_layout_values)
-{
- menu_layout_node_menuname_get_values (node, layout_values);
-
- if (!(layout_values->mask & MENU_LAYOUT_VALUES_SHOW_EMPTY))
- layout_values->show_empty = default_layout_values->show_empty;
-
- if (!(layout_values->mask & MENU_LAYOUT_VALUES_INLINE_MENUS))
- layout_values->inline_menus = default_layout_values->inline_menus;
-
- if (!(layout_values->mask & MENU_LAYOUT_VALUES_INLINE_LIMIT))
- layout_values->inline_limit = default_layout_values->inline_limit;
-
- if (!(layout_values->mask & MENU_LAYOUT_VALUES_INLINE_HEADER))
- layout_values->inline_header = default_layout_values->inline_header;
-
- if (!(layout_values->mask & MENU_LAYOUT_VALUES_INLINE_ALIAS))
- layout_values->inline_alias = default_layout_values->inline_alias;
-}
-
-static guint
-get_real_subdirs_len (XfceMenuTreeDirectory *directory)
-{
- guint len;
- GSList *tmp;
-
- len = 0;
-
- tmp = directory->subdirs;
- while (tmp != NULL)
- {
- XfceMenuTreeDirectory *subdir = tmp->data;
-
- tmp = tmp->next;
-
- if (subdir->will_inline_header != G_MAXUINT16)
- {
- len += get_real_subdirs_len (subdir) + g_slist_length (subdir->entries) + 1;
- }
- else
- len += 1;
- }
-
- return len;
-}
-
-static void
-preprocess_layout_info_subdir_helper (XfceMenuTree *tree,
- XfceMenuTreeDirectory *directory,
- XfceMenuTreeDirectory *subdir,
- MenuLayoutValues *layout_values,
- gboolean *contents_added,
- gboolean *should_remove)
-{
- preprocess_layout_info (tree, subdir);
-
- *should_remove = FALSE;
- *contents_added = FALSE;
-
- if (subdir->subdirs == NULL && subdir->entries == NULL)
- {
- if (!(tree->flags & XFCEMENU_TREE_FLAGS_SHOW_EMPTY) &&
- !layout_values->show_empty)
- {
- menu_verbose ("Not showing empty menu '%s'\n", subdir->name);
- *should_remove = TRUE;
- }
- }
-
- else if (layout_values->inline_menus)
- {
- guint real_subdirs_len;
-
- real_subdirs_len = get_real_subdirs_len (subdir);
-
- if (layout_values->inline_alias &&
- real_subdirs_len + g_slist_length (subdir->entries) == 1)
- {
- XfceMenuTreeAlias *alias;
- XfceMenuTreeItem *item;
- GSList *list;
-
- if (subdir->subdirs != NULL)
- list = subdir->subdirs;
- else
- list = subdir->entries;
-
- item = XFCEMENU_TREE_ITEM (list->data);
-
- menu_verbose ("Inline aliasing '%s' to '%s'\n",
- item->type == XFCEMENU_TREE_ITEM_ENTRY ?
- xfcemenu_tree_entry_get_name (XFCEMENU_TREE_ENTRY (item)) :
- (item->type == XFCEMENU_TREE_ITEM_DIRECTORY ?
- xfcemenu_tree_directory_get_name (XFCEMENU_TREE_DIRECTORY (item)) :
- xfcemenu_tree_directory_get_name (XFCEMENU_TREE_ALIAS (item)->directory)),
- subdir->name);
-
- alias = xfcemenu_tree_alias_new (directory, subdir, item);
-
- g_slist_foreach (list,
- (GFunc) xfcemenu_tree_item_unref_and_unset_parent,
- NULL);
- g_slist_free (list);
- subdir->subdirs = NULL;
- subdir->entries = NULL;
-
- if (item->type == XFCEMENU_TREE_ITEM_DIRECTORY)
- directory->subdirs = g_slist_append (directory->subdirs, alias);
- else
- directory->entries = g_slist_append (directory->entries, alias);
-
- *contents_added = TRUE;
- *should_remove = TRUE;
- }
-
- else if (layout_values->inline_limit == 0 ||
- layout_values->inline_limit >= real_subdirs_len + g_slist_length (subdir->entries))
- {
- if (layout_values->inline_header)
- {
- menu_verbose ("Creating inline header with name '%s'\n", subdir->name);
- /* we're limited to 16-bits to spare some memory; if the limit is
- * higher than that (would be crazy), we just consider it's
- * unlimited */
- if (layout_values->inline_limit < G_MAXUINT16)
- subdir->will_inline_header = layout_values->inline_limit;
- else
- subdir->will_inline_header = 0;
- }
- else
- {
- g_slist_foreach (subdir->subdirs,
- (GFunc) xfcemenu_tree_item_set_parent,
- directory);
- directory->subdirs = g_slist_concat (directory->subdirs,
- subdir->subdirs);
- subdir->subdirs = NULL;
-
- g_slist_foreach (subdir->entries,
- (GFunc) xfcemenu_tree_item_set_parent,
- directory);
- directory->entries = g_slist_concat (directory->entries,
- subdir->entries);
- subdir->entries = NULL;
-
- *contents_added = TRUE;
- *should_remove = TRUE;
- }
-
- menu_verbose ("Inlining directory contents of '%s' to '%s'\n",
- subdir->name, directory->name);
- }
- }
-}
-
-static void
-preprocess_layout_info (XfceMenuTree *tree,
- XfceMenuTreeDirectory *directory)
-{
- GSList *tmp;
- GSList *layout_info;
- gboolean using_default_layout;
- GSList *last_subdir;
- gboolean strip_duplicates;
- gboolean contents_added;
- gboolean should_remove;
- GSList *subdirs_sentinel;
-
- /* Note: we need to preprocess all menus, even if the layout mask for a menu
- * is MENU_LAYOUT_VALUES_NONE: in this case, we need to remove empty menus;
- * and the layout mask can be different for a submenu anyway */
-
- menu_verbose ("Processing menu layout inline hints for %s\n", directory->name);
- g_assert (!directory->preprocessed);
-
- strip_duplicates = FALSE;
- /* we use last_subdir to track the last non-inlined subdirectory */
- last_subdir = g_slist_last (directory->subdirs);
-
- /*
- * First process subdirectories with explicit layout
- */
- layout_info = get_layout_info (directory, &using_default_layout);
- tmp = layout_info;
- /* see comment below about Menuname to understand why we leave the loop if
- * last_subdir is NULL */
- while (tmp != NULL && last_subdir != NULL)
- {
- MenuLayoutNode *node = tmp->data;
- MenuLayoutValues layout_values;
- const char *name;
- XfceMenuTreeDirectory *subdir;
- GSList *subdir_l;
-
- tmp = tmp->next;
-
- /* only Menuname nodes are relevant here */
- if (menu_layout_node_get_type (node) != MENU_LAYOUT_NODE_MENUNAME)
- continue;
-
- get_values_with_defaults (node,
- &layout_values,
- &directory->default_layout_values);
-
- /* find the subdirectory that is affected by those attributes */
- name = menu_layout_node_get_content (node);
- subdir = NULL;
- subdir_l = directory->subdirs;
- while (subdir_l != NULL)
- {
- subdir = subdir_l->data;
-
- if (!strcmp (subdir->name, name))
- break;
-
- subdir = NULL;
- subdir_l = subdir_l->next;
-
- /* We do not want to use Menuname on a menu that appeared via
- * inlining: without inlining, the Menuname wouldn't have matched
- * anything, and we want to keep the same behavior.
- * Unless the layout is a default layout, in which case the Menuname
- * does match the subdirectory. */
- if (!using_default_layout && subdir_l == last_subdir)
- {
- subdir_l = NULL;
- break;
- }
- }
-
- if (subdir == NULL)
- continue;
-
- preprocess_layout_info_subdir_helper (tree, directory,
- subdir, &layout_values,
- &contents_added, &should_remove);
- strip_duplicates = strip_duplicates || contents_added;
- if (should_remove)
- {
- if (last_subdir == subdir_l)
- {
- /* we need to recompute last_subdir since we'll remove it from
- * the list */
- GSList *buf;
-
- if (subdir_l == directory->subdirs)
- last_subdir = NULL;
- else
- {
- buf = directory->subdirs;
- while (buf != NULL && buf->next != subdir_l)
- buf = buf->next;
- last_subdir = buf;
- }
- }
-
- directory->subdirs = g_slist_remove (directory->subdirs, subdir);
- xfcemenu_tree_item_unref_and_unset_parent (XFCEMENU_TREE_ITEM (subdir));
- }
- }
-
- /*
- * Now process the subdirectories with no explicit layout
- */
- /* this is bogus data, but we just need the pointer anyway */
- subdirs_sentinel = g_slist_prepend (directory->subdirs, PACKAGE);
- directory->subdirs = subdirs_sentinel;
-
- tmp = directory->subdirs;
- while (tmp->next != NULL)
- {
- XfceMenuTreeDirectory *subdir = tmp->next->data;
-
- if (subdir->preprocessed)
- {
- tmp = tmp->next;
- continue;
- }
-
- preprocess_layout_info_subdir_helper (tree, directory,
- subdir, &directory->default_layout_values,
- &contents_added, &should_remove);
- strip_duplicates = strip_duplicates || contents_added;
- if (should_remove)
- {
- tmp = g_slist_delete_link (tmp, tmp->next);
- xfcemenu_tree_item_unref_and_unset_parent (XFCEMENU_TREE_ITEM (subdir));
- }
- else
- tmp = tmp->next;
- }
-
- /* remove the sentinel */
- directory->subdirs = g_slist_delete_link (directory->subdirs,
- directory->subdirs);
-
- /*
- * Finally, remove duplicates if needed
- */
- if (strip_duplicates)
- {
- /* strip duplicate entries; there should be no duplicate directories */
- directory->entries = g_slist_sort (directory->entries,
- (GCompareFunc) xfcemenu_tree_entry_compare_by_id);
- tmp = directory->entries;
- while (tmp != NULL && tmp->next != NULL)
- {
- XfceMenuTreeItem *a = tmp->data;
- XfceMenuTreeItem *b = tmp->next->data;
-
- if (a->type == XFCEMENU_TREE_ITEM_ALIAS)
- a = XFCEMENU_TREE_ALIAS (a)->aliased_item;
-
- if (b->type == XFCEMENU_TREE_ITEM_ALIAS)
- b = XFCEMENU_TREE_ALIAS (b)->aliased_item;
-
- if (strcmp (XFCEMENU_TREE_ENTRY (a)->desktop_file_id,
- XFCEMENU_TREE_ENTRY (b)->desktop_file_id) == 0)
- {
- tmp = g_slist_delete_link (tmp, tmp->next);
- xfcemenu_tree_item_unref (b);
- }
- else
- tmp = tmp->next;
- }
- }
-
- directory->preprocessed = TRUE;
-}
-
-static void process_layout_info (XfceMenuTree *tree,
- XfceMenuTreeDirectory *directory);
-
-static void
-check_pending_separator (XfceMenuTreeDirectory *directory)
-{
- if (directory->layout_pending_separator)
- {
- menu_verbose ("Adding pending separator in '%s'\n", directory->name);
-
- directory->contents = g_slist_append (directory->contents,
- xfcemenu_tree_separator_new (directory));
- directory->layout_pending_separator = FALSE;
- }
-}
-
-static void
-merge_alias (XfceMenuTree *tree,
- XfceMenuTreeDirectory *directory,
- XfceMenuTreeAlias *alias)
-{
- menu_verbose ("Merging alias '%s' in directory '%s'\n",
- alias->directory->name, directory->name);
-
- if (alias->aliased_item->type == XFCEMENU_TREE_ITEM_DIRECTORY)
- {
- process_layout_info (tree, XFCEMENU_TREE_DIRECTORY (alias->aliased_item));
- }
-
- check_pending_separator (directory);
-
- directory->contents = g_slist_append (directory->contents,
- xfcemenu_tree_item_ref (alias));
-}
-
-static void
-merge_subdir (XfceMenuTree *tree,
- XfceMenuTreeDirectory *directory,
- XfceMenuTreeDirectory *subdir)
-{
- menu_verbose ("Merging subdir '%s' in directory '%s'\n",
- subdir->name, directory->name);
-
- process_layout_info (tree, subdir);
-
- check_pending_separator (directory);
-
- if (subdir->will_inline_header == 0 ||
- (subdir->will_inline_header != G_MAXUINT16 &&
- g_slist_length (subdir->contents) <= subdir->will_inline_header))
- {
- XfceMenuTreeHeader *header;
-
- header = xfcemenu_tree_header_new (directory, subdir);
- directory->contents = g_slist_append (directory->contents, header);
-
- g_slist_foreach (subdir->contents,
- (GFunc) xfcemenu_tree_item_set_parent,
- directory);
- directory->contents = g_slist_concat (directory->contents,
- subdir->contents);
- subdir->contents = NULL;
- subdir->will_inline_header = G_MAXUINT16;
-
- xfcemenu_tree_item_set_parent (XFCEMENU_TREE_ITEM (subdir), NULL);
- }
- else
- {
- directory->contents = g_slist_append (directory->contents,
- xfcemenu_tree_item_ref (subdir));
- }
-}
-
-static void
-merge_subdir_by_name (XfceMenuTree *tree,
- XfceMenuTreeDirectory *directory,
- const char *subdir_name)
-{
- GSList *tmp;
-
- menu_verbose ("Attempting to merge subdir '%s' in directory '%s'\n",
- subdir_name, directory->name);
-
- tmp = directory->subdirs;
- while (tmp != NULL)
- {
- XfceMenuTreeDirectory *subdir = tmp->data;
- GSList *next = tmp->next;
-
- /* if it's an alias, then it cannot be affected by
- * the Merge nodes in the layout */
- if (XFCEMENU_TREE_ITEM (subdir)->type == XFCEMENU_TREE_ITEM_ALIAS)
- continue;
-
- if (!strcmp (subdir->name, subdir_name))
- {
- directory->subdirs = g_slist_delete_link (directory->subdirs, tmp);
- merge_subdir (tree, directory, subdir);
- xfcemenu_tree_item_unref (subdir);
- }
-
- tmp = next;
- }
-}
-
-static void
-merge_entry (XfceMenuTree *tree,
- XfceMenuTreeDirectory *directory,
- XfceMenuTreeEntry *entry)
-{
- menu_verbose ("Merging entry '%s' in directory '%s'\n",
- entry->desktop_file_id, directory->name);
-
- check_pending_separator (directory);
- directory->contents = g_slist_append (directory->contents,
- xfcemenu_tree_item_ref (entry));
-}
-
-static void
-merge_entry_by_id (XfceMenuTree *tree,
- XfceMenuTreeDirectory *directory,
- const char *file_id)
-{
- GSList *tmp;
-
- menu_verbose ("Attempting to merge entry '%s' in directory '%s'\n",
- file_id, directory->name);
-
- tmp = directory->entries;
- while (tmp != NULL)
- {
- XfceMenuTreeEntry *entry = tmp->data;
- GSList *next = tmp->next;
-
- /* if it's an alias, then it cannot be affected by
- * the Merge nodes in the layout */
- if (XFCEMENU_TREE_ITEM (entry)->type == XFCEMENU_TREE_ITEM_ALIAS)
- continue;
-
- if (!strcmp (entry->desktop_file_id, file_id))
- {
- directory->entries = g_slist_delete_link (directory->entries, tmp);
- merge_entry (tree, directory, entry);
- xfcemenu_tree_item_unref (entry);
- }
-
- tmp = next;
- }
-}
-
-static inline gboolean
-find_name_in_list (const char *name,
- GSList *list)
-{
- while (list != NULL)
- {
- if (!strcmp (name, list->data))
- return TRUE;
-
- list = list->next;
- }
-
- return FALSE;
-}
-
-static void
-merge_subdirs (XfceMenuTree *tree,
- XfceMenuTreeDirectory *directory,
- GSList *except)
-{
- GSList *subdirs;
- GSList *tmp;
-
- menu_verbose ("Merging subdirs in directory '%s'\n", directory->name);
-
- subdirs = directory->subdirs;
- directory->subdirs = NULL;
-
- subdirs = g_slist_sort_with_data (subdirs,
- (GCompareDataFunc) xfcemenu_tree_item_compare,
- GINT_TO_POINTER (XFCEMENU_TREE_SORT_NAME));
-
- tmp = subdirs;
- while (tmp != NULL)
- {
- XfceMenuTreeDirectory *subdir = tmp->data;
-
- if (XFCEMENU_TREE_ITEM (subdir)->type == XFCEMENU_TREE_ITEM_ALIAS)
- {
- merge_alias (tree, directory, XFCEMENU_TREE_ALIAS (subdir));
- xfcemenu_tree_item_unref (subdir);
- }
- else if (!find_name_in_list (subdir->name, except))
- {
- merge_subdir (tree, directory, subdir);
- xfcemenu_tree_item_unref (subdir);
- }
- else
- {
- menu_verbose ("Not merging directory '%s' yet\n", subdir->name);
- directory->subdirs = g_slist_append (directory->subdirs, subdir);
- }
-
- tmp = tmp->next;
- }
-
- g_slist_free (subdirs);
- g_slist_free (except);
-}
-
-static void
-merge_entries (XfceMenuTree *tree,
- XfceMenuTreeDirectory *directory,
- GSList *except)
-{
- GSList *entries;
- GSList *tmp;
-
- menu_verbose ("Merging entries in directory '%s'\n", directory->name);
-
- entries = directory->entries;
- directory->entries = NULL;
-
- entries = g_slist_sort_with_data (entries,
- (GCompareDataFunc) xfcemenu_tree_item_compare,
- GINT_TO_POINTER (tree->sort_key));
-
- tmp = entries;
- while (tmp != NULL)
- {
- XfceMenuTreeEntry *entry = tmp->data;
-
- if (XFCEMENU_TREE_ITEM (entry)->type == XFCEMENU_TREE_ITEM_ALIAS)
- {
- merge_alias (tree, directory, XFCEMENU_TREE_ALIAS (entry));
- xfcemenu_tree_item_unref (entry);
- }
- else if (!find_name_in_list (entry->desktop_file_id, except))
- {
- merge_entry (tree, directory, entry);
- xfcemenu_tree_item_unref (entry);
- }
- else
- {
- menu_verbose ("Not merging entry '%s' yet\n", entry->desktop_file_id);
- directory->entries = g_slist_append (directory->entries, entry);
- }
-
- tmp = tmp->next;
- }
-
- g_slist_free (entries);
- g_slist_free (except);
-}
-
-static void
-merge_subdirs_and_entries (XfceMenuTree *tree,
- XfceMenuTreeDirectory *directory,
- GSList *except_subdirs,
- GSList *except_entries)
-{
- GSList *items;
- GSList *tmp;
-
- menu_verbose ("Merging subdirs and entries together in directory %s\n",
- directory->name);
-
- items = g_slist_concat (directory->subdirs, directory->entries);
-
- directory->subdirs = NULL;
- directory->entries = NULL;
-
- items = g_slist_sort_with_data (items,
- (GCompareDataFunc) xfcemenu_tree_item_compare,
- GINT_TO_POINTER (tree->sort_key));
-
- tmp = items;
- while (tmp != NULL)
- {
- XfceMenuTreeItem *item = tmp->data;
- XfceMenuTreeItemType type;
-
- type = xfcemenu_tree_item_get_type (item);
-
- if (type == XFCEMENU_TREE_ITEM_ALIAS)
- {
- merge_alias (tree, directory, XFCEMENU_TREE_ALIAS (item));
- xfcemenu_tree_item_unref (item);
- }
- else if (type == XFCEMENU_TREE_ITEM_DIRECTORY)
- {
- if (!find_name_in_list (XFCEMENU_TREE_DIRECTORY (item)->name, except_subdirs))
- {
- merge_subdir (tree,
- directory,
- XFCEMENU_TREE_DIRECTORY (item));
- xfcemenu_tree_item_unref (item);
- }
- else
- {
- menu_verbose ("Not merging directory '%s' yet\n",
- XFCEMENU_TREE_DIRECTORY (item)->name);
- directory->subdirs = g_slist_append (directory->subdirs, item);
- }
- }
- else if (type == XFCEMENU_TREE_ITEM_ENTRY)
- {
- if (!find_name_in_list (XFCEMENU_TREE_ENTRY (item)->desktop_file_id, except_entries))
- {
- merge_entry (tree, directory, XFCEMENU_TREE_ENTRY (item));
- xfcemenu_tree_item_unref (item);
- }
- else
- {
- menu_verbose ("Not merging entry '%s' yet\n",
- XFCEMENU_TREE_ENTRY (item)->desktop_file_id);
- directory->entries = g_slist_append (directory->entries, item);
- }
- }
- else
- {
- g_assert_not_reached ();
- }
-
- tmp = tmp->next;
- }
-
- g_slist_free (items);
- g_slist_free (except_subdirs);
- g_slist_free (except_entries);
-}
-
-static GSList *
-get_subdirs_from_layout_info (GSList *layout_info)
-{
- GSList *subdirs;
- GSList *tmp;
-
- subdirs = NULL;
-
- tmp = layout_info;
- while (tmp != NULL)
- {
- MenuLayoutNode *node = tmp->data;
-
- if (menu_layout_node_get_type (node) == MENU_LAYOUT_NODE_MENUNAME)
- {
- subdirs = g_slist_append (subdirs,
- (char *) menu_layout_node_get_content (node));
- }
-
- tmp = tmp->next;
- }
-
- return subdirs;
-}
-
-static GSList *
-get_entries_from_layout_info (GSList *layout_info)
-{
- GSList *entries;
- GSList *tmp;
-
- entries = NULL;
-
- tmp = layout_info;
- while (tmp != NULL)
- {
- MenuLayoutNode *node = tmp->data;
-
- if (menu_layout_node_get_type (node) == MENU_LAYOUT_NODE_FILENAME)
- {
- entries = g_slist_append (entries,
- (char *) menu_layout_node_get_content (node));
- }
-
- tmp = tmp->next;
- }
-
- return entries;
-}
-
-static void
-process_layout_info (XfceMenuTree *tree,
- XfceMenuTreeDirectory *directory)
-{
- GSList *layout_info;
-
- menu_verbose ("Processing menu layout hints for %s\n", directory->name);
-
- g_slist_foreach (directory->contents,
- (GFunc) xfcemenu_tree_item_unref_and_unset_parent,
- NULL);
- g_slist_free (directory->contents);
- directory->contents = NULL;
- directory->layout_pending_separator = FALSE;
-
- layout_info = get_layout_info (directory, NULL);
-
- if (layout_info == NULL)
- {
- merge_subdirs (tree, directory, NULL);
- merge_entries (tree, directory, NULL);
- }
- else
- {
- GSList *tmp;
-
- tmp = layout_info;
- while (tmp != NULL)
- {
- MenuLayoutNode *node = tmp->data;
-
- switch (menu_layout_node_get_type (node))
- {
- case MENU_LAYOUT_NODE_MENUNAME:
- merge_subdir_by_name (tree,
- directory,
- menu_layout_node_get_content (node));
- break;
-
- case MENU_LAYOUT_NODE_FILENAME:
- merge_entry_by_id (tree,
- directory,
- menu_layout_node_get_content (node));
- break;
-
- case MENU_LAYOUT_NODE_SEPARATOR:
- /* Unless explicitly told to show all separators, do not show a
- * separator at the beginning of a menu. Note that we don't add
- * the separators now, and instead make it pending. This way, we
- * won't show two consecutive separators nor will we show a
- * separator at the end of a menu. */
- if (tree->flags & XFCEMENU_TREE_FLAGS_SHOW_ALL_SEPARATORS)
- {
- directory->layout_pending_separator = TRUE;
- check_pending_separator (directory);
- }
- else if (directory->contents)
- {
- menu_verbose ("Adding a potential separator in '%s'\n",
- directory->name);
-
- directory->layout_pending_separator = TRUE;
- }
- else
- {
- menu_verbose ("Skipping separator at the beginning of '%s'\n",
- directory->name);
- }
- break;
-
- case MENU_LAYOUT_NODE_MERGE:
- switch (menu_layout_node_merge_get_type (node))
- {
- case MENU_LAYOUT_MERGE_NONE:
- break;
-
- case MENU_LAYOUT_MERGE_MENUS:
- merge_subdirs (tree,
- directory,
- get_subdirs_from_layout_info (tmp->next));
- break;
-
- case MENU_LAYOUT_MERGE_FILES:
- merge_entries (tree,
- directory,
- get_entries_from_layout_info (tmp->next));
- break;
-
- case MENU_LAYOUT_MERGE_ALL:
- merge_subdirs_and_entries (tree,
- directory,
- get_subdirs_from_layout_info (tmp->next),
- get_entries_from_layout_info (tmp->next));
- break;
-
- default:
- g_assert_not_reached ();
- break;
- }
- break;
-
- default:
- g_assert_not_reached ();
- break;
- }
-
- tmp = tmp->next;
- }
- }
-
- g_slist_foreach (directory->subdirs,
- (GFunc) xfcemenu_tree_item_unref,
- NULL);
- g_slist_free (directory->subdirs);
- directory->subdirs = NULL;
-
- g_slist_foreach (directory->entries,
- (GFunc) xfcemenu_tree_item_unref,
- NULL);
- g_slist_free (directory->entries);
- directory->entries = NULL;
-
- g_slist_foreach (directory->default_layout_info,
- (GFunc) menu_layout_node_unref,
- NULL);
- g_slist_free (directory->default_layout_info);
- directory->default_layout_info = NULL;
-
- g_slist_foreach (directory->layout_info,
- (GFunc) menu_layout_node_unref,
- NULL);
- g_slist_free (directory->layout_info);
- directory->layout_info = NULL;
-}
-
-static void
-handle_entries_changed (MenuLayoutNode *layout,
- XfceMenuTree *tree)
-{
- if (tree->layout == layout)
- {
- xfcemenu_tree_force_rebuild (tree);
- xfcemenu_tree_invoke_monitors (tree);
- }
-}
-
-static void
-xfcemenu_tree_build_from_layout (XfceMenuTree *tree)
-{
- DesktopEntrySet *allocated;
-
- if (tree->root)
- return;
-
- xfcemenu_tree_load_layout (tree);
- if (!tree->layout)
- return;
-
- menu_verbose ("Building menu tree from layout\n");
-
- allocated = desktop_entry_set_new ();
-
- /* create the menu structure */
- tree->root = process_layout (tree,
- NULL,
- find_menu_child (tree->layout),
- allocated);
- if (tree->root)
- {
- xfcemenu_tree_directory_set_tree (tree->root, tree);
-
- process_only_unallocated (tree, tree->root, allocated);
-
- /* process the layout info part that can move/remove items:
- * inline, show_empty, etc. */
- preprocess_layout_info (tree, tree->root);
- /* populate the menu structure that we got with the items, and order it
- * according to the layout info */
- process_layout_info (tree, tree->root);
-
- menu_layout_node_root_add_entries_monitor (tree->layout,
- (MenuLayoutNodeEntriesChangedFunc) handle_entries_changed,
- tree);
- }
-
- desktop_entry_set_unref (allocated);
-}
-
-static void
-xfcemenu_tree_force_rebuild (XfceMenuTree *tree)
-{
- if (tree->root)
- {
- xfcemenu_tree_directory_set_tree (tree->root, NULL);
- xfcemenu_tree_item_unref (tree->root);
- tree->root = NULL;
-
- g_assert (tree->layout != NULL);
-
- menu_layout_node_root_remove_entries_monitor (tree->layout,
- (MenuLayoutNodeEntriesChangedFunc) handle_entries_changed,
- tree);
- }
-}
diff --git a/src/xfcemenu-tree.h b/src/xfcemenu-tree.h
deleted file mode 100644
index f91167f..0000000
--- a/src/xfcemenu-tree.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2004 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef __XFCEMENU_TREE_H__
-#define __XFCEMENU_TREE_H__
-
-#include <glib.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct XfceMenuTree XfceMenuTree;
-typedef struct XfceMenuTreeItem XfceMenuTreeItem;
-typedef struct XfceMenuTreeDirectory XfceMenuTreeDirectory;
-typedef struct XfceMenuTreeEntry XfceMenuTreeEntry;
-typedef struct XfceMenuTreeSeparator XfceMenuTreeSeparator;
-typedef struct XfceMenuTreeHeader XfceMenuTreeHeader;
-typedef struct XfceMenuTreeAlias XfceMenuTreeAlias;
-
-typedef void (*XfceMenuTreeChangedFunc) (XfceMenuTree* tree, gpointer user_data);
-
-typedef enum {
- XFCEMENU_TREE_ITEM_INVALID = 0,
- XFCEMENU_TREE_ITEM_DIRECTORY,
- XFCEMENU_TREE_ITEM_ENTRY,
- XFCEMENU_TREE_ITEM_SEPARATOR,
- XFCEMENU_TREE_ITEM_HEADER,
- XFCEMENU_TREE_ITEM_ALIAS
-} XfceMenuTreeItemType;
-
-#define XFCEMENU_TREE_ITEM(i) ((XfceMenuTreeItem*)(i))
-#define XFCEMENU_TREE_DIRECTORY(i) ((XfceMenuTreeDirectory*)(i))
-#define XFCEMENU_TREE_ENTRY(i) ((XfceMenuTreeEntry*)(i))
-#define XFCEMENU_TREE_SEPARATOR(i) ((XfceMenuTreeSeparator*)(i))
-#define XFCEMENU_TREE_HEADER(i) ((XfceMenuTreeHeader*)(i))
-#define XFCEMENU_TREE_ALIAS(i) ((XfceMenuTreeAlias*)(i))
-
-typedef enum {
- XFCEMENU_TREE_FLAGS_NONE = 0,
- XFCEMENU_TREE_FLAGS_INCLUDE_EXCLUDED = 1 << 0,
- XFCEMENU_TREE_FLAGS_SHOW_EMPTY = 1 << 1,
- XFCEMENU_TREE_FLAGS_INCLUDE_NODISPLAY = 1 << 2,
- XFCEMENU_TREE_FLAGS_SHOW_ALL_SEPARATORS = 1 << 3,
- XFCEMENU_TREE_FLAGS_MASK = 0x0f
-} XfceMenuTreeFlags;
-
-typedef enum {
- #define XFCEMENU_TREE_SORT_FIRST XFCEMENU_TREE_SORT_NAME
- XFCEMENU_TREE_SORT_NAME = 0,
- XFCEMENU_TREE_SORT_DISPLAY_NAME
- #define XFCEMENU_TREE_SORT_LAST XFCEMENU_TREE_SORT_DISPLAY_NAME
-} XfceMenuTreeSortKey;
-
-XfceMenuTree* xfcemenu_tree_lookup(const char* menu_file, XfceMenuTreeFlags flags);
-
-void xfcemenu_tree_unref(XfceMenuTree* tree);
-
-XfceMenuTreeDirectory* xfcemenu_tree_get_root_directory(XfceMenuTree* tree);
-
-void xfcemenu_tree_item_unref(gpointer item);
-
-XfceMenuTreeItemType xfcemenu_tree_item_get_type(XfceMenuTreeItem* item);
-
-
-GSList* xfcemenu_tree_directory_get_contents(XfceMenuTreeDirectory* directory);
-
-const char* xfcemenu_tree_entry_get_name(XfceMenuTreeEntry* entry);
-const char* xfcemenu_tree_entry_get_exec(XfceMenuTreeEntry* entry);
-const char* xfcemenu_tree_entry_get_desktop_file_id(XfceMenuTreeEntry* entry);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __XFCEMENU_TREE_H__ */
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the Xfce4-commits
mailing list