]> git.pld-linux.org Git - packages/desktop-file-utils.git/blame - desktop-file-utils-directory_change_notify.patch
- added nodisplay and noshowin patches (support for NoDisplay and NoShowIn
[packages/desktop-file-utils.git] / desktop-file-utils-directory_change_notify.patch
CommitLineData
a0f3b157 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
3@@ -41,8 +41,16 @@
4 const char *name,
5 gboolean create_if_not_found);
6
7+static DesktopEntryTreeDirAddCallback dir_add_callback = NULL;
8+void desktop_entry_tree_dir_add_notify (void *element, void *user_data);
9
10
11+void
12+desktop_entry_tree_diradd_callback_set (DesktopEntryTreeDirAddCallback proc)
13+{
14+ dir_add_callback = proc;
15+}
16+
17 static MenuNode*
18 find_menu_child (MenuNode *node)
19 {
20@@ -1005,6 +1013,7 @@
21 MenuNode *orig_node;
22 MenuNode *resolved_node;
23 TreeNode *root;
24+ GSList *monitored_dirs;
25 };
26
27 static void build_tree (DesktopEntryTree *tree);
28@@ -1015,6 +1024,21 @@
29 static char* localized_path_for_entry (TreeNode *parent,
30 Entry *entry);
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);
39+
40+const char *desktop_entry_tree_get_menu_file_name (DesktopEntryTree *tree)
41+{
42+ g_return_val_if_fail (tree != NULL, NULL);
43+
44+ return tree->menu_file;
45+}
46+
47
48 DesktopEntryTree*
49 desktop_entry_tree_load (const char *filename,
50@@ -1083,6 +1107,7 @@
51 tree->orig_node = orig_node;
52 tree->resolved_node = resolved_node;
53 tree->root = NULL;
54+ tree->monitored_dirs = NULL;
55
56 return tree;
57 }
58@@ -1096,6 +1121,14 @@
59 tree->refcount += 1;
60 }
61
62+static void
63+monitored_dir_list_clear (void *element,
64+ void *user_data)
65+{
66+ GSList *list = element;
67+ g_free (list->data);
68+}
69+
70 void
71 desktop_entry_tree_unref (DesktopEntryTree *tree)
72 {
73@@ -1111,10 +1144,15 @@
74 menu_node_unref (tree->orig_node);
75 menu_node_unref (tree->resolved_node);
76 if (tree->root)
77+ {
78 tree_node_free (tree->root);
79+ tree->root = NULL;
80+ }
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);
85-#if 1
86+#if 0
87 /* debugging, to make memory stuff fail */
88 memset (tree, 0xff, sizeof (*tree));
89 tree->refcount = -5;
90@@ -1125,12 +1163,42 @@
91
92 void
93 desktop_entry_tree_invalidate (DesktopEntryTree *tree,
94- const char *dirname)
95+ const char *menu_file,
96+ const char *entry_path)
97 {
98- menu_cache_invalidate (tree->menu_cache, dirname);
99+ GHashTable *allocated;
100+ TreeNode *new_node;
101+ char *dirname;
102+
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);
108+ g_free (dirname);
109+
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.
113+ */
114+ allocated = g_hash_table_new (NULL, NULL);
115+
116+ new_node = tree_node_from_menu_node (NULL,
117+ find_menu_child (tree->resolved_node),
118+ allocated,
119+ tree);
120+ if (new_node)
121+ {
122+ tree_node_free (tree->root);
123+ tree->root = new_node;
124+ process_only_unallocated (tree->root, allocated);
125+ remove_empty_submenus (tree->root);
126+ }
127+
128+ g_hash_table_destroy (allocated);
129 }
130
131+
132 static TreeNode*
133 find_subdir (TreeNode *parent,
134 const char *subdir)
135@@ -1634,7 +1702,11 @@
136 {
137 GSList *tmp;
138
139+ if (!node)
140+ return;
141+
142 g_free (node->name);
143+ node->name = NULL;
144
145 tmp = node->subdirs;
146 while (tmp != NULL)
147@@ -1812,10 +1884,39 @@
148 }
149 #endif
150
151+/* Called from an entry_directory_list_foreach()... */
152+void
153+desktop_entry_tree_dir_add_notify (void *element, void *user_data)
154+{
155+ EntryDirectory *dir = element;
156+ DesktopEntryTree *tree = user_data;
157+ GSList *tmp;
158+ const char *path;
159+
160+ g_return_if_fail (dir != NULL);
161+ path = entry_directory_get_absolute_path (dir);
162+
163+ /* Ensure we haven't already set a callback for this directory with
164+ * this tree.
165+ */
166+ tmp = tree->monitored_dirs;
167+ while (tmp != NULL)
168+ {
169+ if (strcmp (tmp->data, path) == 0)
170+ return;
171+ tmp = tmp->next;
172+ }
173+
174+ tree->monitored_dirs = g_slist_append (tree->monitored_dirs, g_strdup (path));
175+ if (dir_add_callback)
176+ (*dir_add_callback) (tree, path);
177+}
178+
179 static TreeNode*
180 tree_node_from_menu_node (TreeNode *parent,
181 MenuNode *menu_node,
182- GHashTable *allocated)
183+ GHashTable *allocated,
184+ const DesktopEntryTree *tree)
185 {
186 MenuNode *child;
187 EntryDirectoryList *app_dirs;
188@@ -1854,7 +1955,8 @@
189
190 child_tree = tree_node_from_menu_node (tree_node,
191 child,
192- allocated);
193+ allocated,
194+ tree);
195 if (child_tree)
196 tree_node->subdirs = g_slist_prepend (tree_node->subdirs,
197 child_tree);
198@@ -2012,7 +2114,12 @@
199 if (tree_node_free_if_broken (tree_node))
200 return NULL;
201 else
202+ {
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);
206 return tree_node;
207+ }
208 }
209
210 static void
211@@ -2102,7 +2209,8 @@
212
213 tree->root = tree_node_from_menu_node (NULL,
214 find_menu_child (tree->resolved_node),
215- allocated);
216+ allocated,
217+ tree);
218 if (tree->root)
219 process_only_unallocated (tree->root, allocated);
220
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
223@@ -67,7 +67,8 @@
224
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);
230
231 /* These don't return references; the DesktopEntryTree is just immutable. */
232 gboolean desktop_entry_tree_get_node (DesktopEntryTree *tree,
233@@ -134,6 +135,11 @@
234 const char *menu_path_basename,
235 const char *override_fs_dirname_dest,
236 GError **error);
237+const char *desktop_entry_tree_get_menu_file_name (DesktopEntryTree *tree);
238+
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);
242
243
244 /* Diff */
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
247@@ -491,7 +491,7 @@
248 /* tell the tree that it needs to reload the .desktop file
249 * cache
250 */
251- desktop_entry_tree_invalidate (tree, override_dir);
252+ desktop_entry_tree_invalidate (tree, override_dir, override_dir);
253
254 /* Now include the .desktop file in the .menu file */
255 if (!desktop_entry_tree_include (tree,
256@@ -583,7 +583,7 @@
257 /* tell the tree that it needs to reload the .desktop file
258 * cache
259 */
260- desktop_entry_tree_invalidate (tree, override_dir);
261+ desktop_entry_tree_invalidate (tree, override_dir, override_dir);
262
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 @@
268 const char *path)
269 {
270 CachedDir* dir;
271- char *dirname;
272 char *basename;
273+ char *dirname;
274 char *canonical;
275 Entry *retval;
276
277 retval = NULL;
278- dirname = g_path_get_basename (path);
279-
280- canonical = g_canonicalize_file_name (dirname, FALSE);
281+ canonical = g_canonicalize_file_name (path, FALSE);
282 if (canonical == NULL)
283 {
284 menu_verbose ("Error %d getting entry \"%s\": %s\n", errno, path,
285 g_strerror (errno));
286- g_free (dirname);
287 return NULL;
288 }
289
290- basename = g_path_get_dirname (path);
291-
292+ dirname = g_path_get_dirname (path);
293 dir = cached_dir_load (cache, dirname, 0, NULL);
294-
295 if (dir != NULL)
296- retval = cached_dir_find_entry (dir, basename);
297-
298+ {
299+ basename = g_path_get_basename (path);
300+ retval = cached_dir_find_entry (dir, basename);
301+ g_free (basename);
302+ }
303 g_free (dirname);
304- g_free (basename);
305
306 if (retval)
307 entry_ref (retval);
308@@ -344,6 +341,12 @@
309 }
310 }
311
312+const char*
313+entry_directory_get_absolute_path (EntryDirectory *dir)
314+{
315+ return dir->absolute_path;
316+}
317+
318 static Entry*
319 entry_from_cached_entry (EntryDirectory *ed,
320 Entry *src,
321@@ -681,6 +684,12 @@
322 }
323
324 void
325+entry_directory_list_foreach (EntryDirectoryList *list, EntryDirectoryListForeachProc proc, DesktopEntryTree *tree)
326+{
327+ g_slist_foreach (list->dirs, proc, tree);
328+}
329+
330+void
331 entry_directory_list_prepend (EntryDirectoryList *list,
332 EntryDirectory *dir)
333 {
334@@ -1501,6 +1510,7 @@
335 while (tmp != NULL)
336 {
337 g_string_append (str, tmp->data);
338+ g_string_append (str, "/");
339
340 tmp = tmp->next;
341 }
342@@ -2173,6 +2183,10 @@
343 static EntryCache*
344 cached_dir_get_cache (CachedDir *dir)
345 {
346+ if (!dir->have_read_entries)
347+ {
348+ cached_dir_scan_recursive (dir, NULL);
349+ }
350 return dir->cache;
351 }
352
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
355@@ -24,6 +24,7 @@
356
357 #include <glib.h>
358 #include "menu-layout.h"
359+#include "menu-process.h"
360
361 /* This API is about actually loading directories full of .desktop
362 * files and the .desktop/.directory files themselves. It also has
363@@ -84,12 +85,19 @@
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);
368+
369+typedef void (*EntryDirectoryListForeachProc)(void *element, void *user_data);
370
371 EntryDirectoryList* entry_directory_list_new (void);
372
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);
379+
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
385@@ -29,9 +29,11 @@
386 #include <sys/stat.h>
387 #include <fcntl.h>
388 #include <errno.h>
389+#include <stdio.h>
390
391 #include <config.h>
392
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>
397@@ -46,6 +48,8 @@
398
399 #include "menu-tree-cache.h"
400 #include "menu-util.h"
401+#include "menu-entries.h"
402+#include "menu-process.h"
403
404 /* FIXME - we have a gettext domain problem while not included in libgnomevfs */
405 #define _(x) x
406@@ -151,6 +155,14 @@
407 static void monitor_handle_ref (MonitorHandle *handle);
408 static void monitor_handle_unref (MonitorHandle *handle);
409
410+
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);
417+
418 struct {
419 const char *scheme;
420 const char *menu_file;
421@@ -737,6 +749,7 @@
422 GnomeVFSMethod *
423 vfs_module_init (const char *method_name, const char *args)
424 {
425+ desktop_entry_tree_diradd_callback_set (directory_add_callback);
426 return &vtable;
427 }
428
429@@ -1988,3 +2001,33 @@
430 g_free (handle);
431 }
432 }
433+
434+static void
435+directory_add_callback (DesktopEntryTree * tree, const char * path)
436+{
437+ GnomeVFSMonitorHandle* handle;
438+
439+ gnome_vfs_monitor_add (&handle, path,
440+ GNOME_VFS_MONITOR_DIRECTORY,
441+ directory_monitor_callback, tree);
442+}
443+
444+
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)
450+{
451+ MenuMethod * method;
452+ DesktopEntryTree * tree = user_data;
453+
454+ method = method_checkout ();
455+
456+ if (tree)
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));
460+
461+ method_return (method);
462+}
This page took 0.452478 seconds and 4 git commands to generate.