1 --- desktop-file-utils-0.6/src/menu-process.c.directory-change-notify 2004-05-03 23:46:00.074881280 -0400
2 +++ desktop-file-utils-0.6/src/menu-process.c 2004-05-03 23:47:09.124384160 -0400
5 gboolean create_if_not_found);
7 +static DesktopEntryTreeDirAddCallback dir_add_callback = NULL;
8 +void desktop_entry_tree_dir_add_notify (void *element, void *user_data);
12 +desktop_entry_tree_diradd_callback_set (DesktopEntryTreeDirAddCallback proc)
14 + dir_add_callback = proc;
18 find_menu_child (MenuNode *node)
22 MenuNode *resolved_node;
24 + GSList *monitored_dirs;
27 static void build_tree (DesktopEntryTree *tree);
28 @@ -1015,6 +1024,21 @@
29 static char* localized_path_for_entry (TreeNode *parent,
31 static char* localized_path_for_node (TreeNode *node);
32 +static TreeNode* tree_node_from_menu_node (TreeNode *parent,
33 + MenuNode *menu_node,
34 + GHashTable *allocated,
35 + const DesktopEntryTree *tree);
36 +static void remove_empty_submenus (TreeNode * node);
37 +static void process_only_unallocated (TreeNode *node,
38 + GHashTable *allocated);
40 +const char *desktop_entry_tree_get_menu_file_name (DesktopEntryTree *tree)
42 + g_return_val_if_fail (tree != NULL, NULL);
44 + return tree->menu_file;
49 desktop_entry_tree_load (const char *filename,
51 tree->orig_node = orig_node;
52 tree->resolved_node = resolved_node;
54 + tree->monitored_dirs = NULL;
58 @@ -1096,6 +1121,14 @@
63 +monitored_dir_list_clear (void *element,
66 + GSList *list = element;
67 + g_free (list->data);
71 desktop_entry_tree_unref (DesktopEntryTree *tree)
73 @@ -1111,10 +1144,15 @@
74 menu_node_unref (tree->orig_node);
75 menu_node_unref (tree->resolved_node);
78 tree_node_free (tree->root);
81 + g_slist_foreach (tree->monitored_dirs, monitored_dir_list_clear, NULL);
82 + g_slist_free (tree->monitored_dirs);
83 entry_cache_unref (tree->entry_cache);
84 menu_cache_unref (tree->menu_cache);
87 /* debugging, to make memory stuff fail */
88 memset (tree, 0xff, sizeof (*tree));
90 @@ -1125,12 +1163,42 @@
93 desktop_entry_tree_invalidate (DesktopEntryTree *tree,
94 - const char *dirname)
95 + const char *menu_file,
96 + const char *entry_path)
98 - menu_cache_invalidate (tree->menu_cache, dirname);
99 + GHashTable *allocated;
100 + TreeNode *new_node;
103 + /* menu_file: the actual .menu file to reload */
104 + /* entry_dir: actual FS directory of .desktop files to reload */
105 + menu_cache_invalidate (tree->menu_cache, menu_file);
106 + dirname = g_path_get_dirname (entry_path);
107 entry_cache_invalidate (tree->entry_cache, dirname);
110 + /* FIXME For the actual DesktopEntryTree itself, there aren't really
111 + * invalidation functions yet (FIXME). Therefore, we blow away the root
112 + * and rebuild it every time.
114 + allocated = g_hash_table_new (NULL, NULL);
116 + new_node = tree_node_from_menu_node (NULL,
117 + find_menu_child (tree->resolved_node),
122 + tree_node_free (tree->root);
123 + tree->root = new_node;
124 + process_only_unallocated (tree->root, allocated);
125 + remove_empty_submenus (tree->root);
128 + g_hash_table_destroy (allocated);
133 find_subdir (TreeNode *parent,
135 @@ -1634,7 +1702,11 @@
147 @@ -1812,10 +1884,39 @@
151 +/* Called from an entry_directory_list_foreach()... */
153 +desktop_entry_tree_dir_add_notify (void *element, void *user_data)
155 + EntryDirectory *dir = element;
156 + DesktopEntryTree *tree = user_data;
160 + g_return_if_fail (dir != NULL);
161 + path = entry_directory_get_absolute_path (dir);
163 + /* Ensure we haven't already set a callback for this directory with
166 + tmp = tree->monitored_dirs;
167 + while (tmp != NULL)
169 + if (strcmp (tmp->data, path) == 0)
174 + tree->monitored_dirs = g_slist_append (tree->monitored_dirs, g_strdup (path));
175 + if (dir_add_callback)
176 + (*dir_add_callback) (tree, path);
180 tree_node_from_menu_node (TreeNode *parent,
182 - GHashTable *allocated)
183 + GHashTable *allocated,
184 + const DesktopEntryTree *tree)
187 EntryDirectoryList *app_dirs;
188 @@ -1854,7 +1955,8 @@
190 child_tree = tree_node_from_menu_node (tree_node,
196 tree_node->subdirs = g_slist_prepend (tree_node->subdirs,
198 @@ -2012,7 +2114,12 @@
199 if (tree_node_free_if_broken (tree_node))
203 + /* Monitor directories containing .desktop & .directory files for changes */
204 + entry_directory_list_foreach (app_dirs, desktop_entry_tree_dir_add_notify, tree);
205 + entry_directory_list_foreach (dir_dirs, desktop_entry_tree_dir_add_notify, tree);
211 @@ -2102,7 +2209,8 @@
213 tree->root = tree_node_from_menu_node (NULL,
214 find_menu_child (tree->resolved_node),
219 process_only_unallocated (tree->root, allocated);
221 --- desktop-file-utils-0.6/src/menu-process.h.directory-change-notify 2004-03-21 23:46:20.000000000 -0500
222 +++ desktop-file-utils-0.6/src/menu-process.h 2004-05-03 23:46:00.403831272 -0400
225 /* after calling this, the tree is out-of-date vs. what's on disk */
226 void desktop_entry_tree_invalidate (DesktopEntryTree *tree,
227 - const char *dirname);
228 + const char *menu_file,
229 + const char *entry_path);
231 /* These don't return references; the DesktopEntryTree is just immutable. */
232 gboolean desktop_entry_tree_get_node (DesktopEntryTree *tree,
234 const char *menu_path_basename,
235 const char *override_fs_dirname_dest,
237 +const char *desktop_entry_tree_get_menu_file_name (DesktopEntryTree *tree);
239 +/* Callback for each .desktop directory added */
240 +typedef void (*DesktopEntryTreeDirAddCallback)(DesktopEntryTree * tree, const char *path);
241 +void desktop_entry_tree_diradd_callback_set (DesktopEntryTreeDirAddCallback proc);
245 --- desktop-file-utils-0.6/src/menu-tree-cache.c.directory-change-notify 2004-05-03 23:45:59.753930072 -0400
246 +++ desktop-file-utils-0.6/src/menu-tree-cache.c 2004-05-03 23:46:00.407830664 -0400
248 /* tell the tree that it needs to reload the .desktop file
251 - desktop_entry_tree_invalidate (tree, override_dir);
252 + desktop_entry_tree_invalidate (tree, override_dir, override_dir);
254 /* Now include the .desktop file in the .menu file */
255 if (!desktop_entry_tree_include (tree,
257 /* tell the tree that it needs to reload the .desktop file
260 - desktop_entry_tree_invalidate (tree, override_dir);
261 + desktop_entry_tree_invalidate (tree, override_dir, override_dir);
263 /* Now include the .desktop file in the .menu file */
264 if (!desktop_entry_tree_exclude (tree,
265 --- desktop-file-utils-0.6/src/menu-entries.c.directory-change-notify 2004-03-21 23:46:20.000000000 -0500
266 +++ desktop-file-utils-0.6/src/menu-entries.c 2004-05-03 23:46:00.413829752 -0400
267 @@ -247,32 +247,29 @@
278 - dirname = g_path_get_basename (path);
280 - canonical = g_canonicalize_file_name (dirname, FALSE);
281 + canonical = g_canonicalize_file_name (path, FALSE);
282 if (canonical == NULL)
284 menu_verbose ("Error %d getting entry \"%s\": %s\n", errno, path,
290 - basename = g_path_get_dirname (path);
292 + dirname = g_path_get_dirname (path);
293 dir = cached_dir_load (cache, dirname, 0, NULL);
296 - retval = cached_dir_find_entry (dir, basename);
299 + basename = g_path_get_basename (path);
300 + retval = cached_dir_find_entry (dir, basename);
313 +entry_directory_get_absolute_path (EntryDirectory *dir)
315 + return dir->absolute_path;
319 entry_from_cached_entry (EntryDirectory *ed,
325 +entry_directory_list_foreach (EntryDirectoryList *list, EntryDirectoryListForeachProc proc, DesktopEntryTree *tree)
327 + g_slist_foreach (list->dirs, proc, tree);
331 entry_directory_list_prepend (EntryDirectoryList *list,
334 @@ -1501,6 +1510,7 @@
337 g_string_append (str, tmp->data);
338 + g_string_append (str, "/");
342 @@ -2173,6 +2183,10 @@
344 cached_dir_get_cache (CachedDir *dir)
346 + if (!dir->have_read_entries)
348 + cached_dir_scan_recursive (dir, NULL);
353 --- desktop-file-utils-0.6/src/menu-entries.h.directory-change-notify 2004-03-21 23:46:20.000000000 -0500
354 +++ desktop-file-utils-0.6/src/menu-entries.h 2004-05-03 23:46:00.416829296 -0400
358 #include "menu-layout.h"
359 +#include "menu-process.h"
361 /* This API is about actually loading directories full of .desktop
362 * files and the .desktop/.directory files themselves. It also has
364 void entry_directory_get_by_category (EntryDirectory *dir,
365 const char *category,
366 EntrySet *add_to_set);
367 +const char* entry_directory_get_absolute_path (EntryDirectory *dir);
369 +typedef void (*EntryDirectoryListForeachProc)(void *element, void *user_data);
371 EntryDirectoryList* entry_directory_list_new (void);
373 void entry_directory_list_ref (EntryDirectoryList *list);
374 void entry_directory_list_unref (EntryDirectoryList *list);
375 void entry_directory_list_clear (EntryDirectoryList *list);
376 +void entry_directory_list_foreach (EntryDirectoryList *list,
377 + EntryDirectoryListForeachProc proc,
378 + DesktopEntryTree *tree);
380 /* prepended dirs are searched first */
381 void entry_directory_list_prepend (EntryDirectoryList *list,
382 EntryDirectory *dir);
383 --- desktop-file-utils-0.6/src/menu-method.c.directory-change-notify 2004-05-03 23:45:59.440977648 -0400
384 +++ desktop-file-utils-0.6/src/menu-method.c 2004-05-03 23:46:00.423828232 -0400
386 #include <sys/stat.h>
393 +#include <libgnomevfs/gnome-vfs-ops.h>
394 #include <libgnomevfs/gnome-vfs-method.h>
395 #include <libgnomevfs/gnome-vfs-module-shared.h>
396 #include <libgnomevfs/gnome-vfs-module.h>
399 #include "menu-tree-cache.h"
400 #include "menu-util.h"
401 +#include "menu-entries.h"
402 +#include "menu-process.h"
404 /* FIXME - we have a gettext domain problem while not included in libgnomevfs */
407 static void monitor_handle_ref (MonitorHandle *handle);
408 static void monitor_handle_unref (MonitorHandle *handle);
411 +static void directory_add_callback (DesktopEntryTree * tree, const char * path);
412 +void directory_monitor_callback (GnomeVFSMonitorHandle *handle,
413 + const gchar *monitor_uri,
414 + const gchar *info_uri,
415 + GnomeVFSMonitorEventType event_type,
416 + gpointer user_data);
420 const char *menu_file;
423 vfs_module_init (const char *method_name, const char *args)
425 + desktop_entry_tree_diradd_callback_set (directory_add_callback);
429 @@ -1988,3 +2001,33 @@
435 +directory_add_callback (DesktopEntryTree * tree, const char * path)
437 + GnomeVFSMonitorHandle* handle;
439 + gnome_vfs_monitor_add (&handle, path,
440 + GNOME_VFS_MONITOR_DIRECTORY,
441 + directory_monitor_callback, tree);
445 +void directory_monitor_callback (GnomeVFSMonitorHandle *handle,
446 + const gchar *monitor_uri,
447 + const gchar *info_uri,
448 + GnomeVFSMonitorEventType event_type,
449 + gpointer user_data)
451 + MenuMethod * method;
452 + DesktopEntryTree * tree = user_data;
454 + method = method_checkout ();
457 + desktop_entry_tree_invalidate( tree,
458 + desktop_entry_tree_get_menu_file_name (tree),
459 + gnome_vfs_get_local_path_from_uri (info_uri));
461 + method_return (method);