Codebase list cinnamon-menus / upstream/3.8.1
New upstream version 3.8.1 Maximiliano Curia 5 years ago
49 changed file(s) with 11218 addition(s) and 22 deletion(s). Raw diff Collapse all Expand all
0 debian/patches
0 /* -*- mode:c; c-file-style: "gnu"; indent-tabs-mode: nil -*-
1 * Copyright (C) 2003, 2004, 2011 Red Hat, Inc.
2 *
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2 of the License, or (at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the
15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 * Boston, MA 02111-1307, USA.
17 */
18
19 #include <config.h>
20
21 #include "gmenu-tree.h"
22
23 #include <string.h>
24 #include <errno.h>
25
26 #include "menu-layout.h"
27 #include "menu-monitor.h"
28 #include "menu-util.h"
29 #include "canonicalize.h"
30
31 /* private */
32 typedef struct GMenuTreeItem GMenuTreeItem;
33 #define GMENU_TREE_ITEM(i) ((GMenuTreeItem *)(i))
34 #define GMENU_TREE_DIRECTORY(i) ((GMenuTreeDirectory *)(i))
35 #define GMENU_TREE_ENTRY(i) ((GMenuTreeEntry *)(i))
36 #define GMENU_TREE_SEPARATOR(i) ((GMenuTreeSeparator *)(i))
37 #define GMENU_TREE_HEADER(i) ((GMenuTreeHeader *)(i))
38 #define GMENU_TREE_ALIAS(i) ((GMenuTreeAlias *)(i))
39
40 enum {
41 PROP_0,
42
43 PROP_MENU_BASENAME,
44 PROP_MENU_PATH,
45 PROP_FLAGS
46 };
47
48 /* Signals */
49 enum
50 {
51 CHANGED,
52 LAST_SIGNAL
53 };
54
55 static guint gmenu_tree_signals [LAST_SIGNAL] = { 0 };
56
57 struct _GMenuTree
58 {
59 GObject parent_instance;
60
61 char *basename;
62 char *non_prefixed_basename;
63 char *path;
64 char *canonical_path;
65
66 GMenuTreeFlags flags;
67
68 GSList *menu_file_monitors;
69
70 MenuLayoutNode *layout;
71 GMenuTreeDirectory *root;
72 GHashTable *entries_by_id;
73
74 guint canonical : 1;
75 guint loaded : 1;
76 };
77
78 G_DEFINE_TYPE (GMenuTree, gmenu_tree, G_TYPE_OBJECT)
79
80 struct GMenuTreeItem
81 {
82 volatile gint refcount;
83
84 GMenuTreeItemType type;
85
86 GMenuTreeDirectory *parent;
87 GMenuTree *tree;
88 };
89
90 struct GMenuTreeIter
91 {
92 volatile gint refcount;
93
94 GMenuTreeItem *item;
95 GSList *contents;
96 GSList *contents_iter;
97 };
98
99 struct GMenuTreeDirectory
100 {
101 GMenuTreeItem item;
102
103 DesktopEntry *directory_entry;
104 char *name;
105
106 GSList *entries;
107 GSList *subdirs;
108
109 MenuLayoutValues default_layout_values;
110 GSList *default_layout_info;
111 GSList *layout_info;
112 GSList *contents;
113
114 guint only_unallocated : 1;
115 guint is_nodisplay : 1;
116 guint layout_pending_separator : 1;
117 guint preprocessed : 1;
118
119 /* 16 bits should be more than enough; G_MAXUINT16 means no inline header */
120 guint will_inline_header : 16;
121 };
122
123 struct GMenuTreeEntry
124 {
125 GMenuTreeItem item;
126
127 DesktopEntry *desktop_entry;
128 char *desktop_file_id;
129
130 guint is_excluded : 1;
131 guint is_unallocated : 1;
132 };
133
134 struct GMenuTreeSeparator
135 {
136 GMenuTreeItem item;
137 };
138
139 struct GMenuTreeHeader
140 {
141 GMenuTreeItem item;
142
143 GMenuTreeDirectory *directory;
144 };
145
146 struct GMenuTreeAlias
147 {
148 GMenuTreeItem item;
149
150 GMenuTreeDirectory *directory;
151 GMenuTreeItem *aliased_item;
152 };
153
154 static gboolean gmenu_tree_load_layout (GMenuTree *tree,
155 GError **error);
156 static void gmenu_tree_force_reload (GMenuTree *tree);
157 static gboolean gmenu_tree_build_from_layout (GMenuTree *tree,
158 GError **error);
159 static void gmenu_tree_force_rebuild (GMenuTree *tree);
160 static void gmenu_tree_resolve_files (GMenuTree *tree,
161 GHashTable *loaded_menu_files,
162 MenuLayoutNode *layout);
163 static void gmenu_tree_force_recanonicalize (GMenuTree *tree);
164 static void gmenu_tree_invoke_monitors (GMenuTree *tree);
165
166 static void gmenu_tree_item_unref_and_unset_parent (gpointer itemp);
167
168 typedef enum
169 {
170 MENU_FILE_MONITOR_INVALID = 0,
171 MENU_FILE_MONITOR_FILE,
172 MENU_FILE_MONITOR_NONEXISTENT_FILE,
173 MENU_FILE_MONITOR_DIRECTORY
174 } MenuFileMonitorType;
175
176 typedef struct
177 {
178 MenuFileMonitorType type;
179 MenuMonitor *monitor;
180 } MenuFileMonitor;
181
182 static void
183 handle_nonexistent_menu_file_changed (MenuMonitor *monitor,
184 MenuMonitorEvent event,
185 const char *path,
186 GMenuTree *tree)
187 {
188 if (event == MENU_MONITOR_EVENT_CHANGED ||
189 event == MENU_MONITOR_EVENT_CREATED)
190 {
191 menu_verbose ("\"%s\" %s, marking tree for recanonicalization\n",
192 path,
193 event == MENU_MONITOR_EVENT_CREATED ? "created" : "changed");
194
195 gmenu_tree_force_recanonicalize (tree);
196 gmenu_tree_invoke_monitors (tree);
197 }
198 }
199
200 static void
201 handle_menu_file_changed (MenuMonitor *monitor,
202 MenuMonitorEvent event,
203 const char *path,
204 GMenuTree *tree)
205 {
206 menu_verbose ("\"%s\" %s, marking tree for recanicalization\n",
207 path,
208 event == MENU_MONITOR_EVENT_CREATED ? "created" :
209 event == MENU_MONITOR_EVENT_CHANGED ? "changed" : "deleted");
210
211 gmenu_tree_force_recanonicalize (tree);
212 gmenu_tree_invoke_monitors (tree);
213 }
214
215 static void
216 handle_menu_file_directory_changed (MenuMonitor *monitor,
217 MenuMonitorEvent event,
218 const char *path,
219 GMenuTree *tree)
220 {
221 if (!g_str_has_suffix (path, ".menu"))
222 return;
223
224 menu_verbose ("\"%s\" %s, marking tree for recanicalization\n",
225 path,
226 event == MENU_MONITOR_EVENT_CREATED ? "created" :
227 event == MENU_MONITOR_EVENT_CHANGED ? "changed" : "deleted");
228
229 gmenu_tree_force_recanonicalize (tree);
230 gmenu_tree_invoke_monitors (tree);
231 }
232
233 static void
234 gmenu_tree_add_menu_file_monitor (GMenuTree *tree,
235 const char *path,
236 MenuFileMonitorType type)
237 {
238 MenuFileMonitor *monitor;
239
240 monitor = g_slice_new0 (MenuFileMonitor);
241
242 monitor->type = type;
243
244 switch (type)
245 {
246 case MENU_FILE_MONITOR_FILE:
247 menu_verbose ("Adding a menu file monitor for \"%s\"\n", path);
248
249 monitor->monitor = menu_get_file_monitor (path);
250 menu_monitor_add_notify (monitor->monitor,
251 (MenuMonitorNotifyFunc) handle_menu_file_changed,
252 tree);
253 break;
254
255 case MENU_FILE_MONITOR_NONEXISTENT_FILE:
256 menu_verbose ("Adding a menu file monitor for non-existent \"%s\"\n", path);
257
258 monitor->monitor = menu_get_file_monitor (path);
259 menu_monitor_add_notify (monitor->monitor,
260 (MenuMonitorNotifyFunc) handle_nonexistent_menu_file_changed,
261 tree);
262 break;
263
264 case MENU_FILE_MONITOR_DIRECTORY:
265 menu_verbose ("Adding a menu directory monitor for \"%s\"\n", path);
266
267 monitor->monitor = menu_get_directory_monitor (path);
268 menu_monitor_add_notify (monitor->monitor,
269 (MenuMonitorNotifyFunc) handle_menu_file_directory_changed,
270 tree);
271 break;
272
273 default:
274 g_assert_not_reached ();
275 break;
276 }
277
278 tree->menu_file_monitors = g_slist_prepend (tree->menu_file_monitors, monitor);
279 }
280
281 static void
282 remove_menu_file_monitor (MenuFileMonitor *monitor,
283 GMenuTree *tree)
284 {
285 switch (monitor->type)
286 {
287 case MENU_FILE_MONITOR_FILE:
288 menu_monitor_remove_notify (monitor->monitor,
289 (MenuMonitorNotifyFunc) handle_menu_file_changed,
290 tree);
291 break;
292
293 case MENU_FILE_MONITOR_NONEXISTENT_FILE:
294 menu_monitor_remove_notify (monitor->monitor,
295 (MenuMonitorNotifyFunc) handle_nonexistent_menu_file_changed,
296 tree);
297 break;
298
299 case MENU_FILE_MONITOR_DIRECTORY:
300 menu_monitor_remove_notify (monitor->monitor,
301 (MenuMonitorNotifyFunc) handle_menu_file_directory_changed,
302 tree);
303 break;
304
305 default:
306 g_assert_not_reached ();
307 break;
308 }
309
310 menu_monitor_unref (monitor->monitor);
311 monitor->monitor = NULL;
312
313 monitor->type = MENU_FILE_MONITOR_INVALID;
314
315 g_slice_free (MenuFileMonitor, monitor);
316 }
317
318 static void
319 gmenu_tree_remove_menu_file_monitors (GMenuTree *tree)
320 {
321 menu_verbose ("Removing all menu file monitors\n");
322
323 g_slist_foreach (tree->menu_file_monitors,
324 (GFunc) remove_menu_file_monitor,
325 tree);
326 g_slist_free (tree->menu_file_monitors);
327 tree->menu_file_monitors = NULL;
328 }
329
330 static gboolean
331 canonicalize_path (GMenuTree *tree,
332 const char *path)
333 {
334 tree->canonical_path = menu_canonicalize_file_name (path, FALSE);
335 if (tree->canonical_path)
336 {
337 tree->canonical = TRUE;
338 gmenu_tree_add_menu_file_monitor (tree,
339 tree->canonical_path,
340 MENU_FILE_MONITOR_FILE);
341 }
342 else
343 {
344 gmenu_tree_add_menu_file_monitor (tree,
345 path,
346 MENU_FILE_MONITOR_NONEXISTENT_FILE);
347 }
348
349 return tree->canonical;
350 }
351
352 static gboolean
353 canonicalize_basename_with_config_dir (GMenuTree *tree,
354 const char *basename,
355 const char *config_dir)
356 {
357 gboolean ret;
358 char *path;
359
360 path = g_build_filename (config_dir, "menus", basename, NULL);
361 ret = canonicalize_path (tree, path);
362 g_free (path);
363
364 return ret;
365 }
366
367 static void
368 canonicalize_basename (GMenuTree *tree,
369 const char *basename)
370 {
371 if (!canonicalize_basename_with_config_dir (tree,
372 basename,
373 g_get_user_config_dir ()))
374 {
375 const char * const *system_config_dirs;
376 int i;
377
378 system_config_dirs = g_get_system_config_dirs ();
379
380 i = 0;
381 while (system_config_dirs[i] != NULL)
382 {
383 if (canonicalize_basename_with_config_dir (tree,
384 basename,
385 system_config_dirs[i]))
386 break;
387
388 ++i;
389 }
390 }
391 }
392
393 static gboolean
394 gmenu_tree_canonicalize_path (GMenuTree *tree,
395 GError **error)
396 {
397 const char *menu_file = NULL;
398
399 if (tree->canonical)
400 return TRUE;
401
402 g_assert (tree->canonical_path == NULL);
403
404 gmenu_tree_remove_menu_file_monitors (tree);
405
406 if (tree->path)
407 {
408 menu_file = tree->path;
409 canonicalize_path (tree, tree->path);
410 }
411 else
412 {
413 const gchar *xdg_menu_prefix;
414
415 menu_file = tree->basename;
416 xdg_menu_prefix = g_getenv ("XDG_MENU_PREFIX");
417
418 if (xdg_menu_prefix != NULL)
419 {
420 gchar *prefixed_basename;
421
422 prefixed_basename = g_strdup_printf ("%sapplications.menu",
423 xdg_menu_prefix);
424
425 /* Some gnome-menus using applications just use "applications.menu"
426 * as the basename and expect gnome-menus to prefix it. Others (e.g.
427 * Alacarte) explicitly use "${XDG_MENU_PREFIX}applications.menu" as
428 * the basename, because they want to save changes to the right files
429 * in ~. In both cases, we want to use "applications-merged" as the
430 * merge directory (as required by the fd.o menu spec), so we save
431 * the non-prefixed basename and use it later when calling
432 * menu_layout_load().
433 */
434 if (!g_strcmp0 (tree->basename, "applications.menu") ||
435 !g_strcmp0 (tree->basename, prefixed_basename))
436 {
437 canonicalize_basename (tree, prefixed_basename);
438 g_free (tree->non_prefixed_basename);
439 tree->non_prefixed_basename = g_strdup ("applications.menu");
440 }
441 g_free (prefixed_basename);
442 }
443
444 if (!tree->canonical)
445 canonicalize_basename (tree, tree->basename);
446 }
447
448 if (tree->canonical)
449 {
450 menu_verbose ("Successfully looked up menu_file for \"%s\": %s\n",
451 menu_file, tree->canonical_path);
452 return TRUE;
453 }
454 else
455 {
456 g_set_error (error,
457 G_IO_ERROR,
458 G_IO_ERROR_FAILED,
459 "Failed to look up menu_file for \"%s\"\n",
460 menu_file);
461 return FALSE;
462 }
463 }
464
465 static void
466 gmenu_tree_force_recanonicalize (GMenuTree *tree)
467 {
468 gmenu_tree_remove_menu_file_monitors (tree);
469
470 if (tree->canonical)
471 {
472 gmenu_tree_force_reload (tree);
473
474 g_free (tree->canonical_path);
475 tree->canonical_path = NULL;
476
477 tree->canonical = FALSE;
478 }
479 }
480
481 /**
482 * gmenu_tree_new:
483 * @menu_basename: Basename of menu file
484 * @flags: Flags controlling menu content
485 *
486 * Returns: (transfer full): A new #GMenuTree instance
487 */
488 GMenuTree *
489 gmenu_tree_new (const char *menu_basename,
490 GMenuTreeFlags flags)
491 {
492 g_return_val_if_fail (menu_basename != NULL, NULL);
493
494 return g_object_new (GMENU_TYPE_TREE,
495 "menu-basename", menu_basename,
496 "flags", flags,
497 NULL);
498 }
499
500 /**
501 * gmenu_tree_new_fo_path:
502 * @menu_path: Path of menu file
503 * @flags: Flags controlling menu content
504 *
505 * Returns: (transfer full): A new #GMenuTree instance
506 */
507 GMenuTree *
508 gmenu_tree_new_for_path (const char *menu_path,
509 GMenuTreeFlags flags)
510 {
511 g_return_val_if_fail (menu_path != NULL, NULL);
512
513 return g_object_new (GMENU_TYPE_TREE,
514 "menu-path", menu_path,
515 "flags", flags,
516 NULL);
517 }
518
519 static GObject *
520 gmenu_tree_constructor (GType type,
521 guint n_construct_properties,
522 GObjectConstructParam *construct_properties)
523 {
524 GObject *obj;
525 GMenuTree *self;
526
527 obj = G_OBJECT_CLASS (gmenu_tree_parent_class)->constructor (type,
528 n_construct_properties,
529 construct_properties);
530
531 /* If GMenuTree:menu-path is set, then we should make sure that
532 * GMenuTree:menu-basename is unset (especially as it has a default
533 * value). This has to be done here, in the constructor, since the
534 * properties are construct-only. */
535
536 self = GMENU_TREE (obj);
537
538 if (self->path != NULL)
539 g_object_set (self, "menu-basename", NULL, NULL);
540
541 return obj;
542 }
543
544 static void
545 gmenu_tree_set_property (GObject *object,
546 guint prop_id,
547 const GValue *value,
548 GParamSpec *pspec)
549 {
550 GMenuTree *self = GMENU_TREE (object);
551
552 switch (prop_id)
553 {
554 case PROP_MENU_BASENAME:
555 self->basename = g_value_dup_string (value);
556 break;
557
558 case PROP_MENU_PATH:
559 self->path = g_value_dup_string (value);
560 break;
561
562 case PROP_FLAGS:
563 self->flags = g_value_get_flags (value);
564 break;
565
566 default:
567 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
568 break;
569 }
570 }
571
572 static void
573 gmenu_tree_get_property (GObject *object,
574 guint prop_id,
575 GValue *value,
576 GParamSpec *pspec)
577 {
578 GMenuTree *self = GMENU_TREE (object);
579
580 switch (prop_id)
581 {
582 case PROP_MENU_BASENAME:
583 g_value_set_string (value, self->basename);
584 break;
585 case PROP_MENU_PATH:
586 g_value_set_string (value, self->path);
587 break;
588 case PROP_FLAGS:
589 g_value_set_flags (value, self->flags);
590 break;
591 default:
592 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
593 break;
594 }
595 }
596
597 static void
598 gmenu_tree_finalize (GObject *object)
599 {
600 GMenuTree *tree = GMENU_TREE (object);
601
602 gmenu_tree_force_recanonicalize (tree);
603
604 if (tree->basename != NULL)
605 g_free (tree->basename);
606 tree->basename = NULL;
607
608 g_free (tree->non_prefixed_basename);
609 tree->non_prefixed_basename = NULL;
610
611 if (tree->path != NULL)
612 g_free (tree->path);
613 tree->path = NULL;
614
615 if (tree->canonical_path != NULL)
616 g_free (tree->canonical_path);
617 tree->canonical_path = NULL;
618
619 g_hash_table_destroy (tree->entries_by_id);
620 tree->entries_by_id = NULL;
621
622 G_OBJECT_CLASS (gmenu_tree_parent_class)->finalize (object);
623 }
624
625 static void
626 gmenu_tree_init (GMenuTree *self)
627 {
628 self->entries_by_id = g_hash_table_new (g_str_hash, g_str_equal);
629 }
630
631 static void
632 gmenu_tree_class_init (GMenuTreeClass *klass)
633 {
634 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
635
636 gobject_class->constructor = gmenu_tree_constructor;
637 gobject_class->get_property = gmenu_tree_get_property;
638 gobject_class->set_property = gmenu_tree_set_property;
639 gobject_class->finalize = gmenu_tree_finalize;
640
641 /**
642 * GMenuTree:menu-basename:
643 *
644 * The name of the menu file; must be a basename or a relative path. The file
645 * will be looked up in $XDG_CONFIG_DIRS/menus/. See the Desktop Menu
646 * specification.
647 */
648 g_object_class_install_property (gobject_class,
649 PROP_MENU_BASENAME,
650 g_param_spec_string ("menu-basename", "", "",
651 "applications.menu",
652 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
653 /**
654 * GMenuTree:menu-path:
655 *
656 * The full path of the menu file. If set, GMenuTree:menu-basename will get
657 * ignored.
658 */
659 g_object_class_install_property (gobject_class,
660 PROP_MENU_PATH,
661 g_param_spec_string ("menu-path", "", "",
662 NULL,
663 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
664 /**
665 * GMenuTree:flags:
666 *
667 * Flags controlling the content of the menu.
668 */
669 g_object_class_install_property (gobject_class,
670 PROP_FLAGS,
671 g_param_spec_flags ("flags", "", "",
672 GMENU_TYPE_TREE_FLAGS,
673 GMENU_TREE_FLAGS_NONE,
674 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
675
676 /**
677 * GMenuTree:changed:
678 *
679 * This signal is emitted when applications are added, removed, or
680 * upgraded. But note the new data will only be visible after
681 * gmenu_tree_load_sync() or a variant thereof is invoked.
682 */
683 gmenu_tree_signals[CHANGED] =
684 g_signal_new ("changed",
685 G_TYPE_FROM_CLASS (klass),
686 G_SIGNAL_RUN_LAST,
687 0,
688 NULL, NULL,
689 g_cclosure_marshal_VOID__VOID,
690 G_TYPE_NONE, 0);
691 }
692
693 /**
694 * gmenu_tree_get_canonical_menu_path:
695 * @tree: a #GMenuTree
696 *
697 * This function is only available if the tree has been loaded via
698 * gmenu_tree_load_sync() or a variant thereof.
699 *
700 * Returns: The absolute and canonicalized path to the loaded menu file
701 */
702 const char *
703 gmenu_tree_get_canonical_menu_path (GMenuTree *tree)
704 {
705 g_return_val_if_fail (GMENU_IS_TREE (tree), NULL);
706 g_return_val_if_fail (tree->loaded, NULL);
707
708 return tree->canonical_path;
709 }
710
711 /**
712 * gmenu_tree_load_sync:
713 * @tree: a #GMenuTree
714 * @error: a #GError
715 *
716 * Synchronously load the menu contents. This function
717 * performs a significant amount of blocking I/O if the
718 * tree has not been loaded yet.
719 *
720 * Returns: %TRUE on success, %FALSE on error
721 */
722 gboolean
723 gmenu_tree_load_sync (GMenuTree *tree,
724 GError **error)
725 {
726 GError *local_error = NULL;
727
728 if (tree->loaded)
729 return TRUE;
730
731 if (!gmenu_tree_build_from_layout (tree, &local_error))
732 {
733 if (local_error)
734 g_propagate_error (error, local_error);
735 return FALSE;
736 }
737
738 tree->loaded = TRUE;
739
740 return TRUE;
741 }
742
743 /**
744 * gmenu_tree_get_root_directory:
745 * @tree: a #GMenuTree
746 *
747 * Get the root directory; you must have loaded the tree first (at
748 * least once) via gmenu_tree_load_sync() or a variant thereof.
749 *
750 * Returns: (transfer full): Root of the tree
751 */
752 GMenuTreeDirectory *
753 gmenu_tree_get_root_directory (GMenuTree *tree)
754 {
755 g_return_val_if_fail (tree != NULL, NULL);
756 g_return_val_if_fail (tree->loaded, NULL);
757
758 return gmenu_tree_item_ref (tree->root);
759 }
760
761 static GMenuTreeDirectory *
762 find_path (GMenuTreeDirectory *directory,
763 const char *path)
764 {
765 const char *name;
766 char *slash;
767 char *freeme;
768 GSList *tmp;
769
770 while (path[0] == G_DIR_SEPARATOR) path++;
771
772 if (path[0] == '\0')
773 return directory;
774
775 freeme = NULL;
776 slash = strchr (path, G_DIR_SEPARATOR);
777 if (slash)
778 {
779 name = freeme = g_strndup (path, slash - path);
780 path = slash + 1;
781 }
782 else
783 {
784 name = path;
785 path = NULL;
786 }
787
788 tmp = directory->contents;
789 while (tmp != NULL)
790 {
791 GMenuTreeItem *item = tmp->data;
792
793 if (item->type != GMENU_TREE_ITEM_DIRECTORY)
794 {
795 tmp = tmp->next;
796 continue;
797 }
798
799 if (!strcmp (name, GMENU_TREE_DIRECTORY (item)->name))
800 {
801 g_free (freeme);
802
803 if (path)
804 return find_path (GMENU_TREE_DIRECTORY (item), path);
805 else
806 return GMENU_TREE_DIRECTORY (item);
807 }
808
809 tmp = tmp->next;
810 }
811
812 g_free (freeme);
813
814 return NULL;
815 }
816
817 GMenuTreeDirectory *
818 gmenu_tree_get_directory_from_path (GMenuTree *tree,
819 const char *path)
820 {
821 GMenuTreeDirectory *root;
822 GMenuTreeDirectory *directory;
823
824 g_return_val_if_fail (tree != NULL, NULL);
825 g_return_val_if_fail (path != NULL, NULL);
826
827 if (path[0] != G_DIR_SEPARATOR)
828 return NULL;
829
830 if (!(root = gmenu_tree_get_root_directory (tree)))
831 return NULL;
832
833 directory = find_path (root, path);
834
835 gmenu_tree_item_unref (root);
836
837 return directory ? gmenu_tree_item_ref (directory) : NULL;
838 }
839
840 /**
841 * gmenu_tree_get_entry_by_id:
842 * @tree: a #GMenuTree
843 * @id: a desktop file ID
844 *
845 * Look up the entry corresponding to the given "desktop file id".
846 *
847 * Returns: (transfer full): A newly referenced #GMenuTreeEntry, or %NULL if none
848 */
849 GMenuTreeEntry *
850 gmenu_tree_get_entry_by_id (GMenuTree *tree,
851 const char *id)
852 {
853 GMenuTreeEntry *entry;
854
855 g_return_val_if_fail (tree->loaded, NULL);
856
857 entry = g_hash_table_lookup (tree->entries_by_id, id);
858 if (entry != NULL)
859 gmenu_tree_item_ref (entry);
860
861 return entry;
862 }
863
864 static void
865 gmenu_tree_invoke_monitors (GMenuTree *tree)
866 {
867 g_signal_emit (tree, gmenu_tree_signals[CHANGED], 0);
868 }
869
870 static GMenuTreeDirectory *
871 get_parent (GMenuTreeItem *item)
872 {
873 g_return_val_if_fail (item != NULL, NULL);
874 return item->parent ? gmenu_tree_item_ref (item->parent) : NULL;
875 }
876
877 /**
878 * gmenu_tree_directory_get_parent:
879 * @directory: a #GMenuTreeDirectory
880 *
881 * Returns: (transfer full): The parent directory, or %NULL if none
882 */
883 GMenuTreeDirectory *
884 gmenu_tree_directory_get_parent (GMenuTreeDirectory *directory)
885 {
886 return get_parent ((GMenuTreeItem *)directory);
887 }
888
889 /**
890 * gmenu_tree_entry_get_parent:
891 * @entry: a #GMenuTreeEntry
892 *
893 * Returns: (transfer full): The parent directory, or %NULL if none
894 */
895 GMenuTreeDirectory *
896 gmenu_tree_entry_get_parent (GMenuTreeEntry *entry)
897 {
898 return get_parent ((GMenuTreeItem *)entry);
899 }
900
901 /**
902 * gmenu_tree_alias_get_parent:
903 * @alias: a #GMenuTreeAlias
904 *
905 * Returns: (transfer full): The parent directory, or %NULL if none
906 */
907 GMenuTreeDirectory *
908 gmenu_tree_alias_get_parent (GMenuTreeAlias *alias)
909 {
910 return get_parent ((GMenuTreeItem *)alias);
911 }
912
913 /**
914 * gmenu_tree_header_get_parent:
915 * @header: a #GMenuTreeHeader
916 *
917 * Returns: (transfer full): The parent directory, or %NULL if none
918 */
919 GMenuTreeDirectory *
920 gmenu_tree_header_get_parent (GMenuTreeHeader *header)
921 {
922 return get_parent ((GMenuTreeItem *)header);
923 }
924
925 /**
926 * gmenu_tree_separator_get_parent:
927 * @separator: a #GMenuTreeSeparator
928 *
929 * Returns: (transfer full): The parent directory, or %NULL if none
930 */
931 GMenuTreeDirectory *
932 gmenu_tree_separator_get_parent (GMenuTreeSeparator *separator)
933 {
934 return get_parent ((GMenuTreeItem *)separator);
935 }
936
937 static void
938 gmenu_tree_item_set_parent (GMenuTreeItem *item,
939 GMenuTreeDirectory *parent)
940 {
941 g_return_if_fail (item != NULL);
942
943 item->parent = parent;
944 }
945
946 /**
947 * gmenu_tree_iter_ref: (skip)
948 * @iter: iter
949 *
950 * Increment the reference count of @iter
951 */
952 GMenuTreeIter *
953 gmenu_tree_iter_ref (GMenuTreeIter *iter)
954 {
955 g_atomic_int_inc (&iter->refcount);
956 return iter;
957 }
958
959 /**
960 * gmenu_tree_iter_unref: (skip)
961 * @iter: iter
962 *
963 * Decrement the reference count of @iter
964 */
965 void
966 gmenu_tree_iter_unref (GMenuTreeIter *iter)
967 {
968 if (!g_atomic_int_dec_and_test (&iter->refcount))
969 return;
970
971 g_slist_foreach (iter->contents, (GFunc)gmenu_tree_item_unref, NULL);
972 g_slist_free (iter->contents);
973
974 g_slice_free (GMenuTreeIter, iter);
975 }
976
977 /**
978 * gmenu_tree_directory_iter:
979 * @directory: directory
980 *
981 * Returns: (transfer full): A new iterator over the directory contents
982 */
983 GMenuTreeIter *
984 gmenu_tree_directory_iter (GMenuTreeDirectory *directory)
985 {
986 GMenuTreeIter *iter;
987
988 g_return_val_if_fail (directory != NULL, NULL);
989
990 iter = g_slice_new0 (GMenuTreeIter);
991 iter->refcount = 1;
992
993 iter->contents = g_slist_copy (directory->contents);
994 iter->contents_iter = iter->contents;
995 g_slist_foreach (iter->contents, (GFunc) gmenu_tree_item_ref, NULL);
996
997 return iter;
998 }
999
1000 /**
1001 * gmenu_tree_iter_next:
1002 * @iter: iter
1003 *
1004 * Change the iterator to the next item, and return its type. If
1005 * there are no more items, %GMENU_TREE_ITEM_INVALID is returned.
1006 *
1007 * Returns: The type of the next item that can be retrived from the iterator
1008 */
1009 GMenuTreeItemType
1010 gmenu_tree_iter_next (GMenuTreeIter *iter)
1011 {
1012 g_return_val_if_fail (iter != NULL, GMENU_TREE_ITEM_INVALID);
1013
1014 if (iter->contents_iter)
1015 {
1016 iter->item = iter->contents_iter->data;
1017 iter->contents_iter = iter->contents_iter->next;
1018 return iter->item->type;
1019 }
1020 else
1021 return GMENU_TREE_ITEM_INVALID;
1022 }
1023
1024 /**
1025 * gmenu_tree_iter_get_directory:
1026 * @iter: iter
1027 *
1028 * This method may only be called if gmenu_tree_iter_next()
1029 * returned GMENU_TREE_ITEM_DIRECTORY.
1030 *
1031 * Returns: (transfer full): A directory
1032 */
1033 GMenuTreeDirectory *
1034 gmenu_tree_iter_get_directory (GMenuTreeIter *iter)
1035 {
1036 g_return_val_if_fail (iter != NULL, NULL);
1037 g_return_val_if_fail (iter->item != NULL, NULL);
1038 g_return_val_if_fail (iter->item->type == GMENU_TREE_ITEM_DIRECTORY, NULL);
1039
1040 return (GMenuTreeDirectory*)gmenu_tree_item_ref (iter->item);
1041 }
1042
1043 /**
1044 * gmenu_tree_iter_get_entry:
1045 * @iter: iter
1046 *
1047 * This method may only be called if gmenu_tree_iter_next()
1048 * returned GMENU_TREE_ITEM_ENTRY.
1049 *
1050 * Returns: (transfer full): An entry
1051 */
1052 GMenuTreeEntry *
1053 gmenu_tree_iter_get_entry (GMenuTreeIter *iter)
1054 {
1055 g_return_val_if_fail (iter != NULL, NULL);
1056 g_return_val_if_fail (iter->item != NULL, NULL);
1057 g_return_val_if_fail (iter->item->type == GMENU_TREE_ITEM_ENTRY, NULL);
1058
1059 return (GMenuTreeEntry*)gmenu_tree_item_ref (iter->item);
1060 }
1061
1062 /**
1063 * gmenu_tree_iter_get_header:
1064 * @iter: iter
1065 *
1066 * This method may only be called if gmenu_tree_iter_next()
1067 * returned GMENU_TREE_ITEM_HEADER.
1068 *
1069 * Returns: (transfer full): A header
1070 */
1071 GMenuTreeHeader *
1072 gmenu_tree_iter_get_header (GMenuTreeIter *iter)
1073 {
1074 g_return_val_if_fail (iter != NULL, NULL);
1075 g_return_val_if_fail (iter->item != NULL, NULL);
1076 g_return_val_if_fail (iter->item->type == GMENU_TREE_ITEM_HEADER, NULL);
1077
1078 return (GMenuTreeHeader*)gmenu_tree_item_ref (iter->item);
1079 }
1080
1081 /**
1082 * gmenu_tree_iter_get_alias:
1083 * @iter: iter
1084 *
1085 * This method may only be called if gmenu_tree_iter_next()
1086 * returned GMENU_TREE_ITEM_ALIAS.
1087 *
1088 * Returns: (transfer full): An alias
1089 */
1090 GMenuTreeAlias *
1091 gmenu_tree_iter_get_alias (GMenuTreeIter *iter)
1092 {
1093 g_return_val_if_fail (iter != NULL, NULL);
1094 g_return_val_if_fail (iter->item != NULL, NULL);
1095 g_return_val_if_fail (iter->item->type == GMENU_TREE_ITEM_ALIAS, NULL);
1096
1097 return (GMenuTreeAlias*)gmenu_tree_item_ref (iter->item);
1098 }
1099
1100 /**
1101 * gmenu_tree_iter_get_separator:
1102 * @iter: iter
1103 *
1104 * This method may only be called if gmenu_tree_iter_next()
1105 * returned #GMENU_TREE_ITEM_SEPARATOR.
1106 *
1107 * Returns: (transfer full): A separator
1108 */
1109 GMenuTreeSeparator *
1110 gmenu_tree_iter_get_separator (GMenuTreeIter *iter)
1111 {
1112 g_return_val_if_fail (iter != NULL, NULL);
1113 g_return_val_if_fail (iter->item != NULL, NULL);
1114 g_return_val_if_fail (iter->item->type == GMENU_TREE_ITEM_SEPARATOR, NULL);
1115
1116 return (GMenuTreeSeparator*)gmenu_tree_item_ref (iter->item);
1117 }
1118
1119 const char *
1120 gmenu_tree_directory_get_name (GMenuTreeDirectory *directory)
1121 {
1122 g_return_val_if_fail (directory != NULL, NULL);
1123
1124 if (!directory->directory_entry)
1125 return directory->name;
1126
1127 return desktop_entry_get_name (directory->directory_entry);
1128 }
1129
1130 const char *
1131 gmenu_tree_directory_get_generic_name (GMenuTreeDirectory *directory)
1132 {
1133 g_return_val_if_fail (directory != NULL, NULL);
1134
1135 if (!directory->directory_entry)
1136 return NULL;
1137
1138 return desktop_entry_get_generic_name (directory->directory_entry);
1139 }
1140
1141 const char *
1142 gmenu_tree_directory_get_comment (GMenuTreeDirectory *directory)
1143 {
1144 g_return_val_if_fail (directory != NULL, NULL);
1145
1146 if (!directory->directory_entry)
1147 return NULL;
1148
1149 return desktop_entry_get_comment (directory->directory_entry);
1150 }
1151
1152 /**
1153 * gmenu_tree_directory_get_icon:
1154 * @directory: a #GMenuTreeDirectory
1155 *
1156 * Gets the icon for the directory.
1157 *
1158 * Returns: (transfer none): The #GIcon for this directory
1159 */
1160 GIcon *
1161 gmenu_tree_directory_get_icon (GMenuTreeDirectory *directory)
1162 {
1163 g_return_val_if_fail (directory != NULL, NULL);
1164
1165 if (!directory->directory_entry)
1166 return NULL;
1167
1168 return desktop_entry_get_icon (directory->directory_entry);
1169 }
1170
1171 const char *
1172 gmenu_tree_directory_get_desktop_file_path (GMenuTreeDirectory *directory)
1173 {
1174 g_return_val_if_fail (directory != NULL, NULL);
1175
1176 if (!directory->directory_entry)
1177 return NULL;
1178
1179 return desktop_entry_get_path (directory->directory_entry);
1180 }
1181
1182 const char *
1183 gmenu_tree_directory_get_menu_id (GMenuTreeDirectory *directory)
1184 {
1185 g_return_val_if_fail (directory != NULL, NULL);
1186
1187 return directory->name;
1188 }
1189
1190 gboolean
1191 gmenu_tree_directory_get_is_nodisplay (GMenuTreeDirectory *directory)
1192 {
1193 g_return_val_if_fail (directory != NULL, FALSE);
1194
1195 return directory->is_nodisplay;
1196 }
1197
1198 /**
1199 * gmenu_tree_directory_get_tree:
1200 * @directory: A #GMenuTreeDirectory
1201 *
1202 * Grab the tree associated with a #GMenuTreeItem.
1203 *
1204 * Returns: (transfer full): The #GMenuTree
1205 */
1206 GMenuTree *
1207 gmenu_tree_directory_get_tree (GMenuTreeDirectory *directory)
1208 {
1209 g_return_val_if_fail (directory != NULL, NULL);
1210
1211 return g_object_ref (directory->item.tree);
1212 }
1213
1214 static void
1215 append_directory_path (GMenuTreeDirectory *directory,
1216 GString *path)
1217 {
1218
1219 if (!directory->item.parent)
1220 {
1221 g_string_append_c (path, G_DIR_SEPARATOR);
1222 return;
1223 }
1224
1225 append_directory_path (directory->item.parent, path);
1226
1227 g_string_append (path, directory->name);
1228 g_string_append_c (path, G_DIR_SEPARATOR);
1229 }
1230
1231 char *
1232 gmenu_tree_directory_make_path (GMenuTreeDirectory *directory,
1233 GMenuTreeEntry *entry)
1234 {
1235 GString *path;
1236
1237 g_return_val_if_fail (directory != NULL, NULL);
1238
1239 path = g_string_new (NULL);
1240
1241 append_directory_path (directory, path);
1242
1243 if (entry != NULL)
1244 {
1245 const char *basename;
1246
1247 basename = desktop_entry_get_basename (entry->desktop_entry);
1248 g_string_append (path, basename);
1249 }
1250
1251 return g_string_free (path, FALSE);
1252 }
1253
1254 /**
1255 * gmenu_tree_entry_get_app_info:
1256 * @entry: a #GMenuTreeEntry
1257 *
1258 * Returns: (transfer none): The #GDesktopAppInfo for this entry
1259 */
1260 GDesktopAppInfo *
1261 gmenu_tree_entry_get_app_info (GMenuTreeEntry *entry)
1262 {
1263 g_return_val_if_fail (entry != NULL, NULL);
1264
1265 return desktop_entry_get_app_info (entry->desktop_entry);
1266 }
1267
1268 const char *
1269 gmenu_tree_entry_get_desktop_file_path (GMenuTreeEntry *entry)
1270 {
1271 g_return_val_if_fail (entry != NULL, NULL);
1272
1273 return desktop_entry_get_path (entry->desktop_entry);
1274 }
1275
1276 const char *
1277 gmenu_tree_entry_get_desktop_file_id (GMenuTreeEntry *entry)
1278 {
1279 g_return_val_if_fail (entry != NULL, FALSE);
1280
1281 return entry->desktop_file_id;
1282 }
1283
1284 gboolean
1285 gmenu_tree_entry_get_is_nodisplay_recurse (GMenuTreeEntry *entry)
1286 {
1287 GMenuTreeDirectory *directory;
1288 GDesktopAppInfo *app_info;
1289
1290 g_return_val_if_fail (entry != NULL, FALSE);
1291
1292 app_info = gmenu_tree_entry_get_app_info (entry);
1293
1294 if (g_desktop_app_info_get_nodisplay (app_info))
1295 return TRUE;
1296
1297 directory = entry->item.parent;
1298 while (directory != NULL)
1299 {
1300 if (directory->is_nodisplay)
1301 return TRUE;
1302
1303 directory = directory->item.parent;
1304 }
1305
1306 return FALSE;
1307 }
1308
1309 gboolean
1310 gmenu_tree_entry_get_is_excluded (GMenuTreeEntry *entry)
1311 {
1312 g_return_val_if_fail (entry != NULL, FALSE);
1313
1314 return entry->is_excluded;
1315 }
1316
1317 gboolean
1318 gmenu_tree_entry_get_is_unallocated (GMenuTreeEntry *entry)
1319 {
1320 g_return_val_if_fail (entry != NULL, FALSE);
1321
1322 return entry->is_unallocated;
1323 }
1324
1325 /**
1326 * gmenu_tree_entry_get_tree:
1327 * @entry: A #GMenuTreeEntry
1328 *
1329 * Grab the tree associated with a #GMenuTreeEntry.
1330 *
1331 * Returns: (transfer full): The #GMenuTree
1332 */
1333 GMenuTree *
1334 gmenu_tree_entry_get_tree (GMenuTreeEntry *entry)
1335 {
1336 g_return_val_if_fail (entry != NULL, NULL);
1337
1338 return g_object_ref (entry->item.tree);
1339 }
1340
1341 GMenuTreeDirectory *
1342 gmenu_tree_header_get_directory (GMenuTreeHeader *header)
1343 {
1344 g_return_val_if_fail (header != NULL, NULL);
1345
1346 return gmenu_tree_item_ref (header->directory);
1347 }
1348
1349 /**
1350 * gmenu_tree_header_get_tree:
1351 * @header: A #GMenuTreeHeader
1352 *
1353 * Grab the tree associated with a #GMenuTreeHeader.
1354 *
1355 * Returns: (transfer full): The #GMenuTree
1356 */
1357 GMenuTree *
1358 gmenu_tree_header_get_tree (GMenuTreeHeader *header)
1359 {
1360 g_return_val_if_fail (header != NULL, NULL);
1361
1362 return g_object_ref (header->item.tree);
1363 }
1364
1365 GMenuTreeItemType
1366 gmenu_tree_alias_get_aliased_item_type (GMenuTreeAlias *alias)
1367 {
1368 g_return_val_if_fail (alias != NULL, GMENU_TREE_ITEM_INVALID);
1369
1370 g_assert (alias->aliased_item != NULL);
1371 return alias->aliased_item->type;
1372 }
1373
1374 GMenuTreeDirectory *
1375 gmenu_tree_alias_get_directory (GMenuTreeAlias *alias)
1376 {
1377 g_return_val_if_fail (alias != NULL, NULL);
1378
1379 return gmenu_tree_item_ref (alias->directory);
1380 }
1381
1382 /**
1383 * gmenu_tree_alias_get_tree:
1384 * @alias: A #GMenuTreeAlias
1385 *
1386 * Grab the tree associated with a #GMenuTreeAlias.
1387 *
1388 * Returns: (transfer full): The #GMenuTree
1389 */
1390 GMenuTree *
1391 gmenu_tree_alias_get_tree (GMenuTreeAlias *alias)
1392 {
1393 g_return_val_if_fail (alias != NULL, NULL);
1394
1395 return g_object_ref (alias->item.tree);
1396 }
1397
1398 /**
1399 * gmenu_tree_separator_get_tree:
1400 * @separator: A #GMenuTreeSeparator
1401 *
1402 * Grab the tree associated with a #GMenuTreeSeparator.
1403 *
1404 * Returns: (transfer full): The #GMenuTree
1405 */
1406 GMenuTree *
1407 gmenu_tree_separator_get_tree (GMenuTreeSeparator *separator)
1408 {
1409 g_return_val_if_fail (separator != NULL, NULL);
1410
1411 return g_object_ref (separator->item.tree);
1412 }
1413
1414 /**
1415 * gmenu_tree_alias_get_aliased_directory:
1416 * @alias: alias
1417 *
1418 * Returns: (transfer full): The aliased directory entry
1419 */
1420 GMenuTreeDirectory *
1421 gmenu_tree_alias_get_aliased_directory (GMenuTreeAlias *alias)
1422 {
1423 g_return_val_if_fail (alias != NULL, NULL);
1424 g_return_val_if_fail (alias->aliased_item->type == GMENU_TREE_ITEM_DIRECTORY, NULL);
1425
1426 return (GMenuTreeDirectory *) gmenu_tree_item_ref (alias->aliased_item);
1427 }
1428
1429 /**
1430 * gmenu_tree_alias_get_aliased_entry:
1431 * @alias: alias
1432 *
1433 * Returns: (transfer full): The aliased entry
1434 */
1435 GMenuTreeEntry *
1436 gmenu_tree_alias_get_aliased_entry (GMenuTreeAlias *alias)
1437 {
1438 g_return_val_if_fail (alias != NULL, NULL);
1439 g_return_val_if_fail (alias->aliased_item->type == GMENU_TREE_ITEM_ENTRY, NULL);
1440
1441 return (GMenuTreeEntry *) gmenu_tree_item_ref (alias->aliased_item);
1442 }
1443
1444 static GMenuTreeDirectory *
1445 gmenu_tree_directory_new (GMenuTree *tree,
1446 GMenuTreeDirectory *parent,
1447 const char *name)
1448 {
1449 GMenuTreeDirectory *retval;
1450
1451 retval = g_slice_new0 (GMenuTreeDirectory);
1452
1453 retval->item.type = GMENU_TREE_ITEM_DIRECTORY;
1454 retval->item.parent = parent;
1455 retval->item.refcount = 1;
1456 retval->item.tree = tree;
1457
1458 retval->name = g_strdup (name);
1459 retval->directory_entry = NULL;
1460 retval->entries = NULL;
1461 retval->subdirs = NULL;
1462 retval->default_layout_info = NULL;
1463 retval->layout_info = NULL;
1464 retval->contents = NULL;
1465 retval->only_unallocated = FALSE;
1466 retval->is_nodisplay = FALSE;
1467 retval->layout_pending_separator = FALSE;
1468 retval->preprocessed = FALSE;
1469 retval->will_inline_header = G_MAXUINT16;
1470
1471 retval->default_layout_values.mask = MENU_LAYOUT_VALUES_NONE;
1472 retval->default_layout_values.show_empty = FALSE;
1473 retval->default_layout_values.inline_menus = FALSE;
1474 retval->default_layout_values.inline_limit = 4;
1475 retval->default_layout_values.inline_header = FALSE;
1476 retval->default_layout_values.inline_alias = FALSE;
1477
1478 return retval;
1479 }
1480
1481 static void
1482 gmenu_tree_directory_finalize (GMenuTreeDirectory *directory)
1483 {
1484 g_assert (directory->item.refcount == 0);
1485
1486 g_slist_foreach (directory->contents,
1487 (GFunc) gmenu_tree_item_unref_and_unset_parent,
1488 NULL);
1489 g_slist_free (directory->contents);
1490 directory->contents = NULL;
1491
1492 g_slist_foreach (directory->default_layout_info,
1493 (GFunc) menu_layout_node_unref,
1494 NULL);
1495 g_slist_free (directory->default_layout_info);
1496 directory->default_layout_info = NULL;
1497
1498 g_slist_foreach (directory->layout_info,
1499 (GFunc) menu_layout_node_unref,
1500 NULL);
1501 g_slist_free (directory->layout_info);
1502 directory->layout_info = NULL;
1503
1504 g_slist_foreach (directory->subdirs,
1505 (GFunc) gmenu_tree_item_unref_and_unset_parent,
1506 NULL);
1507 g_slist_free (directory->subdirs);
1508 directory->subdirs = NULL;
1509
1510 g_slist_foreach (directory->entries,
1511 (GFunc) gmenu_tree_item_unref_and_unset_parent,
1512 NULL);
1513 g_slist_free (directory->entries);
1514 directory->entries = NULL;
1515
1516 if (directory->directory_entry)
1517 desktop_entry_unref (directory->directory_entry);
1518 directory->directory_entry = NULL;
1519
1520 g_free (directory->name);
1521 directory->name = NULL;
1522
1523 g_slice_free (GMenuTreeDirectory, directory);
1524 }
1525
1526 static GMenuTreeSeparator *
1527 gmenu_tree_separator_new (GMenuTreeDirectory *parent)
1528 {
1529 GMenuTreeSeparator *retval;
1530
1531 retval = g_slice_new0 (GMenuTreeSeparator);
1532
1533 retval->item.type = GMENU_TREE_ITEM_SEPARATOR;
1534 retval->item.parent = parent;
1535 retval->item.refcount = 1;
1536 retval->item.tree = parent->item.tree;
1537
1538 return retval;
1539 }
1540
1541 static void
1542 gmenu_tree_separator_finalize (GMenuTreeSeparator *separator)
1543 {
1544 g_assert (separator->item.refcount == 0);
1545
1546 g_slice_free (GMenuTreeSeparator, separator);
1547 }
1548
1549 static GMenuTreeHeader *
1550 gmenu_tree_header_new (GMenuTreeDirectory *parent,
1551 GMenuTreeDirectory *directory)
1552 {
1553 GMenuTreeHeader *retval;
1554
1555 retval = g_slice_new0 (GMenuTreeHeader);
1556
1557 retval->item.type = GMENU_TREE_ITEM_HEADER;
1558 retval->item.parent = parent;
1559 retval->item.refcount = 1;
1560 retval->item.tree = parent->item.tree;
1561
1562 retval->directory = gmenu_tree_item_ref (directory);
1563
1564 gmenu_tree_item_set_parent (GMENU_TREE_ITEM (retval->directory), NULL);
1565
1566 return retval;
1567 }
1568
1569 static void
1570 gmenu_tree_header_finalize (GMenuTreeHeader *header)
1571 {
1572 g_assert (header->item.refcount == 0);
1573
1574 if (header->directory != NULL)
1575 gmenu_tree_item_unref (header->directory);
1576 header->directory = NULL;
1577
1578 g_slice_free (GMenuTreeHeader, header);
1579 }
1580
1581 static GMenuTreeAlias *
1582 gmenu_tree_alias_new (GMenuTreeDirectory *parent,
1583 GMenuTreeDirectory *directory,
1584 GMenuTreeItem *item)
1585 {
1586 GMenuTreeAlias *retval;
1587
1588 retval = g_slice_new0 (GMenuTreeAlias);
1589
1590 retval->item.type = GMENU_TREE_ITEM_ALIAS;
1591 retval->item.parent = parent;
1592 retval->item.refcount = 1;
1593 retval->item.tree = parent->item.tree;
1594
1595 retval->directory = gmenu_tree_item_ref (directory);
1596 if (item->type != GMENU_TREE_ITEM_ALIAS)
1597 retval->aliased_item = gmenu_tree_item_ref (item);
1598 else
1599 {
1600 GMenuTreeAlias *alias = GMENU_TREE_ALIAS (item);
1601 retval->aliased_item = gmenu_tree_item_ref (alias->aliased_item);
1602 }
1603
1604 gmenu_tree_item_set_parent (GMENU_TREE_ITEM (retval->directory), NULL);
1605 gmenu_tree_item_set_parent (retval->aliased_item, NULL);
1606
1607 return retval;
1608 }
1609
1610 static void
1611 gmenu_tree_alias_finalize (GMenuTreeAlias *alias)
1612 {
1613 g_assert (alias->item.refcount == 0);
1614
1615 if (alias->directory != NULL)
1616 gmenu_tree_item_unref (alias->directory);
1617 alias->directory = NULL;
1618
1619 if (alias->aliased_item != NULL)
1620 gmenu_tree_item_unref (alias->aliased_item);
1621 alias->aliased_item = NULL;
1622
1623 g_slice_free (GMenuTreeAlias, alias);
1624 }
1625
1626 static GMenuTreeEntry *
1627 gmenu_tree_entry_new (GMenuTreeDirectory *parent,
1628 DesktopEntry *desktop_entry,
1629 const char *desktop_file_id,
1630 gboolean is_excluded,
1631 gboolean is_unallocated)
1632 {
1633 GMenuTreeEntry *retval;
1634
1635 retval = g_slice_new0 (GMenuTreeEntry);
1636
1637 retval->item.type = GMENU_TREE_ITEM_ENTRY;
1638 retval->item.parent = parent;
1639 retval->item.refcount = 1;
1640 retval->item.tree = parent->item.tree;
1641
1642 retval->desktop_entry = desktop_entry_ref (desktop_entry);
1643 retval->desktop_file_id = g_strdup (desktop_file_id);
1644 retval->is_excluded = is_excluded != FALSE;
1645 retval->is_unallocated = is_unallocated != FALSE;
1646
1647 return retval;
1648 }
1649
1650 static void
1651 gmenu_tree_entry_finalize (GMenuTreeEntry *entry)
1652 {
1653 g_assert (entry->item.refcount == 0);
1654
1655 g_free (entry->desktop_file_id);
1656 entry->desktop_file_id = NULL;
1657
1658 if (entry->desktop_entry)
1659 desktop_entry_unref (entry->desktop_entry);
1660 entry->desktop_entry = NULL;
1661
1662 g_slice_free (GMenuTreeEntry, entry);
1663 }
1664
1665 static int
1666 gmenu_tree_entry_compare_by_id (GMenuTreeItem *a,
1667 GMenuTreeItem *b)
1668 {
1669 if (a->type == GMENU_TREE_ITEM_ALIAS)
1670 a = GMENU_TREE_ALIAS (a)->aliased_item;
1671
1672 if (b->type == GMENU_TREE_ITEM_ALIAS)
1673 b = GMENU_TREE_ALIAS (b)->aliased_item;
1674
1675 return strcmp (GMENU_TREE_ENTRY (a)->desktop_file_id,
1676 GMENU_TREE_ENTRY (b)->desktop_file_id);
1677 }
1678
1679 /**
1680 * gmenu_tree_item_ref:
1681 * @item: a #GMenuTreeItem
1682 *
1683 * Returns: (transfer full): The same @item, or %NULL if @item is not a valid #GMenuTreeItem
1684 */
1685 gpointer
1686 gmenu_tree_item_ref (gpointer itemp)
1687 {
1688 GMenuTreeItem *item;
1689
1690 item = (GMenuTreeItem *) itemp;
1691
1692 g_return_val_if_fail (item != NULL, NULL);
1693 g_return_val_if_fail (item->refcount > 0, NULL);
1694
1695 g_atomic_int_inc (&item->refcount);
1696
1697 return item;
1698 }
1699
1700 void
1701 gmenu_tree_item_unref (gpointer itemp)
1702 {
1703 GMenuTreeItem *item;
1704
1705 item = (GMenuTreeItem *) itemp;
1706
1707 g_return_if_fail (item != NULL);
1708 g_return_if_fail (item->refcount > 0);
1709
1710 if (g_atomic_int_dec_and_test (&(item->refcount)))
1711 {
1712 switch (item->type)
1713 {
1714 case GMENU_TREE_ITEM_DIRECTORY:
1715 gmenu_tree_directory_finalize (GMENU_TREE_DIRECTORY (item));
1716 break;
1717
1718 case GMENU_TREE_ITEM_ENTRY:
1719 gmenu_tree_entry_finalize (GMENU_TREE_ENTRY (item));
1720 break;
1721
1722 case GMENU_TREE_ITEM_SEPARATOR:
1723 gmenu_tree_separator_finalize (GMENU_TREE_SEPARATOR (item));
1724 break;
1725
1726 case GMENU_TREE_ITEM_HEADER:
1727 gmenu_tree_header_finalize (GMENU_TREE_HEADER (item));
1728 break;
1729
1730 case GMENU_TREE_ITEM_ALIAS:
1731 gmenu_tree_alias_finalize (GMENU_TREE_ALIAS (item));
1732 break;
1733
1734 default:
1735 g_assert_not_reached ();
1736 break;
1737 }
1738 }
1739 }
1740
1741 static void
1742 gmenu_tree_item_unref_and_unset_parent (gpointer itemp)
1743 {
1744 GMenuTreeItem *item;
1745
1746 item = (GMenuTreeItem *) itemp;
1747
1748 g_return_if_fail (item != NULL);
1749
1750 gmenu_tree_item_set_parent (item, NULL);
1751 gmenu_tree_item_unref (item);
1752 }
1753
1754 static inline const char *
1755 gmenu_tree_item_compare_get_name_helper (GMenuTreeItem *item,
1756 GMenuTreeFlags flags)
1757 {
1758 const char *name;
1759
1760 name = NULL;
1761
1762 switch (item->type)
1763 {
1764 case GMENU_TREE_ITEM_DIRECTORY:
1765 if (GMENU_TREE_DIRECTORY (item)->directory_entry)
1766 name = desktop_entry_get_name (GMENU_TREE_DIRECTORY (item)->directory_entry);
1767 else
1768 name = GMENU_TREE_DIRECTORY (item)->name;
1769 break;
1770
1771 case GMENU_TREE_ITEM_ENTRY:
1772 if (flags & GMENU_TREE_FLAGS_SORT_DISPLAY_NAME)
1773 name = g_app_info_get_display_name (G_APP_INFO (gmenu_tree_entry_get_app_info (GMENU_TREE_ENTRY (item))));
1774 else
1775 name = desktop_entry_get_name (GMENU_TREE_ENTRY (item)->desktop_entry);
1776 break;
1777
1778 case GMENU_TREE_ITEM_ALIAS:
1779 {
1780 GMenuTreeItem *dir;
1781 dir = GMENU_TREE_ITEM (GMENU_TREE_ALIAS (item)->directory);
1782 name = gmenu_tree_item_compare_get_name_helper (dir, flags);
1783 }
1784 break;
1785
1786 case GMENU_TREE_ITEM_SEPARATOR:
1787 case GMENU_TREE_ITEM_HEADER:
1788 default:
1789 g_assert_not_reached ();
1790 break;
1791 }
1792
1793 return name;
1794 }
1795
1796 static int
1797 gmenu_tree_item_compare (GMenuTreeItem *a,
1798 GMenuTreeItem *b,
1799 gpointer flags_p)
1800 {
1801 const char *name_a;
1802 const char *name_b;
1803 GMenuTreeFlags flags;
1804
1805 flags = GPOINTER_TO_INT (flags_p);
1806
1807 name_a = gmenu_tree_item_compare_get_name_helper (a, flags);
1808 name_b = gmenu_tree_item_compare_get_name_helper (b, flags);
1809
1810 return g_utf8_collate (name_a, name_b);
1811 }
1812
1813 static MenuLayoutNode *
1814 find_menu_child (MenuLayoutNode *layout)
1815 {
1816 MenuLayoutNode *child;
1817
1818 child = menu_layout_node_get_children (layout);
1819 while (child && menu_layout_node_get_type (child) != MENU_LAYOUT_NODE_MENU)
1820 child = menu_layout_node_get_next (child);
1821
1822 return child;
1823 }
1824
1825 static void
1826 merge_resolved_children (GMenuTree *tree,
1827 GHashTable *loaded_menu_files,
1828 MenuLayoutNode *where,
1829 MenuLayoutNode *from)
1830 {
1831 MenuLayoutNode *insert_after;
1832 MenuLayoutNode *menu_child;
1833 MenuLayoutNode *from_child;
1834
1835 gmenu_tree_resolve_files (tree, loaded_menu_files, from);
1836
1837 insert_after = where;
1838 g_assert (menu_layout_node_get_type (insert_after) != MENU_LAYOUT_NODE_ROOT);
1839 g_assert (menu_layout_node_get_parent (insert_after) != NULL);
1840
1841 /* skip root node */
1842 menu_child = find_menu_child (from);
1843 g_assert (menu_child != NULL);
1844 g_assert (menu_layout_node_get_type (menu_child) == MENU_LAYOUT_NODE_MENU);
1845
1846 /* merge children of toplevel <Menu> */
1847 from_child = menu_layout_node_get_children (menu_child);
1848 while (from_child != NULL)
1849 {
1850 MenuLayoutNode *next;
1851
1852 next = menu_layout_node_get_next (from_child);
1853
1854 menu_verbose ("Merging ");
1855 menu_debug_print_layout (from_child, FALSE);
1856 menu_verbose (" after ");
1857 menu_debug_print_layout (insert_after, FALSE);
1858
1859 switch (menu_layout_node_get_type (from_child))
1860 {
1861 case MENU_LAYOUT_NODE_NAME:
1862 menu_layout_node_unlink (from_child); /* delete this */
1863 break;
1864
1865 default:
1866 menu_layout_node_steal (from_child);
1867 menu_layout_node_insert_after (insert_after, from_child);
1868 menu_layout_node_unref (from_child);
1869
1870 insert_after = from_child;
1871 break;
1872 }
1873
1874 from_child = next;
1875 }
1876 }
1877
1878 static gboolean
1879 load_merge_file (GMenuTree *tree,
1880 GHashTable *loaded_menu_files,
1881 const char *filename,
1882 gboolean is_canonical,
1883 gboolean add_monitor,
1884 MenuLayoutNode *where)
1885 {
1886 MenuLayoutNode *to_merge;
1887 const char *canonical;
1888 char *freeme;
1889 gboolean retval;
1890
1891 freeme = NULL;
1892 retval = FALSE;
1893
1894 if (!is_canonical)
1895 {
1896 canonical = freeme = menu_canonicalize_file_name (filename, FALSE);
1897 if (canonical == NULL)
1898 {
1899 if (add_monitor)
1900 gmenu_tree_add_menu_file_monitor (tree,
1901 filename,
1902 MENU_FILE_MONITOR_NONEXISTENT_FILE);
1903
1904 menu_verbose ("Failed to canonicalize merge file path \"%s\": %s\n",
1905 filename, g_strerror (errno));
1906 goto out;
1907 }
1908 }
1909 else
1910 {
1911 canonical = filename;
1912 }
1913
1914 if (g_hash_table_lookup (loaded_menu_files, canonical) != NULL)
1915 {
1916 g_warning ("Not loading \"%s\": recursive loop detected in .menu files",
1917 canonical);
1918 retval = TRUE;
1919 goto out;
1920 }
1921
1922 menu_verbose ("Merging file \"%s\"\n", canonical);
1923
1924 to_merge = menu_layout_load (canonical, tree->non_prefixed_basename, NULL);
1925 if (to_merge == NULL)
1926 {
1927 menu_verbose ("No menu for file \"%s\" found when merging\n",
1928 canonical);
1929 goto out;
1930 }
1931
1932 retval = TRUE;
1933
1934 g_hash_table_insert (loaded_menu_files, (char *) canonical, GUINT_TO_POINTER (TRUE));
1935
1936 if (add_monitor)
1937 gmenu_tree_add_menu_file_monitor (tree,
1938 canonical,
1939 MENU_FILE_MONITOR_FILE);
1940
1941 merge_resolved_children (tree, loaded_menu_files, where, to_merge);
1942
1943 g_hash_table_remove (loaded_menu_files, canonical);
1944
1945 menu_layout_node_unref (to_merge);
1946
1947 out:
1948 if (freeme)
1949 g_free (freeme);
1950
1951 return retval;
1952 }
1953
1954 static gboolean
1955 load_merge_file_with_config_dir (GMenuTree *tree,
1956 GHashTable *loaded_menu_files,
1957 const char *menu_file,
1958 const char *config_dir,
1959 MenuLayoutNode *where)
1960 {
1961 char *merge_file;
1962 gboolean loaded;
1963
1964 loaded = FALSE;
1965
1966 merge_file = g_build_filename (config_dir, "menus", menu_file, NULL);
1967
1968 if (load_merge_file (tree, loaded_menu_files, merge_file, FALSE, TRUE, where))
1969 loaded = TRUE;
1970
1971 g_free (merge_file);
1972
1973 return loaded;
1974 }
1975
1976 static gboolean
1977 compare_basedir_to_config_dir (const char *canonical_basedir,
1978 const char *config_dir)
1979 {
1980 char *dirname;
1981 char *canonical_menus_dir;
1982 gboolean retval;
1983
1984 menu_verbose ("Checking to see if basedir '%s' is in '%s'\n",
1985 canonical_basedir, config_dir);
1986
1987 dirname = g_build_filename (config_dir, "menus", NULL);
1988
1989 retval = FALSE;
1990
1991 canonical_menus_dir = menu_canonicalize_file_name (dirname, FALSE);
1992 if (canonical_menus_dir != NULL &&
1993 strcmp (canonical_basedir, canonical_menus_dir) == 0)
1994 {
1995 retval = TRUE;
1996 }
1997
1998 g_free (canonical_menus_dir);
1999 g_free (dirname);
2000
2001 return retval;
2002 }
2003
2004 static gboolean
2005 load_parent_merge_file_from_basename (GMenuTree *tree,
2006 GHashTable *loaded_menu_files,
2007 MenuLayoutNode *layout,
2008 const char *menu_file,
2009 const char *canonical_basedir)
2010 {
2011 gboolean found_basedir;
2012 const char * const *system_config_dirs;
2013 int i;
2014
2015 /* We're not interested in menu files that are in directories which are not a
2016 * parent of the base directory of this menu file */
2017 found_basedir = compare_basedir_to_config_dir (canonical_basedir,
2018 g_get_user_config_dir ());
2019
2020 system_config_dirs = g_get_system_config_dirs ();
2021
2022 i = 0;
2023 while (system_config_dirs[i] != NULL)
2024 {
2025 if (!found_basedir)
2026 {
2027 found_basedir = compare_basedir_to_config_dir (canonical_basedir,
2028 system_config_dirs[i]);
2029 }
2030 else
2031 {
2032 menu_verbose ("Looking for parent menu file '%s' in '%s'\n",
2033 menu_file, system_config_dirs[i]);
2034
2035 if (load_merge_file_with_config_dir (tree,
2036 loaded_menu_files,
2037 menu_file,
2038 system_config_dirs[i],
2039 layout))
2040 {
2041 break;
2042 }
2043 }
2044
2045 ++i;
2046 }
2047
2048 return system_config_dirs[i] != NULL;
2049 }
2050
2051 static gboolean
2052 load_parent_merge_file (GMenuTree *tree,
2053 GHashTable *loaded_menu_files,
2054 MenuLayoutNode *layout)
2055 {
2056 MenuLayoutNode *root;
2057 const char *basedir;
2058 const char *menu_name;
2059 char *canonical_basedir;
2060 char *menu_file;
2061 gboolean found;
2062
2063 root = menu_layout_node_get_root (layout);
2064
2065 basedir = menu_layout_node_root_get_basedir (root);
2066 menu_name = menu_layout_node_root_get_name (root);
2067
2068 canonical_basedir = menu_canonicalize_file_name (basedir, FALSE);
2069 if (canonical_basedir == NULL)
2070 {
2071 menu_verbose ("Menu basedir '%s' no longer exists, not merging parent\n",
2072 basedir);
2073 return FALSE;
2074 }
2075
2076 found = FALSE;
2077 menu_file = g_strconcat (menu_name, ".menu", NULL);
2078
2079 if (strcmp (menu_file, "applications.menu") == 0 &&
2080 g_getenv ("XDG_MENU_PREFIX"))
2081 {
2082 char *prefixed_basename;
2083 prefixed_basename = g_strdup_printf ("%s%s",
2084 g_getenv ("XDG_MENU_PREFIX"),
2085 menu_file);
2086 found = load_parent_merge_file_from_basename (tree, loaded_menu_files,
2087 layout, prefixed_basename,
2088 canonical_basedir);
2089 g_free (prefixed_basename);
2090 }
2091
2092 if (!found)
2093 {
2094 found = load_parent_merge_file_from_basename (tree, loaded_menu_files,
2095 layout, menu_file,
2096 canonical_basedir);
2097 }
2098
2099 g_free (menu_file);
2100 g_free (canonical_basedir);
2101
2102 return found;
2103 }
2104
2105 static void
2106 load_merge_dir (GMenuTree *tree,
2107 GHashTable *loaded_menu_files,
2108 const char *dirname,
2109 MenuLayoutNode *where)
2110 {
2111 GDir *dir;
2112 const char *menu_file;
2113
2114 menu_verbose ("Loading merge dir \"%s\"\n", dirname);
2115
2116 gmenu_tree_add_menu_file_monitor (tree,
2117 dirname,
2118 MENU_FILE_MONITOR_DIRECTORY);
2119
2120 if ((dir = g_dir_open (dirname, 0, NULL)) == NULL)
2121 return;
2122
2123 while ((menu_file = g_dir_read_name (dir)))
2124 {
2125 if (g_str_has_suffix (menu_file, ".menu"))
2126 {
2127 char *full_path;
2128
2129 full_path = g_build_filename (dirname, menu_file, NULL);
2130
2131 load_merge_file (tree, loaded_menu_files, full_path, TRUE, FALSE, where);
2132
2133 g_free (full_path);
2134 }
2135 }
2136
2137 g_dir_close (dir);
2138 }
2139
2140 static void
2141 load_merge_dir_with_config_dir (GMenuTree *tree,
2142 GHashTable *loaded_menu_files,
2143 const char *config_dir,
2144 const char *dirname,
2145 MenuLayoutNode *where)
2146 {
2147 char *path;
2148
2149 path = g_build_filename (config_dir, "menus", dirname, NULL);
2150
2151 load_merge_dir (tree, loaded_menu_files, path, where);
2152
2153 g_free (path);
2154 }
2155
2156 static void
2157 resolve_merge_file (GMenuTree *tree,
2158 GHashTable *loaded_menu_files,
2159 MenuLayoutNode *layout)
2160 {
2161 char *filename;
2162
2163 if (menu_layout_node_merge_file_get_type (layout) == MENU_MERGE_FILE_TYPE_PARENT)
2164 {
2165 if (load_parent_merge_file (tree, loaded_menu_files, layout))
2166 return;
2167 }
2168
2169 filename = menu_layout_node_get_content_as_path (layout);
2170 if (filename == NULL)
2171 {
2172 menu_verbose ("didn't get node content as a path, not merging file\n");
2173 }
2174 else
2175 {
2176 load_merge_file (tree, loaded_menu_files, filename, FALSE, TRUE, layout);
2177
2178 g_free (filename);
2179 }
2180
2181 /* remove the now-replaced node */
2182 menu_layout_node_unlink (layout);
2183 }
2184
2185 static void
2186 resolve_merge_dir (GMenuTree *tree,
2187 GHashTable *loaded_menu_files,
2188 MenuLayoutNode *layout)
2189 {
2190 char *path;
2191
2192 path = menu_layout_node_get_content_as_path (layout);
2193 if (path == NULL)
2194 {
2195 menu_verbose ("didn't get layout node content as a path, not merging dir\n");
2196 }
2197 else
2198 {
2199 load_merge_dir (tree, loaded_menu_files, path, layout);
2200
2201 g_free (path);
2202 }
2203
2204 /* remove the now-replaced node */
2205 menu_layout_node_unlink (layout);
2206 }
2207
2208 static MenuLayoutNode *
2209 add_app_dir (GMenuTree *tree,
2210 MenuLayoutNode *before,
2211 const char *data_dir)
2212 {
2213 MenuLayoutNode *tmp;
2214 char *dirname;
2215
2216 tmp = menu_layout_node_new (MENU_LAYOUT_NODE_APP_DIR);
2217 dirname = g_build_filename (data_dir, "applications", NULL);
2218 menu_layout_node_set_content (tmp, dirname);
2219 menu_layout_node_insert_before (before, tmp);
2220 menu_layout_node_unref (before);
2221
2222 menu_verbose ("Adding <AppDir>%s</AppDir> in <DefaultAppDirs/>\n",
2223 dirname);
2224
2225 g_free (dirname);
2226
2227 return tmp;
2228 }
2229
2230 static void
2231 resolve_default_app_dirs (GMenuTree *tree,
2232 MenuLayoutNode *layout)
2233 {
2234 MenuLayoutNode *before;
2235 const char * const *system_data_dirs;
2236 int i;
2237
2238 system_data_dirs = g_get_system_data_dirs ();
2239
2240 before = add_app_dir (tree,
2241 menu_layout_node_ref (layout),
2242 g_get_user_data_dir ());
2243
2244 i = 0;
2245 while (system_data_dirs[i] != NULL)
2246 {
2247 before = add_app_dir (tree, before, system_data_dirs[i]);
2248
2249 ++i;
2250 }
2251
2252 menu_layout_node_unref (before);
2253
2254 /* remove the now-replaced node */
2255 menu_layout_node_unlink (layout);
2256 }
2257
2258 static MenuLayoutNode *
2259 add_directory_dir (GMenuTree *tree,
2260 MenuLayoutNode *before,
2261 const char *data_dir)
2262 {
2263 MenuLayoutNode *tmp;
2264 char *dirname;
2265
2266 tmp = menu_layout_node_new (MENU_LAYOUT_NODE_DIRECTORY_DIR);
2267 dirname = g_build_filename (data_dir, "desktop-directories", NULL);
2268 menu_layout_node_set_content (tmp, dirname);
2269 menu_layout_node_insert_before (before, tmp);
2270 menu_layout_node_unref (before);
2271
2272 menu_verbose ("Adding <DirectoryDir>%s</DirectoryDir> in <DefaultDirectoryDirs/>\n",
2273 dirname);
2274
2275 g_free (dirname);
2276
2277 return tmp;
2278 }
2279
2280 static void
2281 resolve_default_directory_dirs (GMenuTree *tree,
2282 MenuLayoutNode *layout)
2283 {
2284 MenuLayoutNode *before;
2285 const char * const *system_data_dirs;
2286 int i;
2287
2288 system_data_dirs = g_get_system_data_dirs ();
2289
2290 before = add_directory_dir (tree,
2291 menu_layout_node_ref (layout),
2292 g_get_user_data_dir ());
2293
2294 i = 0;
2295 while (system_data_dirs[i] != NULL)
2296 {
2297 before = add_directory_dir (tree, before, system_data_dirs[i]);
2298
2299 ++i;
2300 }
2301
2302 menu_layout_node_unref (before);
2303
2304 /* remove the now-replaced node */
2305 menu_layout_node_unlink (layout);
2306 }
2307
2308 static void
2309 resolve_default_merge_dirs (GMenuTree *tree,
2310 GHashTable *loaded_menu_files,
2311 MenuLayoutNode *layout)
2312 {
2313 MenuLayoutNode *root;
2314 const char *menu_name;
2315 char *merge_name;
2316 const char * const *system_config_dirs;
2317 int i;
2318
2319 root = menu_layout_node_get_root (layout);
2320 menu_name = menu_layout_node_root_get_name (root);
2321
2322 merge_name = g_strconcat (menu_name, "-merged", NULL);
2323
2324 system_config_dirs = g_get_system_config_dirs ();
2325
2326 /* Merge in reverse order */
2327 i = 0;
2328 while (system_config_dirs[i] != NULL) i++;
2329 while (i > 0)
2330 {
2331 i--;
2332 load_merge_dir_with_config_dir (tree,
2333 loaded_menu_files,
2334 system_config_dirs[i],
2335 merge_name,
2336 layout);
2337 }
2338
2339 load_merge_dir_with_config_dir (tree,
2340 loaded_menu_files,
2341 g_get_user_config_dir (),
2342 merge_name,
2343 layout);
2344
2345 g_free (merge_name);
2346
2347 /* remove the now-replaced node */
2348 menu_layout_node_unlink (layout);
2349 }
2350
2351 static void
2352 add_filename_include (const char *desktop_file_id,
2353 DesktopEntry *entry,
2354 MenuLayoutNode *include)
2355 {
2356 if (!desktop_entry_has_categories (entry))
2357 {
2358 MenuLayoutNode *node;
2359
2360 node = menu_layout_node_new (MENU_LAYOUT_NODE_FILENAME);
2361 menu_layout_node_set_content (node, desktop_file_id);
2362
2363 menu_layout_node_append_child (include, node);
2364 menu_layout_node_unref (node);
2365 }
2366 }
2367
2368 static void
2369 is_dot_directory (const char *basename,
2370 DesktopEntry *entry,
2371 gboolean *has_dot_directory)
2372 {
2373 if (!strcmp (basename, ".directory"))
2374 *has_dot_directory = TRUE;
2375 }
2376
2377 static gboolean
2378 add_menu_for_legacy_dir (MenuLayoutNode *parent,
2379 const char *legacy_dir,
2380 const char *relative_path,
2381 const char *legacy_prefix,
2382 const char *menu_name)
2383 {
2384 EntryDirectory *ed;
2385 DesktopEntrySet *desktop_entries;
2386 DesktopEntrySet *directory_entries;
2387 GSList *subdirs;
2388 gboolean menu_added;
2389 gboolean has_dot_directory;
2390
2391 ed = entry_directory_new_legacy (DESKTOP_ENTRY_INVALID, legacy_dir, legacy_prefix);
2392 if (!ed)
2393 return FALSE;
2394
2395 subdirs = NULL;
2396 desktop_entries = desktop_entry_set_new ();
2397 directory_entries = desktop_entry_set_new ();
2398
2399 entry_directory_get_flat_contents (ed,
2400 desktop_entries,
2401 directory_entries,
2402 &subdirs);
2403 entry_directory_unref (ed);
2404
2405 has_dot_directory = FALSE;
2406 desktop_entry_set_foreach (directory_entries,
2407 (DesktopEntrySetForeachFunc) is_dot_directory,
2408 &has_dot_directory);
2409 desktop_entry_set_unref (directory_entries);
2410
2411 menu_added = FALSE;
2412 if (desktop_entry_set_get_count (desktop_entries) > 0 || subdirs)
2413 {
2414 MenuLayoutNode *menu;
2415 MenuLayoutNode *node;
2416 GString *subdir_path;
2417 GString *subdir_relative;
2418 GSList *tmp;
2419 int legacy_dir_len;
2420 int relative_path_len;
2421
2422 menu = menu_layout_node_new (MENU_LAYOUT_NODE_MENU);
2423 menu_layout_node_append_child (parent, menu);
2424
2425 menu_added = TRUE;
2426
2427 g_assert (menu_name != NULL);
2428
2429 node = menu_layout_node_new (MENU_LAYOUT_NODE_NAME);
2430 menu_layout_node_set_content (node, menu_name);
2431 menu_layout_node_append_child (menu, node);
2432 menu_layout_node_unref (node);
2433
2434 if (has_dot_directory)
2435 {
2436 node = menu_layout_node_new (MENU_LAYOUT_NODE_DIRECTORY);
2437 if (relative_path != NULL)
2438 {
2439 char *directory_entry_path;
2440
2441 directory_entry_path = g_strdup_printf ("%s/.directory", relative_path);
2442 menu_layout_node_set_content (node, directory_entry_path);
2443 g_free (directory_entry_path);
2444 }
2445 else
2446 {
2447 menu_layout_node_set_content (node, ".directory");
2448 }
2449 menu_layout_node_append_child (menu, node);
2450 menu_layout_node_unref (node);
2451 }
2452
2453 if (desktop_entry_set_get_count (desktop_entries) > 0)
2454 {
2455 MenuLayoutNode *include;
2456
2457 include = menu_layout_node_new (MENU_LAYOUT_NODE_INCLUDE);
2458 menu_layout_node_append_child (menu, include);
2459
2460 desktop_entry_set_foreach (desktop_entries,
2461 (DesktopEntrySetForeachFunc) add_filename_include,
2462 include);
2463
2464 menu_layout_node_unref (include);
2465 }
2466
2467 subdir_path = g_string_new (legacy_dir);
2468 legacy_dir_len = strlen (legacy_dir);
2469
2470 subdir_relative = g_string_new (relative_path);
2471 relative_path_len = relative_path ? strlen (relative_path) : 0;
2472
2473 tmp = subdirs;
2474 while (tmp != NULL)
2475 {
2476 const char *subdir = tmp->data;
2477
2478 g_string_append_c (subdir_path, G_DIR_SEPARATOR);
2479 g_string_append (subdir_path, subdir);
2480
2481 if (relative_path_len)
2482 {
2483 g_string_append_c (subdir_relative, G_DIR_SEPARATOR);
2484 }
2485 g_string_append (subdir_relative, subdir);
2486
2487 add_menu_for_legacy_dir (menu,
2488 subdir_path->str,
2489 subdir_relative->str,
2490 legacy_prefix,
2491 subdir);
2492
2493 g_string_truncate (subdir_relative, relative_path_len);
2494 g_string_truncate (subdir_path, legacy_dir_len);
2495
2496 tmp = tmp->next;
2497 }
2498
2499 g_string_free (subdir_path, TRUE);
2500 g_string_free (subdir_relative, TRUE);
2501
2502 menu_layout_node_unref (menu);
2503 }
2504
2505 desktop_entry_set_unref (desktop_entries);
2506
2507 g_slist_foreach (subdirs, (GFunc) g_free, NULL);
2508 g_slist_free (subdirs);
2509
2510 return menu_added;
2511 }
2512
2513 static void
2514 resolve_legacy_dir (GMenuTree *tree,
2515 GHashTable *loaded_menu_files,
2516 MenuLayoutNode *legacy)
2517 {
2518 MenuLayoutNode *to_merge;
2519 MenuLayoutNode *menu;
2520
2521 to_merge = menu_layout_node_new (MENU_LAYOUT_NODE_ROOT);
2522
2523 menu = menu_layout_node_get_parent (legacy);
2524 g_assert (menu_layout_node_get_type (menu) == MENU_LAYOUT_NODE_MENU);
2525
2526 if (add_menu_for_legacy_dir (to_merge,
2527 menu_layout_node_get_content (legacy),
2528 NULL,
2529 menu_layout_node_legacy_dir_get_prefix (legacy),
2530 menu_layout_node_menu_get_name (menu)))
2531 {
2532 merge_resolved_children (tree, loaded_menu_files, legacy, to_merge);
2533 }
2534
2535 menu_layout_node_unref (to_merge);
2536 }
2537
2538 static MenuLayoutNode *
2539 add_legacy_dir (GMenuTree *tree,
2540 GHashTable *loaded_menu_files,
2541 MenuLayoutNode *before,
2542 const char *data_dir)
2543 {
2544 MenuLayoutNode *legacy;
2545 char *dirname;
2546
2547 dirname = g_build_filename (data_dir, "applnk", NULL);
2548
2549 legacy = menu_layout_node_new (MENU_LAYOUT_NODE_LEGACY_DIR);
2550 menu_layout_node_set_content (legacy, dirname);
2551 menu_layout_node_legacy_dir_set_prefix (legacy, "kde");
2552 menu_layout_node_insert_before (before, legacy);
2553 menu_layout_node_unref (before);
2554
2555 menu_verbose ("Adding <LegacyDir>%s</LegacyDir> in <KDELegacyDirs/>\n",
2556 dirname);
2557
2558 resolve_legacy_dir (tree, loaded_menu_files, legacy);
2559
2560 g_free (dirname);
2561
2562 return legacy;
2563 }
2564
2565 static void
2566 resolve_kde_legacy_dirs (GMenuTree *tree,
2567 GHashTable *loaded_menu_files,
2568 MenuLayoutNode *layout)
2569 {
2570 MenuLayoutNode *before;
2571 const char * const *system_data_dirs;
2572 int i;
2573
2574 system_data_dirs = g_get_system_data_dirs ();
2575
2576 before = add_legacy_dir (tree,
2577 loaded_menu_files,
2578 menu_layout_node_ref (layout),
2579 g_get_user_data_dir ());
2580
2581 i = 0;
2582 while (system_data_dirs[i] != NULL)
2583 {
2584 before = add_legacy_dir (tree, loaded_menu_files, before, system_data_dirs[i]);
2585
2586 ++i;
2587 }
2588
2589 menu_layout_node_unref (before);
2590
2591 /* remove the now-replaced node */
2592 menu_layout_node_unlink (layout);
2593 }
2594
2595 static void
2596 gmenu_tree_resolve_files (GMenuTree *tree,
2597 GHashTable *loaded_menu_files,
2598 MenuLayoutNode *layout)
2599 {
2600 MenuLayoutNode *child;
2601
2602 menu_verbose ("Resolving files in: ");
2603 menu_debug_print_layout (layout, TRUE);
2604
2605 switch (menu_layout_node_get_type (layout))
2606 {
2607 case MENU_LAYOUT_NODE_MERGE_FILE:
2608 resolve_merge_file (tree, loaded_menu_files, layout);
2609 break;
2610
2611 case MENU_LAYOUT_NODE_MERGE_DIR:
2612 resolve_merge_dir (tree, loaded_menu_files, layout);
2613 break;
2614
2615 case MENU_LAYOUT_NODE_DEFAULT_APP_DIRS:
2616 resolve_default_app_dirs (tree, layout);
2617 break;
2618
2619 case MENU_LAYOUT_NODE_DEFAULT_DIRECTORY_DIRS:
2620 resolve_default_directory_dirs (tree, layout);
2621 break;
2622
2623 case MENU_LAYOUT_NODE_DEFAULT_MERGE_DIRS:
2624 resolve_default_merge_dirs (tree, loaded_menu_files, layout);
2625 break;
2626
2627 case MENU_LAYOUT_NODE_LEGACY_DIR:
2628 resolve_legacy_dir (tree, loaded_menu_files, layout);
2629 break;
2630
2631 case MENU_LAYOUT_NODE_KDE_LEGACY_DIRS:
2632 resolve_kde_legacy_dirs (tree, loaded_menu_files, layout);
2633 break;
2634
2635 case MENU_LAYOUT_NODE_PASSTHROUGH:
2636 /* Just get rid of these, we don't need the memory usage */
2637 menu_layout_node_unlink (layout);
2638 break;
2639
2640 default:
2641 /* Recurse */
2642 child = menu_layout_node_get_children (layout);
2643 while (child != NULL)
2644 {
2645 MenuLayoutNode *next = menu_layout_node_get_next (child);
2646
2647 gmenu_tree_resolve_files (tree, loaded_menu_files, child);
2648
2649 child = next;
2650 }
2651 break;
2652 }
2653 }
2654
2655 static void
2656 move_children (MenuLayoutNode *from,
2657 MenuLayoutNode *to)
2658 {
2659 MenuLayoutNode *from_child;
2660 MenuLayoutNode *insert_before;
2661
2662 insert_before = menu_layout_node_get_children (to);
2663 from_child = menu_layout_node_get_children (from);
2664
2665 while (from_child != NULL)
2666 {
2667 MenuLayoutNode *next;
2668
2669 next = menu_layout_node_get_next (from_child);
2670
2671 menu_layout_node_steal (from_child);
2672
2673 if (menu_layout_node_get_type (from_child) == MENU_LAYOUT_NODE_NAME)
2674 {
2675 ; /* just drop the Name in the old <Menu> */
2676 }
2677 else if (insert_before)
2678 {
2679 menu_layout_node_insert_before (insert_before, from_child);
2680 g_assert (menu_layout_node_get_next (from_child) == insert_before);
2681 }
2682 else
2683 {
2684 menu_layout_node_append_child (to, from_child);
2685 }
2686
2687 menu_layout_node_unref (from_child);
2688
2689 from_child = next;
2690 }
2691 }
2692
2693 static int
2694 null_safe_strcmp (const char *a,
2695 const char *b)
2696 {
2697 if (a == NULL && b == NULL)
2698 return 0;
2699 else if (a == NULL)
2700 return -1;
2701 else if (b == NULL)
2702 return 1;
2703 else
2704 return strcmp (a, b);
2705 }
2706
2707 static int
2708 node_compare_func (const void *a,
2709 const void *b)
2710 {
2711 MenuLayoutNode *node_a = (MenuLayoutNode*) a;
2712 MenuLayoutNode *node_b = (MenuLayoutNode*) b;
2713 MenuLayoutNodeType t_a = menu_layout_node_get_type (node_a);
2714 MenuLayoutNodeType t_b = menu_layout_node_get_type (node_b);
2715
2716 if (t_a < t_b)
2717 return -1;
2718 else if (t_a > t_b)
2719 return 1;
2720 else
2721 {
2722 const char *c_a = menu_layout_node_get_content (node_a);
2723 const char *c_b = menu_layout_node_get_content (node_b);
2724
2725 return null_safe_strcmp (c_a, c_b);
2726 }
2727 }
2728
2729 static int
2730 node_menu_compare_func (const void *a,
2731 const void *b)
2732 {
2733 MenuLayoutNode *node_a = (MenuLayoutNode*) a;
2734 MenuLayoutNode *node_b = (MenuLayoutNode*) b;
2735 MenuLayoutNode *parent_a = menu_layout_node_get_parent (node_a);
2736 MenuLayoutNode *parent_b = menu_layout_node_get_parent (node_b);
2737
2738 if (parent_a < parent_b)
2739 return -1;
2740 else if (parent_a > parent_b)
2741 return 1;
2742 else
2743 return null_safe_strcmp (menu_layout_node_menu_get_name (node_a),
2744 menu_layout_node_menu_get_name (node_b));
2745 }
2746
2747 static void
2748 gmenu_tree_strip_duplicate_children (GMenuTree *tree,
2749 MenuLayoutNode *layout)
2750 {
2751 MenuLayoutNode *child;
2752 GSList *simple_nodes;
2753 GSList *menu_layout_nodes;
2754 GSList *prev;
2755 GSList *tmp;
2756
2757 /* to strip dups, we find all the child nodes where
2758 * we want to kill dups, sort them,
2759 * then nuke the adjacent nodes that are equal
2760 */
2761
2762 simple_nodes = NULL;
2763 menu_layout_nodes = NULL;
2764
2765 child = menu_layout_node_get_children (layout);
2766 while (child != NULL)
2767 {
2768 switch (menu_layout_node_get_type (child))
2769 {
2770 /* These are dups if their content is the same */
2771 case MENU_LAYOUT_NODE_APP_DIR:
2772 case MENU_LAYOUT_NODE_DIRECTORY_DIR:
2773 case MENU_LAYOUT_NODE_DIRECTORY:
2774 simple_nodes = g_slist_prepend (simple_nodes, child);
2775 break;
2776
2777 /* These have to be merged in a more complicated way,
2778 * and then recursed
2779 */
2780 case MENU_LAYOUT_NODE_MENU:
2781 menu_layout_nodes = g_slist_prepend (menu_layout_nodes, child);
2782 break;
2783
2784 default:
2785 break;
2786 }
2787
2788 child = menu_layout_node_get_next (child);
2789 }
2790
2791 /* Note that the lists are all backward. So we want to keep
2792 * the items that are earlier in the list, because they were
2793 * later in the file
2794 */
2795
2796 /* stable sort the simple nodes */
2797 simple_nodes = g_slist_sort (simple_nodes,
2798 node_compare_func);
2799
2800 prev = NULL;
2801 tmp = simple_nodes;
2802 while (tmp != NULL)
2803 {
2804 GSList *next = tmp->next;
2805
2806 if (prev)
2807 {
2808 MenuLayoutNode *p = prev->data;
2809 MenuLayoutNode *n = tmp->data;
2810
2811 if (node_compare_func (p, n) == 0)
2812 {
2813 /* nuke it! */
2814 menu_layout_node_unlink (n);
2815 simple_nodes = g_slist_delete_link (simple_nodes, tmp);
2816 tmp = prev;
2817 }
2818 }
2819
2820 prev = tmp;
2821 tmp = next;
2822 }
2823
2824 g_slist_free (simple_nodes);
2825 simple_nodes = NULL;
2826
2827 /* stable sort the menu nodes (the sort includes the
2828 * parents of the nodes in the comparison). Remember
2829 * the list is backward.
2830 */
2831 menu_layout_nodes = g_slist_sort (menu_layout_nodes,
2832 node_menu_compare_func);
2833
2834 prev = NULL;
2835 tmp = menu_layout_nodes;
2836 while (tmp != NULL)
2837 {
2838 GSList *next = tmp->next;
2839
2840 if (prev)
2841 {
2842 MenuLayoutNode *p = prev->data;
2843 MenuLayoutNode *n = tmp->data;
2844
2845 if (node_menu_compare_func (p, n) == 0)
2846 {
2847 /* Move children of first menu to the start of second
2848 * menu and nuke the first menu
2849 */
2850 move_children (n, p);
2851 menu_layout_node_unlink (n);
2852 menu_layout_nodes = g_slist_delete_link (menu_layout_nodes, tmp);
2853 tmp = prev;
2854 }
2855 }
2856
2857 prev = tmp;
2858 tmp = next;
2859 }
2860
2861 g_slist_free (menu_layout_nodes);
2862 menu_layout_nodes = NULL;
2863
2864 /* Recursively clean up all children */
2865 child = menu_layout_node_get_children (layout);
2866 while (child != NULL)
2867 {
2868 if (menu_layout_node_get_type (child) == MENU_LAYOUT_NODE_MENU)
2869 gmenu_tree_strip_duplicate_children (tree, child);
2870
2871 child = menu_layout_node_get_next (child);
2872 }
2873 }
2874
2875 static MenuLayoutNode *
2876 find_submenu (MenuLayoutNode *layout,
2877 const char *path,
2878 gboolean create_if_not_found)
2879 {
2880 MenuLayoutNode *child;
2881 const char *slash;
2882 const char *next_path;
2883 char *name;
2884
2885 menu_verbose (" (splitting \"%s\")\n", path);
2886
2887 if (path[0] == '\0' || path[0] == G_DIR_SEPARATOR)
2888 return NULL;
2889
2890 slash = strchr (path, G_DIR_SEPARATOR);
2891 if (slash != NULL)
2892 {
2893 name = g_strndup (path, slash - path);
2894 next_path = slash + 1;
2895 if (*next_path == '\0')
2896 next_path = NULL;
2897 }
2898 else
2899 {
2900 name = g_strdup (path);
2901 next_path = NULL;
2902 }
2903
2904 child = menu_layout_node_get_children (layout);
2905 while (child != NULL)
2906 {
2907 switch (menu_layout_node_get_type (child))
2908 {
2909 case MENU_LAYOUT_NODE_MENU:
2910 {
2911 if (strcmp (name, menu_layout_node_menu_get_name (child)) == 0)
2912 {
2913 menu_verbose ("MenuNode %p found for path component \"%s\"\n",
2914 child, name);
2915
2916 g_free (name);
2917
2918 if (!next_path)
2919 {
2920 menu_verbose (" Found menu node %p parent is %p\n",
2921 child, layout);
2922 return child;
2923 }
2924
2925 return find_submenu (child, next_path, create_if_not_found);
2926 }
2927 }
2928 break;
2929
2930 default:
2931 break;
2932 }
2933
2934 child = menu_layout_node_get_next (child);
2935 }
2936
2937 if (create_if_not_found)
2938 {
2939 MenuLayoutNode *name_node;
2940
2941 child = menu_layout_node_new (MENU_LAYOUT_NODE_MENU);
2942 menu_layout_node_append_child (layout, child);
2943
2944 name_node = menu_layout_node_new (MENU_LAYOUT_NODE_NAME);
2945 menu_layout_node_set_content (name_node, name);
2946 menu_layout_node_append_child (child, name_node);
2947 menu_layout_node_unref (name_node);
2948
2949 menu_verbose (" Created menu node %p parent is %p\n",
2950 child, layout);
2951
2952 menu_layout_node_unref (child);
2953 g_free (name);
2954
2955 if (!next_path)
2956 return child;
2957
2958 return find_submenu (child, next_path, create_if_not_found);
2959 }
2960 else
2961 {
2962 g_free (name);
2963 return NULL;
2964 }
2965 }
2966
2967 /* To call this you first have to strip duplicate children once,
2968 * otherwise when you move a menu Foo to Bar then you may only
2969 * move one of Foo, not all the merged Foo.
2970 */
2971 static void
2972 gmenu_tree_execute_moves (GMenuTree *tree,
2973 MenuLayoutNode *layout,
2974 gboolean *need_remove_dups_p)
2975 {
2976 MenuLayoutNode *child;
2977 gboolean need_remove_dups;
2978 GSList *move_nodes;
2979 GSList *tmp;
2980
2981 need_remove_dups = FALSE;
2982
2983 move_nodes = NULL;
2984
2985 child = menu_layout_node_get_children (layout);
2986 while (child != NULL)
2987 {
2988 switch (menu_layout_node_get_type (child))
2989 {
2990 case MENU_LAYOUT_NODE_MENU:
2991 /* Recurse - we recurse first and process the current node
2992 * second, as the spec dictates.
2993 */
2994 gmenu_tree_execute_moves (tree, child, &need_remove_dups);
2995 break;
2996
2997 case MENU_LAYOUT_NODE_MOVE:
2998 move_nodes = g_slist_prepend (move_nodes, child);
2999 break;
3000
3001 default:
3002 break;
3003 }
3004
3005 child = menu_layout_node_get_next (child);
3006 }
3007
3008 /* We need to execute the move operations in the order that they appear */
3009 move_nodes = g_slist_reverse (move_nodes);
3010
3011 tmp = move_nodes;
3012 while (tmp != NULL)
3013 {
3014 MenuLayoutNode *move_node = tmp->data;
3015 MenuLayoutNode *old_node;
3016 GSList *next = tmp->next;
3017 const char *old;
3018 const char *new;
3019
3020 old = menu_layout_node_move_get_old (move_node);
3021 new = menu_layout_node_move_get_new (move_node);
3022 g_assert (old != NULL && new != NULL);
3023
3024 menu_verbose ("executing <Move> old = \"%s\" new = \"%s\"\n",
3025 old, new);
3026
3027 old_node = find_submenu (layout, old, FALSE);
3028 if (old_node != NULL)
3029 {
3030 MenuLayoutNode *new_node;
3031
3032 /* here we can create duplicates anywhere below the
3033 * node
3034 */
3035 need_remove_dups = TRUE;
3036
3037 /* look up new node creating it and its parents if
3038 * required
3039 */
3040 new_node = find_submenu (layout, new, TRUE);
3041 g_assert (new_node != NULL);
3042
3043 move_children (old_node, new_node);
3044
3045 menu_layout_node_unlink (old_node);
3046 }
3047
3048 menu_layout_node_unlink (move_node);
3049
3050 tmp = next;
3051 }
3052
3053 g_slist_free (move_nodes);
3054
3055 /* This oddness is to ensure we only remove dups once,
3056 * at the root, instead of recursing the tree over
3057 * and over.
3058 */
3059 if (need_remove_dups_p)
3060 *need_remove_dups_p = need_remove_dups;
3061 else if (need_remove_dups)
3062 gmenu_tree_strip_duplicate_children (tree, layout);
3063 }
3064
3065 static gboolean
3066 gmenu_tree_load_layout (GMenuTree *tree,
3067 GError **error)
3068 {
3069 GHashTable *loaded_menu_files;
3070
3071 if (tree->layout)
3072 return TRUE;
3073
3074 if (!gmenu_tree_canonicalize_path (tree, error))
3075 return FALSE;
3076
3077 menu_verbose ("Loading menu layout from \"%s\"\n",
3078 tree->canonical_path);
3079
3080 tree->layout = menu_layout_load (tree->canonical_path,
3081 tree->non_prefixed_basename,
3082 error);
3083 if (!tree->layout)
3084 return FALSE;
3085
3086 loaded_menu_files = g_hash_table_new (g_str_hash, g_str_equal);
3087 g_hash_table_insert (loaded_menu_files, tree->canonical_path, GUINT_TO_POINTER (TRUE));
3088 gmenu_tree_resolve_files (tree, loaded_menu_files, tree->layout);
3089 g_hash_table_destroy (loaded_menu_files);
3090
3091 gmenu_tree_strip_duplicate_children (tree, tree->layout);
3092 gmenu_tree_execute_moves (tree, tree->layout, NULL);
3093
3094 return TRUE;
3095 }
3096
3097 static void
3098 gmenu_tree_force_reload (GMenuTree *tree)
3099 {
3100 gmenu_tree_force_rebuild (tree);
3101
3102 if (tree->layout)
3103 menu_layout_node_unref (tree->layout);
3104 tree->layout = NULL;
3105 }
3106
3107 typedef struct
3108 {
3109 DesktopEntrySet *set;
3110 const char *category;
3111 } GetByCategoryForeachData;
3112
3113 static void
3114 get_by_category_foreach (const char *file_id,
3115 DesktopEntry *entry,
3116 GetByCategoryForeachData *data)
3117 {
3118 if (desktop_entry_has_category (entry, data->category))
3119 desktop_entry_set_add_entry (data->set, entry, file_id);
3120 }
3121
3122 static void
3123 get_by_category (DesktopEntrySet *entry_pool,
3124 DesktopEntrySet *set,
3125 const char *category)
3126 {
3127 GetByCategoryForeachData data;
3128
3129 data.set = set;
3130 data.category = category;
3131
3132 desktop_entry_set_foreach (entry_pool,
3133 (DesktopEntrySetForeachFunc) get_by_category_foreach,
3134 &data);
3135 }
3136
3137 static DesktopEntrySet *
3138 process_include_rules (MenuLayoutNode *layout,
3139 DesktopEntrySet *entry_pool)
3140 {
3141 DesktopEntrySet *set = NULL;
3142
3143 switch (menu_layout_node_get_type (layout))
3144 {
3145 case MENU_LAYOUT_NODE_AND:
3146 {
3147 MenuLayoutNode *child;
3148
3149 menu_verbose ("Processing <And>\n");
3150
3151 child = menu_layout_node_get_children (layout);
3152 while (child != NULL)
3153 {
3154 DesktopEntrySet *child_set;
3155
3156 child_set = process_include_rules (child, entry_pool);
3157
3158 if (set == NULL)
3159 {
3160 set = child_set;
3161 }
3162 else
3163 {
3164 desktop_entry_set_intersection (set, child_set);
3165 desktop_entry_set_unref (child_set);
3166 }
3167
3168 /* as soon as we get empty results, we can bail,
3169 * because it's an AND
3170 */
3171 if (desktop_entry_set_get_count (set) == 0)
3172 break;
3173
3174 child = menu_layout_node_get_next (child);
3175 }
3176 menu_verbose ("Processed <And>\n");
3177 }
3178 break;
3179
3180 case MENU_LAYOUT_NODE_OR:
3181 {
3182 MenuLayoutNode *child;
3183
3184 menu_verbose ("Processing <Or>\n");
3185
3186 child = menu_layout_node_get_children (layout);
3187 while (child != NULL)
3188 {
3189 DesktopEntrySet *child_set;
3190
3191 child_set = process_include_rules (child, entry_pool);
3192
3193 if (set == NULL)
3194 {
3195 set = child_set;
3196 }
3197 else
3198 {
3199 desktop_entry_set_union (set, child_set);
3200 desktop_entry_set_unref (child_set);
3201 }
3202
3203 child = menu_layout_node_get_next (child);
3204 }
3205 menu_verbose ("Processed <Or>\n");
3206 }
3207 break;
3208
3209 case MENU_LAYOUT_NODE_NOT:
3210 {
3211 /* First get the OR of all the rules */
3212 MenuLayoutNode *child;
3213
3214 menu_verbose ("Processing <Not>\n");
3215
3216 child = menu_layout_node_get_children (layout);
3217 while (child != NULL)
3218 {
3219 DesktopEntrySet *child_set;
3220
3221 child_set = process_include_rules (child, entry_pool);
3222
3223 if (set == NULL)
3224 {
3225 set = child_set;
3226 }
3227 else
3228 {
3229 desktop_entry_set_union (set, child_set);
3230 desktop_entry_set_unref (child_set);
3231 }
3232
3233 child = menu_layout_node_get_next (child);
3234 }
3235
3236 if (set != NULL)
3237 {
3238 DesktopEntrySet *inverted;
3239
3240 /* Now invert the result */
3241 inverted = desktop_entry_set_new ();
3242 desktop_entry_set_union (inverted, entry_pool);
3243 desktop_entry_set_subtract (inverted, set);
3244 desktop_entry_set_unref (set);
3245 set = inverted;
3246 }
3247 menu_verbose ("Processed <Not>\n");
3248 }
3249 break;
3250
3251 case MENU_LAYOUT_NODE_ALL:
3252 menu_verbose ("Processing <All>\n");
3253 set = desktop_entry_set_new ();
3254 desktop_entry_set_union (set, entry_pool);
3255 menu_verbose ("Processed <All>\n");
3256 break;
3257
3258 case MENU_LAYOUT_NODE_FILENAME:
3259 {
3260 DesktopEntry *entry;
3261
3262 menu_verbose ("Processing <Filename>%s</Filename>\n",
3263 menu_layout_node_get_content (layout));
3264
3265 entry = desktop_entry_set_lookup (entry_pool,
3266 menu_layout_node_get_content (layout));
3267 if (entry != NULL)
3268 {
3269 set = desktop_entry_set_new ();
3270 desktop_entry_set_add_entry (set,
3271 entry,
3272 menu_layout_node_get_content (layout));
3273 }
3274 menu_verbose ("Processed <Filename>%s</Filename>\n",
3275 menu_layout_node_get_content (layout));
3276 }
3277 break;
3278
3279 case MENU_LAYOUT_NODE_CATEGORY:
3280 menu_verbose ("Processing <Category>%s</Category>\n",
3281 menu_layout_node_get_content (layout));
3282 set = desktop_entry_set_new ();
3283 get_by_category (entry_pool, set, menu_layout_node_get_content (layout));
3284 menu_verbose ("Processed <Category>%s</Category>\n",
3285 menu_layout_node_get_content (layout));
3286 break;
3287
3288 default:
3289 break;
3290 }
3291
3292 if (set == NULL)
3293 set = desktop_entry_set_new (); /* create an empty set */
3294
3295 menu_verbose ("Matched %d entries\n", desktop_entry_set_get_count (set));
3296
3297 return set;
3298 }
3299
3300 static void
3301 collect_layout_info (MenuLayoutNode *layout,
3302 GSList **layout_info)
3303 {
3304 MenuLayoutNode *iter;
3305
3306 g_slist_foreach (*layout_info,
3307 (GFunc) menu_layout_node_unref,
3308 NULL);
3309 g_slist_free (*layout_info);
3310 *layout_info = NULL;
3311
3312 iter = menu_layout_node_get_children (layout);
3313 while (iter != NULL)
3314 {
3315 switch (menu_layout_node_get_type (iter))
3316 {
3317 case MENU_LAYOUT_NODE_MENUNAME:
3318 case MENU_LAYOUT_NODE_FILENAME:
3319 case MENU_LAYOUT_NODE_SEPARATOR:
3320 case MENU_LAYOUT_NODE_MERGE:
3321 *layout_info = g_slist_prepend (*layout_info,
3322 menu_layout_node_ref (iter));
3323 break;
3324
3325 default:
3326 break;
3327 }
3328
3329 iter = menu_layout_node_get_next (iter);
3330 }
3331
3332 *layout_info = g_slist_reverse (*layout_info);
3333 }
3334
3335 static void
3336 entries_listify_foreach (const char *desktop_file_id,
3337 DesktopEntry *desktop_entry,
3338 GMenuTreeDirectory *directory)
3339 {
3340 directory->entries =
3341 g_slist_prepend (directory->entries,
3342 gmenu_tree_entry_new (directory,
3343 desktop_entry,
3344 desktop_file_id,
3345 FALSE,
3346 FALSE));
3347 }
3348
3349 static void
3350 excluded_entries_listify_foreach (const char *desktop_file_id,
3351 DesktopEntry *desktop_entry,
3352 GMenuTreeDirectory *directory)
3353 {
3354 directory->entries =
3355 g_slist_prepend (directory->entries,
3356 gmenu_tree_entry_new (directory,
3357 desktop_entry,
3358 desktop_file_id,
3359 TRUE,
3360 FALSE));
3361 }
3362
3363 static void
3364 unallocated_entries_listify_foreach (const char *desktop_file_id,
3365 DesktopEntry *desktop_entry,
3366 GMenuTreeDirectory *directory)
3367 {
3368 directory->entries =
3369 g_slist_prepend (directory->entries,
3370 gmenu_tree_entry_new (directory,
3371 desktop_entry,
3372 desktop_file_id,
3373 FALSE,
3374 TRUE));
3375 }
3376
3377 static void
3378 set_default_layout_values (GMenuTreeDirectory *parent,
3379 GMenuTreeDirectory *child)
3380 {
3381 GSList *tmp;
3382
3383 /* if the child has a defined default layout, we don't want to override its
3384 * values. The parent might have a non-defined layout info (ie, no child of
3385 * the DefaultLayout node) but it doesn't meant the default layout values
3386 * (ie, DefaultLayout attributes) aren't different from the global defaults.
3387 */
3388 if (child->default_layout_info != NULL ||
3389 child->default_layout_values.mask != MENU_LAYOUT_VALUES_NONE)
3390 return;
3391
3392 child->default_layout_values = parent->default_layout_values;
3393
3394 tmp = child->subdirs;
3395 while (tmp != NULL)
3396 {
3397 GMenuTreeDirectory *subdir = tmp->data;
3398
3399 set_default_layout_values (child, subdir);
3400
3401 tmp = tmp->next;
3402 }
3403 }
3404
3405 static GMenuTreeDirectory *
3406 process_layout (GMenuTree *tree,
3407 GMenuTreeDirectory *parent,
3408 MenuLayoutNode *layout,
3409 DesktopEntrySet *allocated)
3410 {
3411 MenuLayoutNode *layout_iter;
3412 GMenuTreeDirectory *directory;
3413 DesktopEntrySet *entry_pool;
3414 DesktopEntrySet *entries;
3415 DesktopEntrySet *allocated_set;
3416 DesktopEntrySet *excluded_set;
3417 gboolean deleted;
3418 gboolean only_unallocated;
3419 GSList *tmp;
3420
3421 g_assert (menu_layout_node_get_type (layout) == MENU_LAYOUT_NODE_MENU);
3422 g_assert (menu_layout_node_menu_get_name (layout) != NULL);
3423
3424 directory = gmenu_tree_directory_new (tree, parent,
3425 menu_layout_node_menu_get_name (layout));
3426
3427 menu_verbose ("=== Menu name = %s ===\n", directory->name);
3428
3429
3430 deleted = FALSE;
3431 only_unallocated = FALSE;
3432
3433 entries = desktop_entry_set_new ();
3434 allocated_set = desktop_entry_set_new ();
3435
3436 if (tree->flags & GMENU_TREE_FLAGS_INCLUDE_EXCLUDED)
3437 excluded_set = desktop_entry_set_new ();
3438 else
3439 excluded_set = NULL;
3440
3441 entry_pool = _entry_directory_list_get_all_desktops (menu_layout_node_menu_get_app_dirs (layout));
3442
3443 layout_iter = menu_layout_node_get_children (layout);
3444 while (layout_iter != NULL)
3445 {
3446 switch (menu_layout_node_get_type (layout_iter))
3447 {
3448 case MENU_LAYOUT_NODE_MENU:
3449 /* recurse */
3450 {
3451 GMenuTreeDirectory *child_dir;
3452
3453 menu_verbose ("Processing <Menu>\n");
3454
3455 child_dir = process_layout (tree,
3456 directory,
3457 layout_iter,
3458 allocated);
3459 if (child_dir)
3460 directory->subdirs = g_slist_prepend (directory->subdirs,
3461 child_dir);
3462
3463 menu_verbose ("Processed <Menu>\n");
3464 }
3465 break;
3466
3467 case MENU_LAYOUT_NODE_INCLUDE:
3468 {
3469 /* The match rule children of the <Include> are
3470 * independent (logical OR) so we can process each one by
3471 * itself
3472 */
3473 MenuLayoutNode *rule;
3474
3475 menu_verbose ("Processing <Include> (%d entries)\n",
3476 desktop_entry_set_get_count (entries));
3477
3478 rule = menu_layout_node_get_children (layout_iter);
3479 while (rule != NULL)
3480 {
3481 DesktopEntrySet *rule_set;
3482
3483 rule_set = process_include_rules (rule, entry_pool);
3484 if (rule_set != NULL)
3485 {
3486 desktop_entry_set_union (entries, rule_set);
3487 desktop_entry_set_union (allocated_set, rule_set);
3488 if (excluded_set != NULL)
3489 desktop_entry_set_subtract (excluded_set, rule_set);
3490 desktop_entry_set_unref (rule_set);
3491 }
3492
3493 rule = menu_layout_node_get_next (rule);
3494 }
3495
3496 menu_verbose ("Processed <Include> (%d entries)\n",
3497 desktop_entry_set_get_count (entries));
3498 }
3499 break;
3500
3501 case MENU_LAYOUT_NODE_EXCLUDE:
3502 {
3503 /* The match rule children of the <Exclude> are
3504 * independent (logical OR) so we can process each one by
3505 * itself
3506 */
3507 MenuLayoutNode *rule;
3508
3509 menu_verbose ("Processing <Exclude> (%d entries)\n",
3510 desktop_entry_set_get_count (entries));
3511
3512 rule = menu_layout_node_get_children (layout_iter);
3513 while (rule != NULL)
3514 {
3515 DesktopEntrySet *rule_set;
3516
3517 rule_set = process_include_rules (rule, entry_pool);
3518 if (rule_set != NULL)
3519 {
3520 if (excluded_set != NULL)
3521 desktop_entry_set_union (excluded_set, rule_set);
3522 desktop_entry_set_subtract (entries, rule_set);
3523 desktop_entry_set_unref (rule_set);
3524 }
3525
3526 rule = menu_layout_node_get_next (rule);
3527 }
3528
3529 menu_verbose ("Processed <Exclude> (%d entries)\n",
3530 desktop_entry_set_get_count (entries));
3531 }
3532 break;
3533
3534 case MENU_LAYOUT_NODE_DIRECTORY:
3535 {
3536 DesktopEntry *entry;
3537
3538 menu_verbose ("Processing <Directory>%s</Directory>\n",
3539 menu_layout_node_get_content (layout_iter));
3540
3541 /*
3542 * The last <Directory> to exist wins, so we always try overwriting
3543 */
3544 entry = entry_directory_list_get_directory (menu_layout_node_menu_get_directory_dirs (layout),
3545 menu_layout_node_get_content (layout_iter));
3546
3547 if (entry != NULL)
3548 {
3549 if (!desktop_entry_get_hidden (entry))
3550 {
3551 if (directory->directory_entry)
3552 desktop_entry_unref (directory->directory_entry);
3553 directory->directory_entry = entry; /* pass ref ownership */
3554 }
3555 else
3556 {
3557 desktop_entry_unref (entry);
3558 }
3559 }
3560
3561 menu_verbose ("Processed <Directory> new directory entry = %p (%s)\n",
3562 directory->directory_entry,
3563 directory->directory_entry? desktop_entry_get_path (directory->directory_entry) : "null");
3564 }
3565 break;
3566
3567 case MENU_LAYOUT_NODE_DELETED:
3568 menu_verbose ("Processed <Deleted/>\n");
3569 deleted = TRUE;
3570 break;
3571
3572 case MENU_LAYOUT_NODE_NOT_DELETED:
3573 menu_verbose ("Processed <NotDeleted/>\n");
3574 deleted = FALSE;
3575 break;
3576
3577 case MENU_LAYOUT_NODE_ONLY_UNALLOCATED:
3578 menu_verbose ("Processed <OnlyUnallocated/>\n");
3579 only_unallocated = TRUE;
3580 break;
3581
3582 case MENU_LAYOUT_NODE_NOT_ONLY_UNALLOCATED:
3583 menu_verbose ("Processed <NotOnlyUnallocated/>\n");
3584 only_unallocated = FALSE;
3585 break;
3586
3587 case MENU_LAYOUT_NODE_DEFAULT_LAYOUT:
3588 menu_layout_node_default_layout_get_values (layout_iter,
3589 &directory->default_layout_values);
3590 collect_layout_info (layout_iter, &directory->default_layout_info);
3591 menu_verbose ("Processed <DefaultLayout/>\n");
3592 break;
3593
3594 case MENU_LAYOUT_NODE_LAYOUT:
3595 collect_layout_info (layout_iter, &directory->layout_info);
3596 menu_verbose ("Processed <Layout/>\n");
3597 break;
3598
3599 default:
3600 break;
3601 }
3602
3603 layout_iter = menu_layout_node_get_next (layout_iter);
3604 }
3605
3606 desktop_entry_set_unref (entry_pool);
3607
3608 directory->only_unallocated = only_unallocated;
3609
3610 if (!directory->only_unallocated)
3611 desktop_entry_set_union (allocated, allocated_set);
3612
3613 desktop_entry_set_unref (allocated_set);
3614
3615 if (directory->directory_entry)
3616 {
3617 if (desktop_entry_get_no_display (directory->directory_entry))
3618 {
3619 directory->is_nodisplay = TRUE;
3620
3621 if (!(tree->flags & GMENU_TREE_FLAGS_INCLUDE_NODISPLAY))
3622 {
3623 menu_verbose ("Not showing menu %s because NoDisplay=true\n",
3624 desktop_entry_get_name (directory->directory_entry));
3625 deleted = TRUE;
3626 }
3627 }
3628
3629 if (!desktop_entry_get_show_in (directory->directory_entry))
3630 {
3631 menu_verbose ("Not showing menu %s because OnlyShowIn!=$DESKTOP or NotShowIn=$DESKTOP (with $DESKTOP=${XDG_CURRENT_DESKTOP:-GNOME})\n",
3632 desktop_entry_get_name (directory->directory_entry));
3633 deleted = TRUE;
3634 }
3635 }
3636
3637 if (deleted)
3638 {
3639 if (excluded_set != NULL)
3640 desktop_entry_set_unref (excluded_set);
3641 desktop_entry_set_unref (entries);
3642 gmenu_tree_item_unref (directory);
3643 return NULL;
3644 }
3645
3646 desktop_entry_set_foreach (entries,
3647 (DesktopEntrySetForeachFunc) entries_listify_foreach,
3648 directory);
3649 desktop_entry_set_unref (entries);
3650
3651 if (excluded_set != NULL)
3652 {
3653 desktop_entry_set_foreach (excluded_set,
3654 (DesktopEntrySetForeachFunc) excluded_entries_listify_foreach,
3655 directory);
3656 desktop_entry_set_unref (excluded_set);
3657 }
3658
3659 tmp = directory->subdirs;
3660 while (tmp != NULL)
3661 {
3662 GMenuTreeDirectory *subdir = tmp->data;
3663
3664 set_default_layout_values (directory, subdir);
3665
3666 tmp = tmp->next;
3667 }
3668
3669 tmp = directory->entries;
3670 while (tmp != NULL)
3671 {
3672 GMenuTreeEntry *entry = tmp->data;
3673 GSList *next = tmp->next;
3674 gboolean delete = FALSE;
3675
3676 /* If adding a new condition to delete here, it has to be added to
3677 * get_still_unallocated_foreach() too */
3678
3679 if (desktop_entry_get_hidden (entry->desktop_entry))
3680 {
3681 menu_verbose ("Deleting %s because Hidden=true\n",
3682 desktop_entry_get_name (entry->desktop_entry));
3683 delete = TRUE;
3684 }
3685
3686 if (!(tree->flags & GMENU_TREE_FLAGS_INCLUDE_NODISPLAY) &&
3687 desktop_entry_get_no_display (entry->desktop_entry))
3688 {
3689 menu_verbose ("Deleting %s because NoDisplay=true\n",
3690 desktop_entry_get_name (entry->desktop_entry));
3691 delete = TRUE;
3692 }
3693
3694 if (!desktop_entry_get_show_in (entry->desktop_entry))
3695 {
3696 menu_verbose ("Deleting %s because OnlyShowIn!=$DESKTOP or NotShowIn=$DESKTOP (with $DESKTOP=${XDG_CURRENT_DESKTOP:-GNOME})\n",
3697 desktop_entry_get_name (entry->desktop_entry));
3698 delete = TRUE;
3699 }
3700
3701 /* No need to filter out based on TryExec since GDesktopAppInfo cannot
3702 * deal with .desktop files with a failed TryExec. */
3703
3704 if (delete)
3705 {
3706 directory->entries = g_slist_delete_link (directory->entries,
3707 tmp);
3708 gmenu_tree_item_unref_and_unset_parent (entry);
3709 }
3710
3711 tmp = next;
3712 }
3713
3714 g_assert (directory->name != NULL);
3715
3716 return directory;
3717 }
3718
3719 static void
3720 process_only_unallocated (GMenuTree *tree,
3721 GMenuTreeDirectory *directory,
3722 DesktopEntrySet *allocated,
3723 DesktopEntrySet *unallocated_used)
3724 {
3725 GSList *tmp;
3726
3727 /* For any directory marked only_unallocated, we have to remove any
3728 * entries that were in fact allocated.
3729 */
3730
3731 if (directory->only_unallocated)
3732 {
3733 tmp = directory->entries;
3734 while (tmp != NULL)
3735 {
3736 GMenuTreeEntry *entry = tmp->data;
3737 GSList *next = tmp->next;
3738
3739 if (desktop_entry_set_lookup (allocated, entry->desktop_file_id))
3740 {
3741 directory->entries = g_slist_delete_link (directory->entries,
3742 tmp);
3743 gmenu_tree_item_unref_and_unset_parent (entry);
3744 }
3745 else
3746 {
3747 desktop_entry_set_add_entry (unallocated_used, entry->desktop_entry, entry->desktop_file_id);
3748 }
3749
3750 tmp = next;
3751 }
3752 }
3753
3754 tmp = directory->subdirs;
3755 while (tmp != NULL)
3756 {
3757 GMenuTreeDirectory *subdir = tmp->data;
3758
3759 process_only_unallocated (tree, subdir, allocated, unallocated_used);
3760
3761 tmp = tmp->next;
3762 }
3763 }
3764
3765 typedef struct
3766 {
3767 GMenuTree *tree;
3768 DesktopEntrySet *allocated;
3769 DesktopEntrySet *unallocated_used;
3770 DesktopEntrySet *still_unallocated;
3771 } GetStillUnallocatedForeachData;
3772
3773 static void
3774 get_still_unallocated_foreach (const char *file_id,
3775 DesktopEntry *entry,
3776 GetStillUnallocatedForeachData *data)
3777 {
3778 if (desktop_entry_set_lookup (data->allocated, file_id))
3779 return;
3780
3781 if (desktop_entry_set_lookup (data->unallocated_used, file_id))
3782 return;
3783
3784 /* Same rules than at the end of process_layout() */
3785 if (desktop_entry_get_hidden (entry))
3786 return;
3787
3788 if (!(data->tree->flags & GMENU_TREE_FLAGS_INCLUDE_NODISPLAY) &&
3789 desktop_entry_get_no_display (entry))
3790 return;
3791
3792 if (!desktop_entry_get_show_in (entry))
3793 return;
3794
3795 desktop_entry_set_add_entry (data->still_unallocated, entry, file_id);
3796 }
3797
3798 static void preprocess_layout_info (GMenuTree *tree,
3799 GMenuTreeDirectory *directory);
3800
3801 static GSList *
3802 get_layout_info (GMenuTreeDirectory *directory,
3803 gboolean *is_default_layout)
3804 {
3805 GMenuTreeDirectory *iter;
3806
3807 if (directory->layout_info != NULL)
3808 {
3809 if (is_default_layout)
3810 {
3811 *is_default_layout = FALSE;
3812 }
3813 return directory->layout_info;
3814 }
3815
3816 /* Even if there's no layout information at all, the result will be an
3817 * implicit default layout */
3818 if (is_default_layout)
3819 {
3820 *is_default_layout = TRUE;
3821 }
3822
3823 iter = directory;
3824 while (iter != NULL)
3825 {
3826 /* FIXME: this is broken: we might skip real parent in the
3827 * XML structure, that are hidden because of inlining. */
3828 if (iter->default_layout_info != NULL)
3829 {
3830 return iter->default_layout_info;
3831 }
3832
3833 iter = GMENU_TREE_ITEM (iter)->parent;
3834 }
3835
3836 return NULL;
3837 }
3838
3839 static void
3840 get_values_with_defaults (MenuLayoutNode *node,
3841 MenuLayoutValues *layout_values,
3842 MenuLayoutValues *default_layout_values)
3843 {
3844 menu_layout_node_menuname_get_values (node, layout_values);
3845
3846 if (!(layout_values->mask & MENU_LAYOUT_VALUES_SHOW_EMPTY))
3847 layout_values->show_empty = default_layout_values->show_empty;
3848
3849 if (!(layout_values->mask & MENU_LAYOUT_VALUES_INLINE_MENUS))
3850 layout_values->inline_menus = default_layout_values->inline_menus;
3851
3852 if (!(layout_values->mask & MENU_LAYOUT_VALUES_INLINE_LIMIT))
3853 layout_values->inline_limit = default_layout_values->inline_limit;
3854
3855 if (!(layout_values->mask & MENU_LAYOUT_VALUES_INLINE_HEADER))
3856 layout_values->inline_header = default_layout_values->inline_header;
3857
3858 if (!(layout_values->mask & MENU_LAYOUT_VALUES_INLINE_ALIAS))
3859 layout_values->inline_alias = default_layout_values->inline_alias;
3860 }
3861
3862 static guint
3863 get_real_subdirs_len (GMenuTreeDirectory *directory)
3864 {
3865 guint len;
3866 GSList *tmp;
3867
3868 len = 0;
3869
3870 tmp = directory->subdirs;
3871 while (tmp != NULL)
3872 {
3873 GMenuTreeDirectory *subdir = tmp->data;
3874
3875 tmp = tmp->next;
3876
3877 if (subdir->will_inline_header != G_MAXUINT16)
3878 {
3879 len += get_real_subdirs_len (subdir) + g_slist_length (subdir->entries) + 1;
3880 }
3881 else
3882 len += 1;
3883 }
3884
3885 return len;
3886 }
3887
3888 static void
3889 preprocess_layout_info_subdir_helper (GMenuTree *tree,
3890 GMenuTreeDirectory *directory,
3891 GMenuTreeDirectory *subdir,
3892 MenuLayoutValues *layout_values,
3893 gboolean *contents_added,
3894 gboolean *should_remove)
3895 {
3896 preprocess_layout_info (tree, subdir);
3897
3898 *should_remove = FALSE;
3899 *contents_added = FALSE;
3900
3901 if (subdir->subdirs == NULL && subdir->entries == NULL)
3902 {
3903 if (!(tree->flags & GMENU_TREE_FLAGS_SHOW_EMPTY) &&
3904 !layout_values->show_empty)
3905 {
3906 menu_verbose ("Not showing empty menu '%s'\n", subdir->name);
3907 *should_remove = TRUE;
3908 }
3909 }
3910
3911 else if (layout_values->inline_menus)
3912 {
3913 guint real_subdirs_len;
3914
3915 real_subdirs_len = get_real_subdirs_len (subdir);
3916
3917 if (layout_values->inline_alias &&
3918 real_subdirs_len + g_slist_length (subdir->entries) == 1)
3919 {
3920 GMenuTreeAlias *alias;
3921 GMenuTreeItem *item;
3922 GSList *list;
3923
3924 if (subdir->subdirs != NULL)
3925 list = subdir->subdirs;
3926 else
3927 list = subdir->entries;
3928
3929 item = GMENU_TREE_ITEM (list->data);
3930
3931 menu_verbose ("Inline aliasing '%s' to '%s'\n",
3932 item->type == GMENU_TREE_ITEM_ENTRY ?
3933 g_app_info_get_name (G_APP_INFO (gmenu_tree_entry_get_app_info (GMENU_TREE_ENTRY (item)))) :
3934 (item->type == GMENU_TREE_ITEM_DIRECTORY ?
3935 gmenu_tree_directory_get_name (GMENU_TREE_DIRECTORY (item)) :
3936 gmenu_tree_directory_get_name (GMENU_TREE_ALIAS (item)->directory)),
3937 subdir->name);
3938
3939 alias = gmenu_tree_alias_new (directory, subdir, item);
3940
3941 g_slist_foreach (list,
3942 (GFunc) gmenu_tree_item_unref_and_unset_parent,
3943 NULL);
3944 g_slist_free (list);
3945 subdir->subdirs = NULL;
3946 subdir->entries = NULL;
3947
3948 if (item->type == GMENU_TREE_ITEM_DIRECTORY)
3949 directory->subdirs = g_slist_append (directory->subdirs, alias);
3950 else
3951 directory->entries = g_slist_append (directory->entries, alias);
3952
3953 *contents_added = TRUE;
3954 *should_remove = TRUE;
3955 }
3956
3957 else if (layout_values->inline_limit == 0 ||
3958 layout_values->inline_limit >= real_subdirs_len + g_slist_length (subdir->entries))
3959 {
3960 if (layout_values->inline_header)
3961 {
3962 menu_verbose ("Creating inline header with name '%s'\n", subdir->name);
3963 /* we're limited to 16-bits to spare some memory; if the limit is
3964 * higher than that (would be crazy), we just consider it's
3965 * unlimited */
3966 if (layout_values->inline_limit < G_MAXUINT16)
3967 subdir->will_inline_header = layout_values->inline_limit;
3968 else
3969 subdir->will_inline_header = 0;
3970 }
3971 else
3972 {
3973 g_slist_foreach (subdir->subdirs,
3974 (GFunc) gmenu_tree_item_set_parent,
3975 directory);
3976 directory->subdirs = g_slist_concat (directory->subdirs,
3977 subdir->subdirs);
3978 subdir->subdirs = NULL;
3979
3980 g_slist_foreach (subdir->entries,
3981 (GFunc) gmenu_tree_item_set_parent,
3982 directory);
3983 directory->entries = g_slist_concat (directory->entries,
3984 subdir->entries);
3985 subdir->entries = NULL;
3986
3987 *contents_added = TRUE;
3988 *should_remove = TRUE;
3989 }
3990
3991 menu_verbose ("Inlining directory contents of '%s' to '%s'\n",
3992 subdir->name, directory->name);
3993 }
3994 }
3995 }
3996
3997 static void
3998 preprocess_layout_info (GMenuTree *tree,
3999 GMenuTreeDirectory *directory)
4000 {
4001 GSList *tmp;
4002 GSList *layout_info;
4003 gboolean using_default_layout;
4004 GSList *last_subdir;
4005 gboolean strip_duplicates;
4006 gboolean contents_added;
4007 gboolean should_remove;
4008 GSList *subdirs_sentinel;
4009
4010 /* Note: we need to preprocess all menus, even if the layout mask for a menu
4011 * is MENU_LAYOUT_VALUES_NONE: in this case, we need to remove empty menus;
4012 * and the layout mask can be different for a submenu anyway */
4013
4014 menu_verbose ("Processing menu layout inline hints for %s\n", directory->name);
4015 g_assert (!directory->preprocessed);
4016
4017 strip_duplicates = FALSE;
4018 /* we use last_subdir to track the last non-inlined subdirectory */
4019 last_subdir = g_slist_last (directory->subdirs);
4020
4021 /*
4022 * First process subdirectories with explicit layout
4023 */
4024 layout_info = get_layout_info (directory, &using_default_layout);
4025 tmp = layout_info;
4026 /* see comment below about Menuname to understand why we leave the loop if
4027 * last_subdir is NULL */
4028 while (tmp != NULL && last_subdir != NULL)
4029 {
4030 MenuLayoutNode *node = tmp->data;
4031 MenuLayoutValues layout_values;
4032 const char *name;
4033 GMenuTreeDirectory *subdir;
4034 GSList *subdir_l;
4035
4036 tmp = tmp->next;
4037
4038 /* only Menuname nodes are relevant here */
4039 if (menu_layout_node_get_type (node) != MENU_LAYOUT_NODE_MENUNAME)
4040 continue;
4041
4042 get_values_with_defaults (node,
4043 &layout_values,
4044 &directory->default_layout_values);
4045
4046 /* find the subdirectory that is affected by those attributes */
4047 name = menu_layout_node_get_content (node);
4048 subdir = NULL;
4049 subdir_l = directory->subdirs;
4050 while (subdir_l != NULL)
4051 {
4052 subdir = subdir_l->data;
4053
4054 if (!strcmp (subdir->name, name))
4055 break;
4056
4057 subdir = NULL;
4058 subdir_l = subdir_l->next;
4059
4060 /* We do not want to use Menuname on a menu that appeared via
4061 * inlining: without inlining, the Menuname wouldn't have matched
4062 * anything, and we want to keep the same behavior.
4063 * Unless the layout is a default layout, in which case the Menuname
4064 * does match the subdirectory. */
4065 if (!using_default_layout && subdir_l == last_subdir)
4066 {
4067 subdir_l = NULL;
4068 break;
4069 }
4070 }
4071
4072 if (subdir == NULL)
4073 continue;
4074
4075 preprocess_layout_info_subdir_helper (tree, directory,
4076 subdir, &layout_values,
4077 &contents_added, &should_remove);
4078 strip_duplicates = strip_duplicates || contents_added;
4079 if (should_remove)
4080 {
4081 if (last_subdir == subdir_l)
4082 {
4083 /* we need to recompute last_subdir since we'll remove it from
4084 * the list */
4085 GSList *buf;
4086
4087 if (subdir_l == directory->subdirs)
4088 last_subdir = NULL;
4089 else
4090 {
4091 buf = directory->subdirs;
4092 while (buf != NULL && buf->next != subdir_l)
4093 buf = buf->next;
4094 last_subdir = buf;
4095 }
4096 }
4097
4098 directory->subdirs = g_slist_remove (directory->subdirs, subdir);
4099 gmenu_tree_item_unref_and_unset_parent (GMENU_TREE_ITEM (subdir));
4100 }
4101 }
4102
4103 /*
4104 * Now process the subdirectories with no explicit layout
4105 */
4106 /* this is bogus data, but we just need the pointer anyway */
4107 subdirs_sentinel = g_slist_prepend (directory->subdirs, PACKAGE);
4108 directory->subdirs = subdirs_sentinel;
4109
4110 tmp = directory->subdirs;
4111 while (tmp->next != NULL)
4112 {
4113 GMenuTreeDirectory *subdir = tmp->next->data;
4114
4115 if (subdir->preprocessed)
4116 {
4117 tmp = tmp->next;
4118 continue;
4119 }
4120
4121 preprocess_layout_info_subdir_helper (tree, directory,
4122 subdir, &directory->default_layout_values,
4123 &contents_added, &should_remove);
4124 strip_duplicates = strip_duplicates || contents_added;
4125 if (should_remove)
4126 {
4127 tmp = g_slist_delete_link (tmp, tmp->next);
4128 gmenu_tree_item_unref_and_unset_parent (GMENU_TREE_ITEM (subdir));
4129 }
4130 else
4131 tmp = tmp->next;
4132 }
4133
4134 /* remove the sentinel */
4135 directory->subdirs = g_slist_delete_link (directory->subdirs,
4136 directory->subdirs);
4137
4138 /*
4139 * Finally, remove duplicates if needed
4140 */
4141 if (strip_duplicates)
4142 {
4143 /* strip duplicate entries; there should be no duplicate directories */
4144 directory->entries = g_slist_sort (directory->entries,
4145 (GCompareFunc) gmenu_tree_entry_compare_by_id);
4146 tmp = directory->entries;
4147 while (tmp != NULL && tmp->next != NULL)
4148 {
4149 GMenuTreeItem *a = tmp->data;
4150 GMenuTreeItem *b = tmp->next->data;
4151
4152 if (a->type == GMENU_TREE_ITEM_ALIAS)
4153 a = GMENU_TREE_ALIAS (a)->aliased_item;
4154
4155 if (b->type == GMENU_TREE_ITEM_ALIAS)
4156 b = GMENU_TREE_ALIAS (b)->aliased_item;
4157
4158 if (strcmp (GMENU_TREE_ENTRY (a)->desktop_file_id,
4159 GMENU_TREE_ENTRY (b)->desktop_file_id) == 0)
4160 {
4161 tmp = g_slist_delete_link (tmp, tmp->next);
4162 gmenu_tree_item_unref (b);
4163 }
4164 else
4165 tmp = tmp->next;
4166 }
4167 }
4168
4169 directory->preprocessed = TRUE;
4170 }
4171
4172 static void process_layout_info (GMenuTree *tree,
4173 GMenuTreeDirectory *directory);
4174
4175 static void
4176 check_pending_separator (GMenuTreeDirectory *directory)
4177 {
4178 if (directory->layout_pending_separator)
4179 {
4180 menu_verbose ("Adding pending separator in '%s'\n", directory->name);
4181
4182 directory->contents = g_slist_append (directory->contents,
4183 gmenu_tree_separator_new (directory));
4184 directory->layout_pending_separator = FALSE;
4185 }
4186 }
4187
4188 static void
4189 merge_alias (GMenuTree *tree,
4190 GMenuTreeDirectory *directory,
4191 GMenuTreeAlias *alias)
4192 {
4193 menu_verbose ("Merging alias '%s' in directory '%s'\n",
4194 alias->directory->name, directory->name);
4195
4196 if (alias->aliased_item->type == GMENU_TREE_ITEM_DIRECTORY)
4197 {
4198 process_layout_info (tree, GMENU_TREE_DIRECTORY (alias->aliased_item));
4199 }
4200
4201 check_pending_separator (directory);
4202
4203 directory->contents = g_slist_append (directory->contents,
4204 gmenu_tree_item_ref (alias));
4205 }
4206
4207 static void
4208 merge_subdir (GMenuTree *tree,
4209 GMenuTreeDirectory *directory,
4210 GMenuTreeDirectory *subdir)
4211 {
4212 menu_verbose ("Merging subdir '%s' in directory '%s'\n",
4213 subdir->name, directory->name);
4214
4215 process_layout_info (tree, subdir);
4216
4217 check_pending_separator (directory);
4218
4219 if (subdir->will_inline_header == 0 ||
4220 (subdir->will_inline_header != G_MAXUINT16 &&
4221 g_slist_length (subdir->contents) <= subdir->will_inline_header))
4222 {
4223 GMenuTreeHeader *header;
4224
4225 header = gmenu_tree_header_new (directory, subdir);
4226 directory->contents = g_slist_append (directory->contents, header);
4227
4228 g_slist_foreach (subdir->contents,
4229 (GFunc) gmenu_tree_item_set_parent,
4230 directory);
4231 directory->contents = g_slist_concat (directory->contents,
4232 subdir->contents);
4233 subdir->contents = NULL;
4234 subdir->will_inline_header = G_MAXUINT16;
4235
4236 gmenu_tree_item_set_parent (GMENU_TREE_ITEM (subdir), NULL);
4237 }
4238 else
4239 {
4240 directory->contents = g_slist_append (directory->contents,
4241 gmenu_tree_item_ref (subdir));
4242 }
4243 }
4244
4245 static void
4246 merge_subdir_by_name (GMenuTree *tree,
4247 GMenuTreeDirectory *directory,
4248 const char *subdir_name)
4249 {
4250 GSList *tmp;
4251
4252 menu_verbose ("Attempting to merge subdir '%s' in directory '%s'\n",
4253 subdir_name, directory->name);
4254
4255 tmp = directory->subdirs;
4256 while (tmp != NULL)
4257 {
4258 GMenuTreeDirectory *subdir = tmp->data;
4259 GSList *next = tmp->next;
4260
4261 /* if it's an alias, then it cannot be affected by
4262 * the Merge nodes in the layout */
4263 if (GMENU_TREE_ITEM (subdir)->type == GMENU_TREE_ITEM_ALIAS)
4264 continue;
4265
4266 if (!strcmp (subdir->name, subdir_name))
4267 {
4268 directory->subdirs = g_slist_delete_link (directory->subdirs, tmp);
4269 merge_subdir (tree, directory, subdir);
4270 gmenu_tree_item_unref (subdir);
4271 }
4272
4273 tmp = next;
4274 }
4275 }
4276
4277 static void
4278 merge_entry (GMenuTree *tree,
4279 GMenuTreeDirectory *directory,
4280 GMenuTreeEntry *entry)
4281 {
4282 menu_verbose ("Merging entry '%s' in directory '%s'\n",
4283 entry->desktop_file_id, directory->name);
4284
4285 check_pending_separator (directory);
4286 directory->contents = g_slist_append (directory->contents,
4287 gmenu_tree_item_ref (entry));
4288 }
4289
4290 static void
4291 merge_entry_by_id (GMenuTree *tree,
4292 GMenuTreeDirectory *directory,
4293 const char *file_id)
4294 {
4295 GSList *tmp;
4296
4297 menu_verbose ("Attempting to merge entry '%s' in directory '%s'\n",
4298 file_id, directory->name);
4299
4300 tmp = directory->entries;
4301 while (tmp != NULL)
4302 {
4303 GMenuTreeEntry *entry = tmp->data;
4304 GSList *next = tmp->next;
4305
4306 /* if it's an alias, then it cannot be affected by
4307 * the Merge nodes in the layout */
4308 if (GMENU_TREE_ITEM (entry)->type == GMENU_TREE_ITEM_ALIAS)
4309 continue;
4310
4311 if (!strcmp (entry->desktop_file_id, file_id))
4312 {
4313 directory->entries = g_slist_delete_link (directory->entries, tmp);
4314 merge_entry (tree, directory, entry);
4315 gmenu_tree_item_unref (entry);
4316 }
4317
4318 tmp = next;
4319 }
4320 }
4321
4322 static inline gboolean
4323 find_name_in_list (const char *name,
4324 GSList *list)
4325 {
4326 while (list != NULL)
4327 {
4328 if (!strcmp (name, list->data))
4329 return TRUE;
4330
4331 list = list->next;
4332 }
4333
4334 return FALSE;
4335 }
4336
4337 static void
4338 merge_subdirs (GMenuTree *tree,
4339 GMenuTreeDirectory *directory,
4340 GSList *except)
4341 {
4342 GSList *subdirs;
4343 GSList *tmp;
4344
4345 menu_verbose ("Merging subdirs in directory '%s'\n", directory->name);
4346
4347 subdirs = directory->subdirs;
4348 directory->subdirs = NULL;
4349
4350 subdirs = g_slist_sort_with_data (subdirs,
4351 (GCompareDataFunc) gmenu_tree_item_compare,
4352 GINT_TO_POINTER (GMENU_TREE_FLAGS_NONE));
4353
4354 tmp = subdirs;
4355 while (tmp != NULL)
4356 {
4357 GMenuTreeDirectory *subdir = tmp->data;
4358
4359 if (GMENU_TREE_ITEM (subdir)->type == GMENU_TREE_ITEM_ALIAS)
4360 {
4361 merge_alias (tree, directory, GMENU_TREE_ALIAS (subdir));
4362 gmenu_tree_item_unref (subdir);
4363 }
4364 else if (!find_name_in_list (subdir->name, except))
4365 {
4366 merge_subdir (tree, directory, subdir);
4367 gmenu_tree_item_unref (subdir);
4368 }
4369 else
4370 {
4371 menu_verbose ("Not merging directory '%s' yet\n", subdir->name);
4372 directory->subdirs = g_slist_append (directory->subdirs, subdir);
4373 }
4374
4375 tmp = tmp->next;
4376 }
4377
4378 g_slist_free (subdirs);
4379 g_slist_free (except);
4380 }
4381
4382 static void
4383 merge_entries (GMenuTree *tree,
4384 GMenuTreeDirectory *directory,
4385 GSList *except)
4386 {
4387 GSList *entries;
4388 GSList *tmp;
4389
4390 menu_verbose ("Merging entries in directory '%s'\n", directory->name);
4391
4392 entries = directory->entries;
4393 directory->entries = NULL;
4394
4395 entries = g_slist_sort_with_data (entries,
4396 (GCompareDataFunc) gmenu_tree_item_compare,
4397 GINT_TO_POINTER (tree->flags));
4398
4399 tmp = entries;
4400 while (tmp != NULL)
4401 {
4402 GMenuTreeEntry *entry = tmp->data;
4403
4404 if (GMENU_TREE_ITEM (entry)->type == GMENU_TREE_ITEM_ALIAS)
4405 {
4406 merge_alias (tree, directory, GMENU_TREE_ALIAS (entry));
4407 gmenu_tree_item_unref (entry);
4408 }
4409 else if (!find_name_in_list (entry->desktop_file_id, except))
4410 {
4411 merge_entry (tree, directory, entry);
4412 gmenu_tree_item_unref (entry);
4413 }
4414 else
4415 {
4416 menu_verbose ("Not merging entry '%s' yet\n", entry->desktop_file_id);
4417 directory->entries = g_slist_append (directory->entries, entry);
4418 }
4419
4420 tmp = tmp->next;
4421 }
4422
4423 g_slist_free (entries);
4424 g_slist_free (except);
4425 }
4426
4427 static void
4428 merge_subdirs_and_entries (GMenuTree *tree,
4429 GMenuTreeDirectory *directory,
4430 GSList *except_subdirs,
4431 GSList *except_entries)
4432 {
4433 GSList *items;
4434 GSList *tmp;
4435
4436 menu_verbose ("Merging subdirs and entries together in directory %s\n",
4437 directory->name);
4438
4439 items = g_slist_concat (directory->subdirs, directory->entries);
4440
4441 directory->subdirs = NULL;
4442 directory->entries = NULL;
4443
4444 items = g_slist_sort_with_data (items,
4445 (GCompareDataFunc) gmenu_tree_item_compare,
4446 GINT_TO_POINTER (tree->flags));
4447
4448 tmp = items;
4449 while (tmp != NULL)
4450 {
4451 GMenuTreeItem *item = tmp->data;
4452 GMenuTreeItemType type;
4453
4454 type = item->type;
4455
4456 if (type == GMENU_TREE_ITEM_ALIAS)
4457 {
4458 merge_alias (tree, directory, GMENU_TREE_ALIAS (item));
4459 gmenu_tree_item_unref (item);
4460 }
4461 else if (type == GMENU_TREE_ITEM_DIRECTORY)
4462 {
4463 if (!find_name_in_list (GMENU_TREE_DIRECTORY (item)->name, except_subdirs))
4464 {
4465 merge_subdir (tree,
4466 directory,
4467 GMENU_TREE_DIRECTORY (item));
4468 gmenu_tree_item_unref (item);
4469 }
4470 else
4471 {
4472 menu_verbose ("Not merging directory '%s' yet\n",
4473 GMENU_TREE_DIRECTORY (item)->name);
4474 directory->subdirs = g_slist_append (directory->subdirs, item);
4475 }
4476 }
4477 else if (type == GMENU_TREE_ITEM_ENTRY)
4478 {
4479 if (!find_name_in_list (GMENU_TREE_ENTRY (item)->desktop_file_id, except_entries))
4480 {
4481 merge_entry (tree, directory, GMENU_TREE_ENTRY (item));
4482 gmenu_tree_item_unref (item);
4483 }
4484 else
4485 {
4486 menu_verbose ("Not merging entry '%s' yet\n",
4487 GMENU_TREE_ENTRY (item)->desktop_file_id);
4488 directory->entries = g_slist_append (directory->entries, item);
4489 }
4490 }
4491 else
4492 {
4493 g_assert_not_reached ();
4494 }
4495
4496 tmp = tmp->next;
4497 }
4498
4499 g_slist_free (items);
4500 g_slist_free (except_subdirs);
4501 g_slist_free (except_entries);
4502 }
4503
4504 static GSList *
4505 get_subdirs_from_layout_info (GSList *layout_info)
4506 {
4507 GSList *subdirs;
4508 GSList *tmp;
4509
4510 subdirs = NULL;
4511
4512 tmp = layout_info;
4513 while (tmp != NULL)
4514 {
4515 MenuLayoutNode *node = tmp->data;
4516
4517 if (menu_layout_node_get_type (node) == MENU_LAYOUT_NODE_MENUNAME)
4518 {
4519 subdirs = g_slist_append (subdirs,
4520 (char *) menu_layout_node_get_content (node));
4521 }
4522
4523 tmp = tmp->next;
4524 }
4525
4526 return subdirs;
4527 }
4528
4529 static GSList *
4530 get_entries_from_layout_info (GSList *layout_info)
4531 {
4532 GSList *entries;
4533 GSList *tmp;
4534
4535 entries = NULL;
4536
4537 tmp = layout_info;
4538 while (tmp != NULL)
4539 {
4540 MenuLayoutNode *node = tmp->data;
4541
4542 if (menu_layout_node_get_type (node) == MENU_LAYOUT_NODE_FILENAME)
4543 {
4544 entries = g_slist_append (entries,
4545 (char *) menu_layout_node_get_content (node));
4546 }
4547
4548 tmp = tmp->next;
4549 }
4550
4551 return entries;
4552 }
4553
4554 static void
4555 process_layout_info (GMenuTree *tree,
4556 GMenuTreeDirectory *directory)
4557 {
4558 GSList *layout_info;
4559
4560 menu_verbose ("Processing menu layout hints for %s\n", directory->name);
4561
4562 g_slist_foreach (directory->contents,
4563 (GFunc) gmenu_tree_item_unref_and_unset_parent,
4564 NULL);
4565 g_slist_free (directory->contents);
4566 directory->contents = NULL;
4567 directory->layout_pending_separator = FALSE;
4568
4569 layout_info = get_layout_info (directory, NULL);
4570
4571 if (layout_info == NULL)
4572 {
4573 merge_subdirs (tree, directory, NULL);
4574 merge_entries (tree, directory, NULL);
4575 }
4576 else
4577 {
4578 GSList *tmp;
4579
4580 tmp = layout_info;
4581 while (tmp != NULL)
4582 {
4583 MenuLayoutNode *node = tmp->data;
4584
4585 switch (menu_layout_node_get_type (node))
4586 {
4587 case MENU_LAYOUT_NODE_MENUNAME:
4588 merge_subdir_by_name (tree,
4589 directory,
4590 menu_layout_node_get_content (node));
4591 break;
4592
4593 case MENU_LAYOUT_NODE_FILENAME:
4594 merge_entry_by_id (tree,
4595 directory,
4596 menu_layout_node_get_content (node));
4597 break;
4598
4599 case MENU_LAYOUT_NODE_SEPARATOR:
4600 /* Unless explicitly told to show all separators, do not show a
4601 * separator at the beginning of a menu. Note that we don't add
4602 * the separators now, and instead make it pending. This way, we
4603 * won't show two consecutive separators nor will we show a
4604 * separator at the end of a menu. */
4605 if (tree->flags & GMENU_TREE_FLAGS_SHOW_ALL_SEPARATORS)
4606 {
4607 directory->layout_pending_separator = TRUE;
4608 check_pending_separator (directory);
4609 }
4610 else if (directory->contents)
4611 {
4612 menu_verbose ("Adding a potential separator in '%s'\n",
4613 directory->name);
4614
4615 directory->layout_pending_separator = TRUE;
4616 }
4617 else
4618 {
4619 menu_verbose ("Skipping separator at the beginning of '%s'\n",
4620 directory->name);
4621 }
4622 break;
4623
4624 case MENU_LAYOUT_NODE_MERGE:
4625 switch (menu_layout_node_merge_get_type (node))
4626 {
4627 case MENU_LAYOUT_MERGE_NONE:
4628 break;
4629
4630 case MENU_LAYOUT_MERGE_MENUS:
4631 merge_subdirs (tree,
4632 directory,
4633 get_subdirs_from_layout_info (tmp->next));
4634 break;
4635
4636 case MENU_LAYOUT_MERGE_FILES:
4637 merge_entries (tree,
4638 directory,
4639 get_entries_from_layout_info (tmp->next));
4640 break;
4641
4642 case MENU_LAYOUT_MERGE_ALL:
4643 merge_subdirs_and_entries (tree,
4644 directory,
4645 get_subdirs_from_layout_info (tmp->next),
4646 get_entries_from_layout_info (tmp->next));
4647 break;
4648
4649 default:
4650 g_assert_not_reached ();
4651 break;
4652 }
4653 break;
4654
4655 default:
4656 g_assert_not_reached ();
4657 break;
4658 }
4659
4660 tmp = tmp->next;
4661 }
4662 }
4663
4664 g_slist_foreach (directory->subdirs,
4665 (GFunc) gmenu_tree_item_unref,
4666 NULL);
4667 g_slist_free (directory->subdirs);
4668 directory->subdirs = NULL;
4669
4670 g_slist_foreach (directory->entries,
4671 (GFunc) gmenu_tree_item_unref,
4672 NULL);
4673 g_slist_free (directory->entries);
4674 directory->entries = NULL;
4675
4676 g_slist_foreach (directory->default_layout_info,
4677 (GFunc) menu_layout_node_unref,
4678 NULL);
4679 g_slist_free (directory->default_layout_info);
4680 directory->default_layout_info = NULL;
4681
4682 g_slist_foreach (directory->layout_info,
4683 (GFunc) menu_layout_node_unref,
4684 NULL);
4685 g_slist_free (directory->layout_info);
4686 directory->layout_info = NULL;
4687 }
4688
4689 static void
4690 handle_entries_changed (MenuLayoutNode *layout,
4691 GMenuTree *tree)
4692 {
4693 if (tree->layout == layout)
4694 {
4695 gmenu_tree_force_rebuild (tree);
4696 gmenu_tree_invoke_monitors (tree);
4697 }
4698 }
4699
4700 static void
4701 update_entry_index (GMenuTree *tree,
4702 GMenuTreeDirectory *dir)
4703 {
4704 GMenuTreeIter *iter = gmenu_tree_directory_iter (dir);
4705 GMenuTreeItemType next_type;
4706
4707 while ((next_type = gmenu_tree_iter_next (iter)) != GMENU_TREE_ITEM_INVALID)
4708 {
4709 gpointer item = NULL;
4710
4711 switch (next_type)
4712 {
4713 case GMENU_TREE_ITEM_ENTRY:
4714 {
4715 const char *id;
4716
4717 item = gmenu_tree_iter_get_entry (iter);
4718 id = gmenu_tree_entry_get_desktop_file_id (item);
4719 if (id != NULL)
4720 g_hash_table_insert (tree->entries_by_id, (char*)id, item);
4721 }
4722 break;
4723 case GMENU_TREE_ITEM_DIRECTORY:
4724 {
4725 item = gmenu_tree_iter_get_directory (iter);
4726 update_entry_index (tree, (GMenuTreeDirectory*)item);
4727 }
4728 break;
4729 default:
4730 break;
4731 }
4732 if (item != NULL)
4733 gmenu_tree_item_unref (item);
4734 }
4735
4736 gmenu_tree_iter_unref (iter);
4737 }
4738
4739 static gboolean
4740 gmenu_tree_build_from_layout (GMenuTree *tree,
4741 GError **error)
4742 {
4743 DesktopEntrySet *allocated;
4744
4745 if (tree->root)
4746 return TRUE;
4747
4748 if (!gmenu_tree_load_layout (tree, error))
4749 return FALSE;
4750
4751 menu_verbose ("Building menu tree from layout\n");
4752
4753 allocated = desktop_entry_set_new ();
4754
4755 /* create the menu structure */
4756 tree->root = process_layout (tree,
4757 NULL,
4758 find_menu_child (tree->layout),
4759 allocated);
4760 if (tree->root)
4761 {
4762 DesktopEntrySet *unallocated_used;
4763
4764 unallocated_used = desktop_entry_set_new ();
4765
4766 process_only_unallocated (tree, tree->root, allocated, unallocated_used);
4767 if (tree->flags & GMENU_TREE_FLAGS_INCLUDE_UNALLOCATED)
4768 {
4769 DesktopEntrySet *entry_pool;
4770 DesktopEntrySet *still_unallocated;
4771 GetStillUnallocatedForeachData data;
4772
4773 entry_pool = _entry_directory_list_get_all_desktops (menu_layout_node_menu_get_app_dirs (find_menu_child (tree->layout)));
4774 still_unallocated = desktop_entry_set_new ();
4775
4776 data.tree = tree;
4777 data.allocated = allocated;
4778 data.unallocated_used = unallocated_used;
4779 data.still_unallocated = still_unallocated;
4780
4781 desktop_entry_set_foreach (entry_pool,
4782 (DesktopEntrySetForeachFunc) get_still_unallocated_foreach,
4783 &data);
4784
4785 desktop_entry_set_unref (entry_pool);
4786
4787 desktop_entry_set_foreach (still_unallocated,
4788 (DesktopEntrySetForeachFunc) unallocated_entries_listify_foreach,
4789 tree->root);
4790
4791 desktop_entry_set_unref (still_unallocated);
4792 }
4793
4794 desktop_entry_set_unref (unallocated_used);
4795
4796 /* process the layout info part that can move/remove items:
4797 * inline, show_empty, etc. */
4798 preprocess_layout_info (tree, tree->root);
4799 /* populate the menu structure that we got with the items, and order it
4800 * according to the layout info */
4801 process_layout_info (tree, tree->root);
4802
4803 update_entry_index (tree, tree->root);
4804
4805 menu_layout_node_root_add_entries_monitor (tree->layout,
4806 (MenuLayoutNodeEntriesChangedFunc) handle_entries_changed,
4807 tree);
4808 }
4809
4810 desktop_entry_set_unref (allocated);
4811
4812 return TRUE;
4813 }
4814
4815 static void
4816 gmenu_tree_force_rebuild (GMenuTree *tree)
4817 {
4818 if (tree->root)
4819 {
4820 g_hash_table_remove_all (tree->entries_by_id);
4821 gmenu_tree_item_unref (tree->root);
4822 tree->root = NULL;
4823 tree->loaded = FALSE;
4824
4825 g_assert (tree->layout != NULL);
4826
4827 menu_layout_node_root_remove_entries_monitor (tree->layout,
4828 (MenuLayoutNodeEntriesChangedFunc) handle_entries_changed,
4829 tree);
4830 }
4831 }
4832
4833 GType
4834 gmenu_tree_iter_get_type (void)
4835 {
4836 static GType gtype = G_TYPE_INVALID;
4837 if (gtype == G_TYPE_INVALID)
4838 {
4839 gtype = g_boxed_type_register_static ("GMenuTreeIter",
4840 (GBoxedCopyFunc)gmenu_tree_iter_ref,
4841 (GBoxedFreeFunc)gmenu_tree_iter_unref);
4842 }
4843 return gtype;
4844 }
4845
4846 GType
4847 gmenu_tree_directory_get_type (void)
4848 {
4849 static GType gtype = G_TYPE_INVALID;
4850 if (gtype == G_TYPE_INVALID)
4851 {
4852 gtype = g_boxed_type_register_static ("GMenuTreeDirectory",
4853 (GBoxedCopyFunc)gmenu_tree_item_ref,
4854 (GBoxedFreeFunc)gmenu_tree_item_unref);
4855 }
4856 return gtype;
4857 }
4858
4859 GType
4860 gmenu_tree_entry_get_type (void)
4861 {
4862 static GType gtype = G_TYPE_INVALID;
4863 if (gtype == G_TYPE_INVALID)
4864 {
4865 gtype = g_boxed_type_register_static ("GMenuTreeEntry",
4866 (GBoxedCopyFunc)gmenu_tree_item_ref,
4867 (GBoxedFreeFunc)gmenu_tree_item_unref);
4868 }
4869 return gtype;
4870 }
4871
4872 GType
4873 gmenu_tree_separator_get_type (void)
4874 {
4875 static GType gtype = G_TYPE_INVALID;
4876 if (gtype == G_TYPE_INVALID)
4877 {
4878 gtype = g_boxed_type_register_static ("GMenuTreeSeparator",
4879 (GBoxedCopyFunc)gmenu_tree_item_ref,
4880 (GBoxedFreeFunc)gmenu_tree_item_unref);
4881 }
4882 return gtype;
4883 }
4884
4885 GType
4886 gmenu_tree_header_get_type (void)
4887 {
4888 static GType gtype = G_TYPE_INVALID;
4889 if (gtype == G_TYPE_INVALID)
4890 {
4891 gtype = g_boxed_type_register_static ("GMenuTreeHeader",
4892 (GBoxedCopyFunc)gmenu_tree_item_ref,
4893 (GBoxedFreeFunc)gmenu_tree_item_unref);
4894 }
4895 return gtype;
4896 }
4897
4898 GType
4899 gmenu_tree_alias_get_type (void)
4900 {
4901 static GType gtype = G_TYPE_INVALID;
4902 if (gtype == G_TYPE_INVALID)
4903 {
4904 gtype = g_boxed_type_register_static ("GMenuTreeAlias",
4905 (GBoxedCopyFunc)gmenu_tree_item_ref,
4906 (GBoxedFreeFunc)gmenu_tree_item_unref);
4907 }
4908 return gtype;
4909 }
4910
4911 GType
4912 gmenu_tree_flags_get_type (void)
4913 {
4914 static GType enum_type_id = 0;
4915 if (G_UNLIKELY (!enum_type_id))
4916 {
4917 static const GFlagsValue values[] = {
4918 { GMENU_TREE_FLAGS_NONE, "GMENU_TREE_FLAGS_NONE", "none" },
4919 { GMENU_TREE_FLAGS_INCLUDE_EXCLUDED, "GMENU_TREE_FLAGS_INCLUDE_EXCLUDED", "include-excluded" },
4920 { GMENU_TREE_FLAGS_SHOW_EMPTY, "GMENU_TREE_FLAGS_SHOW_EMPTY", "show-empty" },
4921 { GMENU_TREE_FLAGS_INCLUDE_NODISPLAY, "GMENU_TREE_FLAGS_INCLUDE_NODISPLAY", "include-nodisplay" },
4922 { GMENU_TREE_FLAGS_SHOW_ALL_SEPARATORS, "GMENU_TREE_FLAGS_SHOW_ALL_SEPARATORS", "show-all-separators" },
4923 { GMENU_TREE_FLAGS_SORT_DISPLAY_NAME, "GMENU_TREE_FLAGS_SORT_DISPLAY_NAME", "sort-display-name" },
4924 { GMENU_TREE_FLAGS_INCLUDE_UNALLOCATED, "GMENU_TREE_FLAGS_INCLUDE_UNALLOCATED,", "include-unallocated" },
4925 { 0, NULL, NULL }
4926 };
4927 enum_type_id = g_flags_register_static ("GMenuTreeFlags", values);
4928 }
4929 return enum_type_id;
4930 }
0 /*
1 * Copyright (C) 2002 - 2004 Red Hat, Inc.
2 *
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2 of the License, or (at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the
15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 * Boston, MA 02111-1307, USA.
17 */
18
19 #include <config.h>
20
21 #include "desktop-entries.h"
22 #include <gio/gdesktopappinfo.h>
23
24 #include <string.h>
25
26 #include "menu-util.h"
27
28 #define DESKTOP_ENTRY_GROUP "Desktop Entry"
29
30 struct DesktopEntry
31 {
32 guint refcount;
33
34 char *path;
35 const char *basename;
36
37 guint type : 2;
38 guint reserved : 30;
39 };
40
41 typedef struct
42 {
43 DesktopEntry base;
44
45 GDesktopAppInfo *appinfo;
46 GQuark *categories;
47 } DesktopEntryDesktop;
48
49 typedef struct
50 {
51 DesktopEntry base;
52
53 char *name;
54 char *generic_name;
55 char *comment;
56 GIcon *icon;
57
58 guint nodisplay : 1;
59 guint hidden : 1;
60 guint showin : 1;
61 } DesktopEntryDirectory;
62
63 struct DesktopEntrySet
64 {
65 int refcount;
66 GHashTable *hash;
67 };
68
69 /*
70 * Desktop entries
71 */
72
73 /**
74 * unix_basename_from_path:
75 * @path: Path string
76 *
77 * Returns: A constant pointer into the basename of @path
78 */
79 static const char *
80 unix_basename_from_path (const char *path)
81 {
82 const char *basename = g_strrstr (path, "/");
83 if (basename)
84 return basename + 1;
85 else
86 return path;
87 }
88
89 static const char *
90 get_current_desktop (void)
91 {
92 static char *current_desktop = NULL;
93
94 /* Support XDG_CURRENT_DESKTOP environment variable; this can be used
95 * to abuse gnome-menus in non-GNOME desktops. */
96 if (!current_desktop)
97 {
98 const char *desktop;
99
100 desktop = g_getenv ("XDG_CURRENT_DESKTOP");
101
102 /* Note: if XDG_CURRENT_DESKTOP is set but empty, do as if it
103 * was not set */
104 if (!desktop || desktop[0] == '\0')
105 current_desktop = g_strdup ("GNOME");
106 else
107 current_desktop = g_strdup (desktop);
108 }
109
110 /* Using "*" means skipping desktop-related checks */
111 if (g_strcmp0 (current_desktop, "*") == 0)
112 return NULL;
113
114 return current_desktop;
115 }
116
117 static GIcon *
118 key_file_get_icon (GKeyFile *key_file)
119 {
120 GIcon *icon = NULL;
121 gchar *icon_name;
122
123 icon_name = g_key_file_get_locale_string (key_file, DESKTOP_ENTRY_GROUP,
124 "Icon", NULL, NULL);
125 if (!icon_name)
126 return NULL;
127
128 if (g_path_is_absolute (icon_name)) {
129 GFile *file;
130
131 file = g_file_new_for_path (icon_name);
132 icon = g_file_icon_new (file);
133 g_object_unref (file);
134 } else {
135 char *p;
136
137 /* Work around a common mistake in desktop files */
138 if ((p = strrchr (icon_name, '.')) != NULL &&
139 (strcmp (p, ".png") == 0 ||
140 strcmp (p, ".xpm") == 0 ||
141 strcmp (p, ".svg") == 0))
142 *p = 0;
143
144 icon = g_themed_icon_new (icon_name);
145 }
146
147 g_free (icon_name);
148
149 return icon;
150 }
151
152 static gboolean
153 key_file_get_show_in (GKeyFile *key_file)
154 {
155 const gchar *current_desktop;
156 gchar **strv;
157 gboolean show_in = TRUE;
158 int i;
159
160 current_desktop = get_current_desktop ();
161 if (!current_desktop)
162 return TRUE;
163
164 strv = g_key_file_get_string_list (key_file,
165 DESKTOP_ENTRY_GROUP,
166 "OnlyShowIn",
167 NULL,
168 NULL);
169 if (strv)
170 {
171 show_in = FALSE;
172 for (i = 0; strv[i]; i++)
173 {
174 if (!strcmp (strv[i], current_desktop))
175 {
176 show_in = TRUE;
177 break;
178 }
179 }
180 }
181 else
182 {
183 strv = g_key_file_get_string_list (key_file,
184 DESKTOP_ENTRY_GROUP,
185 "NotShowIn",
186 NULL,
187 NULL);
188 if (strv)
189 {
190 show_in = TRUE;
191 for (i = 0; strv[i]; i++)
192 {
193 if (!strcmp (strv[i], current_desktop))
194 {
195 show_in = FALSE;
196 }
197 }
198 }
199 }
200 g_strfreev (strv);
201
202 return show_in;
203 }
204
205 static gboolean
206 desktop_entry_load_directory (DesktopEntry *entry,
207 GKeyFile *key_file,
208 GError **error)
209 {
210 DesktopEntryDirectory *entry_directory = (DesktopEntryDirectory*)entry;
211 char *type_str;
212
213 type_str = g_key_file_get_string (key_file, DESKTOP_ENTRY_GROUP, "Type", error);
214 if (!type_str)
215 return FALSE;
216
217 if (strcmp (type_str, "Directory") != 0)
218 {
219 g_set_error (error,
220 G_KEY_FILE_ERROR,
221 G_KEY_FILE_ERROR_INVALID_VALUE,
222 "\"%s\" does not contain the correct \"Type\" value\n", entry->path);
223 g_free (type_str);
224 return FALSE;
225 }
226
227 g_free (type_str);
228
229 entry_directory->name = g_key_file_get_locale_string (key_file, DESKTOP_ENTRY_GROUP, "Name", NULL, error);
230 if (entry_directory->name == NULL)
231 return FALSE;
232
233 entry_directory->generic_name = g_key_file_get_locale_string (key_file, DESKTOP_ENTRY_GROUP, "GenericName", NULL, NULL);
234 entry_directory->comment = g_key_file_get_locale_string (key_file, DESKTOP_ENTRY_GROUP, "Comment", NULL, NULL);
235 entry_directory->icon = key_file_get_icon (key_file);
236 entry_directory->nodisplay = g_key_file_get_boolean (key_file,
237 DESKTOP_ENTRY_GROUP,
238 "NoDisplay",
239 NULL);
240 entry_directory->hidden = g_key_file_get_boolean (key_file,
241 DESKTOP_ENTRY_GROUP,
242 "Hidden",
243 NULL);
244 entry_directory->showin = key_file_get_show_in (key_file);
245
246 return TRUE;
247 }
248
249 static gboolean
250 desktop_entry_load (DesktopEntry *entry)
251 {
252 if (entry->type == DESKTOP_ENTRY_DESKTOP)
253 {
254 DesktopEntryDesktop *entry_desktop = (DesktopEntryDesktop*)entry;
255 const char *categories_str;
256
257 entry_desktop->appinfo = g_desktop_app_info_new_from_filename (entry->path);
258 if (!entry_desktop->appinfo ||
259 !g_app_info_get_name (G_APP_INFO (entry_desktop->appinfo)) ||
260 !g_app_info_get_executable (G_APP_INFO (entry_desktop->appinfo)))
261 {
262 menu_verbose ("Failed to load \"%s\"\n", entry->path);
263 return FALSE;
264 }
265
266 categories_str = g_desktop_app_info_get_categories (entry_desktop->appinfo);
267 if (categories_str)
268 {
269 char **categories;
270 int i;
271
272 categories = g_strsplit (categories_str, ";", -1);
273 entry_desktop->categories = g_new0 (GQuark, g_strv_length (categories) + 1);
274
275 for (i = 0; categories[i]; i++)
276 entry_desktop->categories[i] = g_quark_from_string (categories[i]);
277
278 g_strfreev (categories);
279 }
280
281 return TRUE;
282 }
283 else if (entry->type == DESKTOP_ENTRY_DIRECTORY)
284 {
285 GKeyFile *key_file = NULL;
286 GError *error = NULL;
287 gboolean retval = FALSE;
288
289 key_file = g_key_file_new ();
290
291 if (!g_key_file_load_from_file (key_file, entry->path, 0, &error))
292 goto out;
293
294 if (!desktop_entry_load_directory (entry, key_file, &error))
295 goto out;
296
297 retval = TRUE;
298
299 out:
300 g_key_file_free (key_file);
301
302 if (!retval)
303 {
304 if (error)
305 {
306 menu_verbose ("Failed to load \"%s\": %s\n", entry->path, error->message);
307 g_error_free (error);
308 }
309 else
310 menu_verbose ("Failed to load \"%s\"\n", entry->path);
311 }
312
313 return retval;
314 }
315 else
316 g_assert_not_reached ();
317
318 return FALSE;
319 }
320
321 DesktopEntry *
322 desktop_entry_new (const char *path)
323 {
324 DesktopEntryType type;
325 DesktopEntry *retval;
326
327 menu_verbose ("Loading desktop entry \"%s\"\n", path);
328
329 if (g_str_has_suffix (path, ".desktop"))
330 {
331 type = DESKTOP_ENTRY_DESKTOP;
332 retval = (DesktopEntry*)g_new0 (DesktopEntryDesktop, 1);
333 }
334 else if (g_str_has_suffix (path, ".directory"))
335 {
336 type = DESKTOP_ENTRY_DIRECTORY;
337 retval = (DesktopEntry*)g_new0 (DesktopEntryDirectory, 1);
338 }
339 else
340 {
341 menu_verbose ("Unknown desktop entry suffix in \"%s\"\n",
342 path);
343 return NULL;
344 }
345
346 retval->refcount = 1;
347 retval->type = type;
348 retval->path = g_strdup (path);
349 retval->basename = unix_basename_from_path (retval->path);
350
351 if (!desktop_entry_load (retval))
352 {
353 desktop_entry_unref (retval);
354 return NULL;
355 }
356
357 return retval;
358 }
359
360 DesktopEntry *
361 desktop_entry_reload (DesktopEntry *entry)
362 {
363 g_return_val_if_fail (entry != NULL, NULL);
364
365 menu_verbose ("Re-loading desktop entry \"%s\"\n", entry->path);
366
367 if (entry->type == DESKTOP_ENTRY_DESKTOP)
368 {
369 DesktopEntryDesktop *entry_desktop = (DesktopEntryDesktop *) entry;
370
371 g_object_unref (entry_desktop->appinfo);
372 entry_desktop->appinfo = NULL;
373
374 g_free (entry_desktop->categories);
375 entry_desktop->categories = NULL;
376 }
377 else if (entry->type == DESKTOP_ENTRY_DIRECTORY)
378 {
379 DesktopEntryDirectory *entry_directory = (DesktopEntryDirectory*) entry;
380
381 g_free (entry_directory->name);
382 entry_directory->name = NULL;
383
384 g_free (entry_directory->comment);
385 entry_directory->comment = NULL;
386
387 g_object_unref (entry_directory->icon);
388 entry_directory->icon = NULL;
389 }
390 else
391 g_assert_not_reached ();
392
393 if (!desktop_entry_load (entry))
394 {
395 desktop_entry_unref (entry);
396 return NULL;
397 }
398
399 return entry;
400 }
401
402 DesktopEntry *
403 desktop_entry_ref (DesktopEntry *entry)
404 {
405 g_return_val_if_fail (entry != NULL, NULL);
406 g_return_val_if_fail (entry->refcount > 0, NULL);
407
408 g_atomic_int_inc (&entry->refcount);
409
410 return entry;
411 }
412
413 DesktopEntry *
414 desktop_entry_copy (DesktopEntry *entry)
415 {
416 DesktopEntry *retval;
417
418 menu_verbose ("Copying desktop entry \"%s\"\n",
419 entry->basename);
420
421 if (entry->type == DESKTOP_ENTRY_DESKTOP)
422 retval = (DesktopEntry*)g_new0 (DesktopEntryDesktop, 1);
423 else if (entry->type == DESKTOP_ENTRY_DIRECTORY)
424 retval = (DesktopEntry*)g_new0 (DesktopEntryDirectory, 1);
425 else
426 g_assert_not_reached ();
427
428 retval->refcount = 1;
429 retval->type = entry->type;
430 retval->path = g_strdup (entry->path);
431 retval->basename = unix_basename_from_path (retval->path);
432
433 if (retval->type == DESKTOP_ENTRY_DESKTOP)
434 {
435 DesktopEntryDesktop *desktop_entry = (DesktopEntryDesktop*) entry;
436 DesktopEntryDesktop *retval_desktop_entry = (DesktopEntryDesktop*) retval;
437 int i;
438
439 retval_desktop_entry->appinfo = g_object_ref (desktop_entry->appinfo);
440
441 if (desktop_entry->categories != NULL)
442 {
443 i = 0;
444 for (; desktop_entry->categories[i]; i++);
445
446 retval_desktop_entry->categories = g_new0 (GQuark, i + 1);
447
448 i = 0;
449 for (; desktop_entry->categories[i]; i++)
450 retval_desktop_entry->categories[i] = desktop_entry->categories[i];
451 }
452 else
453 retval_desktop_entry->categories = NULL;
454 }
455 else if (entry->type == DESKTOP_ENTRY_DIRECTORY)
456 {
457 DesktopEntryDirectory *entry_directory = (DesktopEntryDirectory*)entry;
458 DesktopEntryDirectory *retval_directory = (DesktopEntryDirectory*)retval;
459
460 retval_directory->name = g_strdup (entry_directory->name);
461 retval_directory->comment = g_strdup (entry_directory->comment);
462 retval_directory->icon = g_object_ref (entry_directory->icon);
463 retval_directory->nodisplay = entry_directory->nodisplay;
464 retval_directory->hidden = entry_directory->hidden;
465 retval_directory->showin = entry_directory->showin;
466 }
467
468 return retval;
469 }
470
471 void
472 desktop_entry_unref (DesktopEntry *entry)
473 {
474 g_return_if_fail (entry != NULL);
475 g_return_if_fail (entry->refcount > 0);
476
477 entry->refcount -= 1;
478 if (entry->refcount != 0)
479 return;
480
481 g_free (entry->path);
482 entry->path = NULL;
483
484 if (entry->type == DESKTOP_ENTRY_DESKTOP)
485 {
486 DesktopEntryDesktop *desktop_entry = (DesktopEntryDesktop*) entry;
487 g_free (desktop_entry->categories);
488 if (desktop_entry->appinfo)
489 g_object_unref (desktop_entry->appinfo);
490 }
491 else if (entry->type == DESKTOP_ENTRY_DIRECTORY)
492 {
493 DesktopEntryDirectory *entry_directory = (DesktopEntryDirectory*) entry;
494
495 g_free (entry_directory->name);
496 entry_directory->name = NULL;
497
498 g_free (entry_directory->comment);
499 entry_directory->comment = NULL;
500
501 if (entry_directory->icon != NULL)
502 {
503 g_object_unref (entry_directory->icon);
504 entry_directory->icon = NULL;
505 }
506 }
507 else
508 g_assert_not_reached ();
509
510 g_free (entry);
511 }
512
513 DesktopEntryType
514 desktop_entry_get_type (DesktopEntry *entry)
515 {
516 return entry->type;
517 }
518
519 const char *
520 desktop_entry_get_path (DesktopEntry *entry)
521 {
522 return entry->path;
523 }
524
525 const char *
526 desktop_entry_get_basename (DesktopEntry *entry)
527 {
528 return entry->basename;
529 }
530
531 const char *
532 desktop_entry_get_name (DesktopEntry *entry)
533 {
534 if (entry->type == DESKTOP_ENTRY_DESKTOP)
535 return g_app_info_get_name (G_APP_INFO (((DesktopEntryDesktop*)entry)->appinfo));
536 return ((DesktopEntryDirectory*)entry)->name;
537 }
538
539 const char *
540 desktop_entry_get_generic_name (DesktopEntry *entry)
541 {
542 if (entry->type == DESKTOP_ENTRY_DESKTOP)
543 return g_desktop_app_info_get_generic_name (((DesktopEntryDesktop*)entry)->appinfo);
544 return ((DesktopEntryDirectory*)entry)->generic_name;
545 }
546
547 const char *
548 desktop_entry_get_comment (DesktopEntry *entry)
549 {
550 if (entry->type == DESKTOP_ENTRY_DESKTOP)
551 return g_app_info_get_description (G_APP_INFO (((DesktopEntryDesktop*)entry)->appinfo));
552 return ((DesktopEntryDirectory*)entry)->comment;
553 }
554
555 GIcon *
556 desktop_entry_get_icon (DesktopEntry *entry)
557 {
558 if (entry->type == DESKTOP_ENTRY_DESKTOP)
559 return g_app_info_get_icon (G_APP_INFO (((DesktopEntryDesktop*)entry)->appinfo));
560 return ((DesktopEntryDirectory*)entry)->icon;
561 }
562
563 gboolean
564 desktop_entry_get_no_display (DesktopEntry *entry)
565 {
566 if (entry->type == DESKTOP_ENTRY_DESKTOP)
567 return g_desktop_app_info_get_nodisplay (((DesktopEntryDesktop*)entry)->appinfo);
568 return ((DesktopEntryDirectory*)entry)->nodisplay;
569 }
570
571 gboolean
572 desktop_entry_get_hidden (DesktopEntry *entry)
573 {
574 if (entry->type == DESKTOP_ENTRY_DESKTOP)
575 return g_desktop_app_info_get_is_hidden (((DesktopEntryDesktop*)entry)->appinfo);
576 return ((DesktopEntryDirectory*)entry)->hidden;
577 }
578
579 gboolean
580 desktop_entry_get_show_in (DesktopEntry *entry)
581 {
582 if (entry->type == DESKTOP_ENTRY_DESKTOP)
583 {
584 const char *current_desktop = get_current_desktop ();
585
586 if (current_desktop == NULL)
587 return TRUE;
588 else
589 return g_desktop_app_info_get_show_in (((DesktopEntryDesktop*)entry)->appinfo, current_desktop);
590 }
591 return ((DesktopEntryDirectory*)entry)->showin;
592 }
593
594
595 GDesktopAppInfo *
596 desktop_entry_get_app_info (DesktopEntry *entry)
597 {
598 g_return_val_if_fail (entry->type == DESKTOP_ENTRY_DESKTOP, NULL);
599 return ((DesktopEntryDesktop*)entry)->appinfo;
600 }
601
602 gboolean
603 desktop_entry_has_categories (DesktopEntry *entry)
604 {
605 DesktopEntryDesktop *desktop_entry;
606 if (entry->type != DESKTOP_ENTRY_DESKTOP)
607 return FALSE;
608
609 desktop_entry = (DesktopEntryDesktop*) entry;
610 return (desktop_entry->categories != NULL && desktop_entry->categories[0] != 0);
611 }
612
613 gboolean
614 desktop_entry_has_category (DesktopEntry *entry,
615 const char *category)
616 {
617 GQuark quark;
618 int i;
619 DesktopEntryDesktop *desktop_entry;
620
621 if (entry->type != DESKTOP_ENTRY_DESKTOP)
622 return FALSE;
623
624 desktop_entry = (DesktopEntryDesktop*) entry;
625
626 if (desktop_entry->categories == NULL)
627 return FALSE;
628
629 if (!(quark = g_quark_try_string (category)))
630 return FALSE;
631
632 for (i = 0; desktop_entry->categories[i]; i++)
633 {
634 if (quark == desktop_entry->categories[i])
635 return TRUE;
636 }
637
638 return FALSE;
639 }
640
641 void
642 desktop_entry_add_legacy_category (DesktopEntry *entry)
643 {
644 GQuark *categories;
645 int i;
646 DesktopEntryDesktop *desktop_entry;
647
648 g_return_if_fail (entry->type == DESKTOP_ENTRY_DESKTOP);
649
650 desktop_entry = (DesktopEntryDesktop*) entry;
651
652 menu_verbose ("Adding Legacy category to \"%s\"\n",
653 entry->basename);
654
655 if (desktop_entry->categories != NULL)
656 {
657 i = 0;
658 for (; desktop_entry->categories[i]; i++);
659
660 categories = g_new0 (GQuark, i + 2);
661
662 i = 0;
663 for (; desktop_entry->categories[i]; i++)
664 categories[i] = desktop_entry->categories[i];
665 }
666 else
667 {
668 categories = g_new0 (GQuark, 2);
669 i = 0;
670 }
671
672 categories[i] = g_quark_from_string ("Legacy");
673
674 g_free (desktop_entry->categories);
675 desktop_entry->categories = categories;
676 }
677
678 /*
679 * Entry sets
680 */
681
682 DesktopEntrySet *
683 desktop_entry_set_new (void)
684 {
685 DesktopEntrySet *set;
686
687 set = g_new0 (DesktopEntrySet, 1);
688 set->refcount = 1;
689
690 menu_verbose (" New entry set %p\n", set);
691
692 return set;
693 }
694
695 DesktopEntrySet *
696 desktop_entry_set_ref (DesktopEntrySet *set)
697 {
698 g_return_val_if_fail (set != NULL, NULL);
699 g_return_val_if_fail (set->refcount > 0, NULL);
700
701 g_atomic_int_inc (&set->refcount);
702
703 return set;
704 }
705
706 void
707 desktop_entry_set_unref (DesktopEntrySet *set)
708 {
709 gboolean is_zero;
710
711 g_return_if_fail (set != NULL);
712 g_return_if_fail (set->refcount > 0);
713
714 is_zero = g_atomic_int_dec_and_test (&set->refcount);
715 if (is_zero)
716 {
717 menu_verbose (" Deleting entry set %p\n", set);
718
719 if (set->hash)
720 g_hash_table_destroy (set->hash);
721 set->hash = NULL;
722
723 g_free (set);
724 }
725 }
726
727 void
728 desktop_entry_set_add_entry (DesktopEntrySet *set,
729 DesktopEntry *entry,
730 const char *file_id)
731 {
732 menu_verbose (" Adding to set %p entry %s\n", set, file_id);
733
734 if (set->hash == NULL)
735 {
736 set->hash = g_hash_table_new_full (g_str_hash,
737 g_str_equal,
738 g_free,
739 (GDestroyNotify) desktop_entry_unref);
740 }
741
742 g_hash_table_replace (set->hash,
743 g_strdup (file_id),
744 desktop_entry_ref (entry));
745 }
746
747 DesktopEntry *
748 desktop_entry_set_lookup (DesktopEntrySet *set,
749 const char *file_id)
750 {
751 if (set->hash == NULL)
752 return NULL;
753
754 return g_hash_table_lookup (set->hash, file_id);
755 }
756
757 typedef struct
758 {
759 DesktopEntrySetForeachFunc func;
760 gpointer user_data;
761 } EntryHashForeachData;
762
763 static void
764 entry_hash_foreach (const char *file_id,
765 DesktopEntry *entry,
766 EntryHashForeachData *fd)
767 {
768 fd->func (file_id, entry, fd->user_data);
769 }
770
771 void
772 desktop_entry_set_foreach (DesktopEntrySet *set,
773 DesktopEntrySetForeachFunc func,
774 gpointer user_data)
775 {
776 g_return_if_fail (set != NULL);
777 g_return_if_fail (func != NULL);
778
779 if (set->hash != NULL)
780 {
781 EntryHashForeachData fd;
782
783 fd.func = func;
784 fd.user_data = user_data;
785
786 g_hash_table_foreach (set->hash,
787 (GHFunc) entry_hash_foreach,
788 &fd);
789 }
790 }
791
792 static void
793 desktop_entry_set_clear (DesktopEntrySet *set)
794 {
795 menu_verbose (" Clearing set %p\n", set);
796
797 if (set->hash != NULL)
798 {
799 g_hash_table_destroy (set->hash);
800 set->hash = NULL;
801 }
802 }
803
804 int
805 desktop_entry_set_get_count (DesktopEntrySet *set)
806 {
807 if (set->hash == NULL)
808 return 0;
809
810 return g_hash_table_size (set->hash);
811 }
812
813 static void
814 union_foreach (const char *file_id,
815 DesktopEntry *entry,
816 DesktopEntrySet *set)
817 {
818 /* we are iterating over "with" adding anything not
819 * already in "set". We unconditionally overwrite
820 * the stuff in "set" because we can assume
821 * two entries with the same name are equivalent.
822 */
823 desktop_entry_set_add_entry (set, entry, file_id);
824 }
825
826 void
827 desktop_entry_set_union (DesktopEntrySet *set,
828 DesktopEntrySet *with)
829 {
830 menu_verbose (" Union of %p and %p\n", set, with);
831
832 if (desktop_entry_set_get_count (with) == 0)
833 return; /* A fast simple case */
834
835 g_hash_table_foreach (with->hash,
836 (GHFunc) union_foreach,
837 set);
838 }
839
840 typedef struct
841 {
842 DesktopEntrySet *set;
843 DesktopEntrySet *with;
844 } IntersectData;
845
846 static gboolean
847 intersect_foreach_remove (const char *file_id,
848 DesktopEntry *entry,
849 IntersectData *id)
850 {
851 /* Remove everything in "set" which is not in "with" */
852
853 if (g_hash_table_lookup (id->with->hash, file_id) != NULL)
854 return FALSE;
855
856 menu_verbose (" Removing from %p entry %s\n", id->set, file_id);
857
858 return TRUE; /* return TRUE to remove */
859 }
860
861 void
862 desktop_entry_set_intersection (DesktopEntrySet *set,
863 DesktopEntrySet *with)
864 {
865 IntersectData id;
866
867 menu_verbose (" Intersection of %p and %p\n", set, with);
868
869 if (desktop_entry_set_get_count (set) == 0 ||
870 desktop_entry_set_get_count (with) == 0)
871 {
872 /* A fast simple case */
873 desktop_entry_set_clear (set);
874 return;
875 }
876
877 id.set = set;
878 id.with = with;
879
880 g_hash_table_foreach_remove (set->hash,
881 (GHRFunc) intersect_foreach_remove,
882 &id);
883 }
884
885 typedef struct
886 {
887 DesktopEntrySet *set;
888 DesktopEntrySet *other;
889 } SubtractData;
890
891 static gboolean
892 subtract_foreach_remove (const char *file_id,
893 DesktopEntry *entry,
894 SubtractData *sd)
895 {
896 /* Remove everything in "set" which is not in "other" */
897
898 if (g_hash_table_lookup (sd->other->hash, file_id) == NULL)
899 return FALSE;
900
901 menu_verbose (" Removing from %p entry %s\n", sd->set, file_id);
902
903 return TRUE; /* return TRUE to remove */
904 }
905
906 void
907 desktop_entry_set_subtract (DesktopEntrySet *set,
908 DesktopEntrySet *other)
909 {
910 SubtractData sd;
911
912 menu_verbose (" Subtract from %p set %p\n", set, other);
913
914 if (desktop_entry_set_get_count (set) == 0 ||
915 desktop_entry_set_get_count (other) == 0)
916 return; /* A fast simple case */
917
918 sd.set = set;
919 sd.other = other;
920
921 g_hash_table_foreach_remove (set->hash,
922 (GHRFunc) subtract_foreach_remove,
923 &sd);
924 }
925
926 void
927 desktop_entry_set_swap_contents (DesktopEntrySet *a,
928 DesktopEntrySet *b)
929 {
930 GHashTable *tmp;
931
932 menu_verbose (" Swap contents of %p and %p\n", a, b);
933
934 tmp = a->hash;
935 a->hash = b->hash;
936 b->hash = tmp;
937 }
0 <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN"
1 "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd">
2
3 <Menu>
4
5 <Name>Applications</Name>
6 <Directory>X-GNOME-Menu-Applications.directory</Directory>
7
8 <!-- Read standard .directory and .desktop file locations -->
9 <DefaultAppDirs/>
10 <DefaultDirectoryDirs/>
11
12 <!-- Read in overrides and child menus from applications-merged/ -->
13 <DefaultMergeDirs/>
14
15 <!-- Accessories submenu -->
16 <Menu>
17 <Name>Accessories</Name>
18 <OnlyUnallocated/>
19 <Directory>Utility.directory</Directory>
20 <Include>
21 <And>
22 <Category>Utility</Category>
23 <!-- Accessibility spec must have either the Utility or Settings
24 category, and we display an accessibility submenu already for
25 the ones that do not have Settings, so don't display accessibility
26 applications here -->
27 <Not><Category>Accessibility</Category></Not>
28 <Not><Category>System</Category></Not>
29
30 <!-- Also exclude everything we put in the X-GNOME-Utilities
31 whitelist -->
32 <Not><Filename>file-roller.desktop</Filename></Not>
33 <Not><Filename>gnome-file-roller.desktop</Filename></Not>
34 <Not><Filename>deja-dup-preferences.desktop</Filename></Not>
35 <Not><Filename>gnome-calculator.desktop</Filename></Not>
36 <Not><Filename>gcalctool.desktop</Filename></Not>
37 <Not><Filename>gucharmap.desktop</Filename></Not>
38 <Not><Filename>gnome-gucharmap.desktop</Filename></Not>
39 <Not><Filename>gnome-font-viewer.desktop</Filename></Not>
40 <Not><Filename>seahorse.desktop</Filename></Not>
41 <Not><Filename>gnome-terminal.desktop</Filename></Not>
42 <Not><Filename>gnome-tweak-tool.desktop</Filename></Not>
43 <Not><Filename>gnome-disks.desktop</Filename></Not>
44 <Not><Filename>gnome-screenshot.desktop</Filename></Not>
45 <Not><Filename>gnome-yelp.desktop</Filename></Not>
46 <Not><Filename>yelp.desktop</Filename></Not>
47 <Not><Filename>gnome-control-center.desktop</Filename></Not>
48 </And>
49 </Include>
50 </Menu> <!-- End Accessories -->
51
52
53 <!-- Accessibility submenu -->
54 <Menu>
55 <Name>Universal Access</Name>
56 <OnlyUnallocated/>
57 <Directory>Utility-Accessibility.directory</Directory>
58 <Include>
59 <And>
60 <Category>Accessibility</Category>
61 <Not><Category>Settings</Category></Not>
62 </And>
63 </Include>
64 </Menu> <!-- End Accessibility -->
65
66 <!-- Development Tools -->
67 <Menu>
68 <Name>Development</Name>
69 <OnlyUnallocated/>
70 <Directory>Development.directory</Directory>
71 <Include>
72 <And>
73 <Category>Development</Category>
74 </And>
75 <Filename>emacs.desktop</Filename>
76 </Include>
77 </Menu> <!-- End Development Tools -->
78
79 <!-- Education -->
80 <Menu>
81 <Name>Education</Name>
82 <Directory>Education.directory</Directory>
83 <Include>
84 <And>
85 <Category>Education</Category>
86 </And>
87 </Include>
88 </Menu> <!-- End Education -->
89
90 <!-- Games -->
91 <Menu>
92 <Name>Games</Name>
93 <Directory>Game.directory</Directory>
94 <Include>
95 <And>
96 <Category>Game</Category>
97 </And>
98 </Include>
99 </Menu> <!-- End Games -->
100
101 <!-- Graphics -->
102 <Menu>
103 <Name>Graphics</Name>
104 <OnlyUnallocated/>
105 <Directory>Graphics.directory</Directory>
106 <Include>
107 <And>
108 <Category>Graphics</Category>
109 <Not><Filename>eog.desktop</Filename></Not>
110 <Not><Filename>gnome-eog.desktop</Filename></Not>
111 <Not><Filename>evince.desktop</Filename></Not>
112 </And>
113 </Include>
114 </Menu> <!-- End Graphics -->
115
116 <!-- Internet -->
117 <Menu>
118 <Name>Internet</Name>
119 <OnlyUnallocated/>
120 <Directory>Network.directory</Directory>
121 <Include>
122 <And>
123 <Category>Network</Category>
124 <Not><Category>X-GNOME-WebApplication</Category></Not>
125 <Not><Filename>vinagre.desktop</Filename></Not>
126 </And>
127 </Include>
128 </Menu> <!-- End Internet -->
129
130 <!-- Web Applications -->
131 <Menu>
132 <Name>Web Applications</Name>
133 <Directory>X-GNOME-WebApplications.directory</Directory>
134 <Include>
135 <And>
136 <Category>Network</Category>
137 <Category>X-GNOME-WebApplication</Category>
138 </And>
139 </Include>
140 </Menu>
141
142 <!-- Multimedia -->
143 <Menu>
144 <Name>Multimedia</Name>
145 <OnlyUnallocated/>
146 <Directory>AudioVideo.directory</Directory>
147 <Include>
148 <And>
149 <Category>AudioVideo</Category>
150 </And>
151 </Include>
152 </Menu> <!-- End Multimedia -->
153
154 <!-- Office -->
155 <Menu>
156 <Name>Office</Name>
157 <OnlyUnallocated/>
158 <Directory>Office.directory</Directory>
159 <Include>
160 <And>
161 <Category>Office</Category>
162 <Not><Filename>evince.desktop</Filename></Not>
163 <Not><Filename>gnome-dictionary.desktop</Filename></Not>
164 </And>
165 </Include>
166 </Menu> <!-- End Office -->
167
168 <!-- Sundry -->
169 <Menu>
170 <Name>Sundry</Name>
171 <Directory>X-GNOME-Sundry.directory</Directory>
172 <Include>
173 <Filename>alacarte.desktop</Filename>
174 <Filename>caribou.desktop</Filename>
175 <Filename>dconf-editor.desktop</Filename>
176 <Filename>fedora-im-chooser.desktop</Filename>
177 <Filename>fedora-release-notes.desktop</Filename>
178 <Filename>firewall-config.desktop</Filename>
179 <Filename>flash-player-properties.desktop</Filename>
180 <Filename>gconf-editor.desktop</Filename>
181 <Filename>gnome-abrt.desktop</Filename>
182 <Filename>fedora-abrt.desktop</Filename>
183 <Filename>gnome-orca.desktop</Filename>
184 <Filename>gnome-power-statistics.desktop</Filename>
185 <Filename>gnome-user-share-properties.desktop</Filename>
186 <Filename>ibus.desktop</Filename>
187 <Filename>ibus-daemon.desktop</Filename>
188 <Filename>ibus-setup-anthy.desktop</Filename>
189 <Filename>ibus-setup.desktop</Filename>
190 <Filename>ibus-setup-hangul.desktop</Filename>
191 <Filename>ibus-setup-libbopomofo.desktop</Filename>
192 <Filename>ibus-setup-libpinyin.desktop</Filename>
193 <Filename>ibus-setup-m17n.desktop</Filename>
194 <Filename>ibus-setup-typing-booster.desktop</Filename>
195 <Filename>im-chooser.desktop</Filename>
196 <Filename>itweb-settings.desktop</Filename>
197 <Filename>jhbuild.desktop</Filename>
198 <Filename>javaws.desktop</Filename>
199 <Filename>java-1.7.0-openjdk-jconsole.desktop</Filename>
200 <Filename>java-1.7.0-openjdk-policytool.desktop</Filename>
201 <Filename>log4j-chainsaw.desktop</Filename>
202 <Filename>log4j-logfactor5.desktop</Filename>
203 <Filename>nm-connection-editor.desktop</Filename>
204 <Filename>orca.desktop</Filename>
205 <Filename>setroubleshoot.desktop</Filename>
206 <Filename>authconfig.desktop</Filename>
207 <Filename>system-config-date.desktop</Filename>
208 <Filename>system-config-firewall.desktop</Filename>
209 <Filename>system-config-keyboard.desktop</Filename>
210 <Filename>system-config-language.desktop</Filename>
211 <Filename>system-config-printer.desktop</Filename>
212 <Filename>system-config-users.desktop</Filename>
213 <Filename>vino-preferences.desktop</Filename>
214 </Include>
215 </Menu>
216
217 <!-- System Tools-->
218 <Menu>
219 <Name>System</Name>
220 <OnlyUnallocated/>
221 <Directory>System-Tools.directory</Directory>
222 <Include>
223 <And>
224 <Category>System</Category>
225 <Not><Category>Settings</Category></Not>
226 <Not><Filename>baobab.desktop</Filename></Not>
227 <Not><Filename>gnome-system-log.desktop</Filename></Not>
228 <Not><Filename>gnome-system-monitor.desktop</Filename></Not>
229 </And>
230 </Include>
231 </Menu> <!-- End System Tools -->
232
233 <!-- System Settings -->
234 <Menu>
235 <Name>System Settings</Name>
236 <Directory>X-GNOME-SystemSettings.directory</Directory>
237 <Include>
238 <Category>X-GNOME-Settings-Panel</Category>
239 </Include>
240 </Menu>
241
242 <!-- Utilities submenu -->
243 <Menu>
244 <Name>Utilities</Name>
245 <Directory>X-GNOME-Utilities.directory</Directory>
246 <Include>
247 <Filename>file-roller.desktop</Filename>
248 <Filename>gnome-calculator.desktop</Filename>
249 <Filename>gnome-font-viewer.desktop</Filename>
250 <Filename>gucharmap.desktop</Filename>
251 <Filename>seahorse.desktop</Filename>
252 <Filename>gnome-terminal.desktop</Filename>
253 <Filename>deja-dup-preferences.desktop</Filename>
254 <Filename>gnome-dictionary.desktop</Filename>
255 <Filename>evince.desktop</Filename>
256 <Filename>eog.desktop</Filename>
257 <Filename>baobab.desktop</Filename>
258 <Filename>gnome-system-log.desktop</Filename>
259 <Filename>gnome-system-monitor.desktop</Filename>
260 <Filename>vinagre.desktop</Filename>
261 <Filename>gnome-tweak-tool.desktop</Filename>
262 <Filename>gnome-disks.desktop</Filename>
263 <Filename>gnome-screenshot.desktop</Filename>
264 <Filename>gnome-yelp.desktop</Filename>
265 <Filename>yelp.desktop</Filename>
266 <Filename>gnome-control-center.desktop</Filename>
267 </Include>
268 </Menu>
269
270 <!-- Other -->
271 <Menu>
272 <Name>Other</Name>
273 <Directory>X-GNOME-Other.directory</Directory>
274 <OnlyUnallocated/>
275 <Include>
276 <And>
277 <Not><Category>Core</Category></Not>
278 <Not><Category>Screensaver</Category></Not>
279
280 <!-- Really Fedora ??? -->
281 <Not><Filename>gnome-eog.desktop</Filename></Not>
282 <Not><Filename>gnome-file-roller.desktop</Filename></Not>
283 <Not><Filename>gnome-gucharmap.desktop</Filename></Not>
284 <Not><Filename>gcalctool.desktop</Filename></Not>
285 </And>
286 </Include>
287 </Menu> <!-- End Other -->
288
289 <Layout>
290 <Merge type="menus" />
291 <Menuname>Other</Menuname>
292 <Merge type="files" />
293 </Layout>
294
295 </Menu> <!-- End Applications -->
0 <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN"
1 "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd">
2
3 <Menu>
4
5 <Name>Applications</Name>
6 <Directory>X-GNOME-Menu-Applications.directory</Directory>
7
8 <!-- Scan legacy dirs first, as later items take priority -->
9 <LegacyDir>/etc/X11/applnk</LegacyDir>
10 <LegacyDir>/usr/share/gnome/apps</LegacyDir>
11
12 <!-- Read standard .directory and .desktop file locations -->
13 <DefaultAppDirs/>
14 <DefaultDirectoryDirs/>
15
16 <!-- Read in overrides and child menus from applications-merged/ -->
17 <DefaultMergeDirs/>
18
19 <!-- Accessories submenu -->
20 <Menu>
21 <Name>Accessories</Name>
22 <OnlyUnallocated/>
23 <Directory>Utility.directory</Directory>
24 <Include>
25 <And>
26 <Category>Utility</Category>
27 <!-- Accessibility spec must have either the Utility or Settings
28 category, and we display an accessibility submenu already for
29 the ones that do not have Settings, so don't display accessibility
30 applications here -->
31 <Not><Category>Accessibility</Category></Not>
32 <Not><Category>System</Category></Not>
33
34 <!-- Also exclude everything we put in the X-GNOME-Utilities
35 whitelist -->
36 <Not><Filename>file-roller.desktop</Filename></Not>
37 <Not><Filename>gnome-file-roller.desktop</Filename></Not>
38 <Not><Filename>deja-dup-preferences.desktop</Filename></Not>
39 <Not><Filename>gnome-calculator.desktop</Filename></Not>
40 <Not><Filename>gcalctool.desktop</Filename></Not>
41 <Not><Filename>gucharmap.desktop</Filename></Not>
42 <Not><Filename>gnome-gucharmap.desktop</Filename></Not>
43 <Not><Filename>gnome-font-viewer.desktop</Filename></Not>
44 <Not><Filename>seahorse.desktop</Filename></Not>
45 <Not><Filename>gnome-terminal.desktop</Filename></Not>
46 <Not><Filename>gnome-tweak-tool.desktop</Filename></Not>
47 <Not><Filename>gnome-disks.desktop</Filename></Not>
48 <Not><Filename>gnome-screenshot.desktop</Filename></Not>
49 <Not><Filename>gnome-yelp.desktop</Filename></Not>
50 <Not><Filename>yelp.desktop</Filename></Not>
51 <Not><Filename>gnome-control-center.desktop</Filename></Not>
52 </And>
53 </Include>
54 </Menu> <!-- End Accessories -->
55
56
57 <!-- Accessibility submenu -->
58 <Menu>
59 <Name>Universal Access</Name>
60 <OnlyUnallocated/>
61 <Directory>Utility-Accessibility.directory</Directory>
62 <Include>
63 <And>
64 <Category>Accessibility</Category>
65 <Not><Category>Settings</Category></Not>
66 </And>
67 </Include>
68 </Menu> <!-- End Accessibility -->
69
70 <!-- Development Tools -->
71 <Menu>
72 <Name>Development</Name>
73 <OnlyUnallocated/>
74 <Directory>Development.directory</Directory>
75 <Include>
76 <And>
77 <Category>Development</Category>
78 </And>
79 <Filename>emacs.desktop</Filename>
80 </Include>
81 </Menu> <!-- End Development Tools -->
82
83 <!-- Education -->
84 <Menu>
85 <Name>Education</Name>
86 <Directory>Education.directory</Directory>
87 <Include>
88 <And>
89 <Category>Education</Category>
90 </And>
91 </Include>
92 </Menu> <!-- End Education -->
93
94 <!-- Games -->
95 <Menu>
96 <Name>Games</Name>
97 <Directory>Game.directory</Directory>
98 <Include>
99 <And>
100 <Category>Game</Category>
101 </And>
102 </Include>
103 </Menu> <!-- End Games -->
104
105 <!-- Graphics -->
106 <Menu>
107 <Name>Graphics</Name>
108 <OnlyUnallocated/>
109 <Directory>Graphics.directory</Directory>
110 <Include>
111 <And>
112 <Category>Graphics</Category>
113 <Not><Filename>eog.desktop</Filename></Not>
114 <Not><Filename>gnome-eog.desktop</Filename></Not>
115 <Not><Filename>evince.desktop</Filename></Not>
116 </And>
117 </Include>
118 </Menu> <!-- End Graphics -->
119
120 <!-- Internet -->
121 <Menu>
122 <Name>Internet</Name>
123 <OnlyUnallocated/>
124 <Directory>Network.directory</Directory>
125 <Include>
126 <And>
127 <Category>Network</Category>
128 <Not><Category>X-GNOME-WebApplication</Category></Not>
129 <Not><Filename>vinagre.desktop</Filename></Not>
130 </And>
131 </Include>
132 </Menu> <!-- End Internet -->
133
134 <!-- Web Applications -->
135 <Menu>
136 <Name>Web Applications</Name>
137 <Directory>X-GNOME-WebApplications.directory</Directory>
138 <Include>
139 <And>
140 <Category>Network</Category>
141 <Category>X-GNOME-WebApplication</Category>
142 </And>
143 </Include>
144 </Menu>
145
146 <!-- Multimedia -->
147 <Menu>
148 <Name>Multimedia</Name>
149 <OnlyUnallocated/>
150 <Directory>AudioVideo.directory</Directory>
151 <Include>
152 <And>
153 <Category>AudioVideo</Category>
154 </And>
155 </Include>
156 </Menu> <!-- End Multimedia -->
157
158 <!-- Office -->
159 <Menu>
160 <Name>Office</Name>
161 <OnlyUnallocated/>
162 <Directory>Office.directory</Directory>
163 <Include>
164 <And>
165 <Category>Office</Category>
166 <Not><Filename>evince.desktop</Filename></Not>
167 <Not><Filename>gnome-dictionary.desktop</Filename></Not>
168 </And>
169 </Include>
170 </Menu> <!-- End Office -->
171
172 <!-- Sundry -->
173 <Menu>
174 <Name>Sundry</Name>
175 <Directory>X-GNOME-Sundry.directory</Directory>
176 <Include>
177 <Filename>alacarte.desktop</Filename>
178 <Filename>caribou.desktop</Filename>
179 <Filename>dconf-editor.desktop</Filename>
180 <Filename>fedora-im-chooser.desktop</Filename>
181 <Filename>fedora-release-notes.desktop</Filename>
182 <Filename>firewall-config.desktop</Filename>
183 <Filename>flash-player-properties.desktop</Filename>
184 <Filename>gconf-editor.desktop</Filename>
185 <Filename>gnome-abrt.desktop</Filename>
186 <Filename>fedora-abrt.desktop</Filename>
187 <Filename>gnome-orca.desktop</Filename>
188 <Filename>gnome-power-statistics.desktop</Filename>
189 <Filename>gnome-user-share-properties.desktop</Filename>
190 <Filename>ibus.desktop</Filename>
191 <Filename>ibus-daemon.desktop</Filename>
192 <Filename>ibus-setup-anthy.desktop</Filename>
193 <Filename>ibus-setup.desktop</Filename>
194 <Filename>ibus-setup-hangul.desktop</Filename>
195 <Filename>ibus-setup-libbopomofo.desktop</Filename>
196 <Filename>ibus-setup-libpinyin.desktop</Filename>
197 <Filename>ibus-setup-m17n.desktop</Filename>
198 <Filename>ibus-setup-typing-booster.desktop</Filename>
199 <Filename>im-chooser.desktop</Filename>
200 <Filename>itweb-settings.desktop</Filename>
201 <Filename>jhbuild.desktop</Filename>
202 <Filename>javaws.desktop</Filename>
203 <Filename>java-1.7.0-openjdk-jconsole.desktop</Filename>
204 <Filename>java-1.7.0-openjdk-policytool.desktop</Filename>
205 <Filename>log4j-chainsaw.desktop</Filename>
206 <Filename>log4j-logfactor5.desktop</Filename>
207 <Filename>nm-connection-editor.desktop</Filename>
208 <Filename>orca.desktop</Filename>
209 <Filename>setroubleshoot.desktop</Filename>
210 <Filename>authconfig.desktop</Filename>
211 <Filename>system-config-date.desktop</Filename>
212 <Filename>system-config-firewall.desktop</Filename>
213 <Filename>system-config-keyboard.desktop</Filename>
214 <Filename>system-config-language.desktop</Filename>
215 <Filename>system-config-printer.desktop</Filename>
216 <Filename>system-config-users.desktop</Filename>
217 <Filename>vino-preferences.desktop</Filename>
218 </Include>
219 </Menu>
220
221 <!-- System Tools-->
222 <Menu>
223 <Name>System</Name>
224 <OnlyUnallocated/>
225 <Directory>System-Tools.directory</Directory>
226 <Include>
227 <And>
228 <Category>System</Category>
229 <Not><Category>Settings</Category></Not>
230 <Not><Filename>baobab.desktop</Filename></Not>
231 <Not><Filename>gnome-system-log.desktop</Filename></Not>
232 <Not><Filename>gnome-system-monitor.desktop</Filename></Not>
233 </And>
234 </Include>
235 </Menu> <!-- End System Tools -->
236
237 <!-- System Settings -->
238 <Menu>
239 <Name>System Settings</Name>
240 <Directory>X-GNOME-SystemSettings.directory</Directory>
241 <Include>
242 <Category>X-GNOME-Settings-Panel</Category>
243 </Include>
244 </Menu>
245
246 <!-- Utilities submenu -->
247 <Menu>
248 <Name>Utilities</Name>
249 <Directory>X-GNOME-Utilities.directory</Directory>
250 <Include>
251 <Filename>file-roller.desktop</Filename>
252 <Filename>gnome-calculator.desktop</Filename>
253 <Filename>gnome-font-viewer.desktop</Filename>
254 <Filename>gucharmap.desktop</Filename>
255 <Filename>seahorse.desktop</Filename>
256 <Filename>gnome-terminal.desktop</Filename>
257 <Filename>deja-dup-preferences.desktop</Filename>
258 <Filename>gnome-dictionary.desktop</Filename>
259 <Filename>evince.desktop</Filename>
260 <Filename>eog.desktop</Filename>
261 <Filename>baobab.desktop</Filename>
262 <Filename>gnome-system-log.desktop</Filename>
263 <Filename>gnome-system-monitor.desktop</Filename>
264 <Filename>vinagre.desktop</Filename>
265 <Filename>gnome-tweak-tool.desktop</Filename>
266 <Filename>gnome-disks.desktop</Filename>
267 <Filename>gnome-screenshot.desktop</Filename>
268 <Filename>gnome-yelp.desktop</Filename>
269 <Filename>yelp.desktop</Filename>
270 <Filename>gnome-control-center.desktop</Filename>
271 </Include>
272 </Menu>
273
274 <!-- Other -->
275 <Menu>
276 <Name>Other</Name>
277 <Directory>X-GNOME-Other.directory</Directory>
278 <OnlyUnallocated/>
279 <Include>
280 <And>
281 <Not><Category>Core</Category></Not>
282 <Not><Category>Screensaver</Category></Not>
283
284 <!-- Really Fedora ??? -->
285 <Not><Filename>gnome-eog.desktop</Filename></Not>
286 <Not><Filename>gnome-file-roller.desktop</Filename></Not>
287 <Not><Filename>gnome-gucharmap.desktop</Filename></Not>
288 <Not><Filename>gcalctool.desktop</Filename></Not>
289 </And>
290 </Include>
291 </Menu> <!-- End Other -->
292
293 <Layout>
294 <Merge type="menus" />
295 <Menuname>Other</Menuname>
296 <Merge type="files" />
297 </Layout>
298
299 </Menu> <!-- End Applications -->
0 <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN"
1 "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd">
2
3 <Menu>
4
5 <Name>Applications</Name>
6 <Directory>X-GNOME-Menu-Applications.directory</Directory>
7
8 <!-- Scan legacy dirs first, as later items take priority -->
9 <LegacyDir>/etc/X11/applnk</LegacyDir>
10 <LegacyDir>/usr/share/gnome/apps</LegacyDir>
11
12 <!-- Read standard .directory and .desktop file locations -->
13 <DefaultAppDirs/>
14 <DefaultDirectoryDirs/>
15
16 <!-- Read in overrides and child menus from applications-merged/ -->
17 <DefaultMergeDirs/>
18
19 <!-- Accessories submenu -->
20 <Menu>
21 <Name>Accessories</Name>
22 <OnlyUnallocated/>
23 <Directory>Utility.directory</Directory>
24 <Include>
25 <And>
26 <Category>Utility</Category>
27 <!-- Accessibility spec must have either the Utility or Settings
28 category, and we display an accessibility submenu already for
29 the ones that do not have Settings, so don't display accessibility
30 applications here -->
31 <Not><Category>Accessibility</Category></Not>
32 <Not><Category>System</Category></Not>
33
34 <!-- Also exclude everything we put in the X-GNOME-Utilities
35 whitelist -->
36 <Not><Filename>file-roller.desktop</Filename></Not>
37 <Not><Filename>gnome-file-roller.desktop</Filename></Not>
38 <Not><Filename>deja-dup-preferences.desktop</Filename></Not>
39 <Not><Filename>gnome-calculator.desktop</Filename></Not>
40 <Not><Filename>gcalctool.desktop</Filename></Not>
41 <Not><Filename>gucharmap.desktop</Filename></Not>
42 <Not><Filename>gnome-gucharmap.desktop</Filename></Not>
43 <Not><Filename>gnome-font-viewer.desktop</Filename></Not>
44 <Not><Filename>seahorse.desktop</Filename></Not>
45 <Not><Filename>gnome-terminal.desktop</Filename></Not>
46 <Not><Filename>gnome-tweak-tool.desktop</Filename></Not>
47 <Not><Filename>gnome-disks.desktop</Filename></Not>
48 <Not><Filename>gnome-screenshot.desktop</Filename></Not>
49 <Not><Filename>gnome-yelp.desktop</Filename></Not>
50 <Not><Filename>yelp.desktop</Filename></Not>
51 <Not><Filename>gnome-control-center.desktop</Filename></Not>
52 </And>
53 </Include>
54 </Menu> <!-- End Accessories -->
55
56
57 <!-- Accessibility submenu -->
58 <Menu>
59 <Name>Universal Access</Name>
60 <OnlyUnallocated/>
61 <Directory>Utility-Accessibility.directory</Directory>
62 <Include>
63 <And>
64 <Category>Accessibility</Category>
65 <Not><Category>Settings</Category></Not>
66 </And>
67 </Include>
68 </Menu> <!-- End Accessibility -->
69
70 <!-- Development Tools -->
71 <Menu>
72 <Name>Development</Name>
73 <OnlyUnallocated/>
74 <Directory>Development.directory</Directory>
75 <Include>
76 <And>
77 <Category>Development</Category>
78 </And>
79 <Filename>emacs.desktop</Filename>
80 </Include>
81 </Menu> <!-- End Development Tools -->
82
83 <!-- Education -->
84 <Menu>
85 <Name>Education</Name>
86 <Directory>Education.directory</Directory>
87 <Include>
88 <And>
89 <Category>Education</Category>
90 </And>
91 </Include>
92 </Menu> <!-- End Education -->
93
94 <!-- Games -->
95 <Menu>
96 <Name>Games</Name>
97 <Directory>Game.directory</Directory>
98 <Include>
99 <And>
100 <Category>Game</Category>
101 </And>
102 </Include>
103 </Menu> <!-- End Games -->
104
105 <!-- Graphics -->
106 <Menu>
107 <Name>Graphics</Name>
108 <OnlyUnallocated/>
109 <Directory>Graphics.directory</Directory>
110 <Include>
111 <And>
112 <Category>Graphics</Category>
113 <Not><Filename>eog.desktop</Filename></Not>
114 <Not><Filename>gnome-eog.desktop</Filename></Not>
115 <Not><Filename>evince.desktop</Filename></Not>
116 </And>
117 </Include>
118 </Menu> <!-- End Graphics -->
119
120 <!-- Internet -->
121 <Menu>
122 <Name>Internet</Name>
123 <OnlyUnallocated/>
124 <Directory>Network.directory</Directory>
125 <Include>
126 <And>
127 <Category>Network</Category>
128 <Not><Category>X-GNOME-WebApplication</Category></Not>
129 <Not><Filename>vinagre.desktop</Filename></Not>
130 </And>
131 </Include>
132 </Menu> <!-- End Internet -->
133
134 <!-- Web Applications -->
135 <Menu>
136 <Name>Web Applications</Name>
137 <Directory>X-GNOME-WebApplications.directory</Directory>
138 <Include>
139 <And>
140 <Category>Network</Category>
141 <Category>X-GNOME-WebApplication</Category>
142 </And>
143 </Include>
144 </Menu>
145
146 <!-- Multimedia -->
147 <Menu>
148 <Name>Multimedia</Name>
149 <OnlyUnallocated/>
150 <Directory>AudioVideo.directory</Directory>
151 <Include>
152 <And>
153 <Category>AudioVideo</Category>
154 </And>
155 </Include>
156 </Menu> <!-- End Multimedia -->
157
158 <!-- Office -->
159 <Menu>
160 <Name>Office</Name>
161 <OnlyUnallocated/>
162 <Directory>Office.directory</Directory>
163 <Include>
164 <And>
165 <Category>Office</Category>
166 <Not><Filename>evince.desktop</Filename></Not>
167 <Not><Filename>gnome-dictionary.desktop</Filename></Not>
168 </And>
169 </Include>
170 </Menu> <!-- End Office -->
171
172 <!-- Sundry -->
173 <Menu>
174 <Name>Sundry</Name>
175 <Directory>X-GNOME-Sundry.directory</Directory>
176 <Include>
177 <Filename>alacarte.desktop</Filename>
178 <Filename>caribou.desktop</Filename>
179 <Filename>dconf-editor.desktop</Filename>
180 <Filename>fedora-im-chooser.desktop</Filename>
181 <Filename>fedora-release-notes.desktop</Filename>
182 <Filename>firewall-config.desktop</Filename>
183 <Filename>flash-player-properties.desktop</Filename>
184 <Filename>gconf-editor.desktop</Filename>
185 <Filename>gnome-abrt.desktop</Filename>
186 <Filename>fedora-abrt.desktop</Filename>
187 <Filename>gnome-orca.desktop</Filename>
188 <Filename>gnome-power-statistics.desktop</Filename>
189 <Filename>gnome-user-share-properties.desktop</Filename>
190 <Filename>ibus.desktop</Filename>
191 <Filename>ibus-daemon.desktop</Filename>
192 <Filename>ibus-setup-anthy.desktop</Filename>
193 <Filename>ibus-setup.desktop</Filename>
194 <Filename>ibus-setup-hangul.desktop</Filename>
195 <Filename>ibus-setup-libbopomofo.desktop</Filename>
196 <Filename>ibus-setup-libpinyin.desktop</Filename>
197 <Filename>ibus-setup-m17n.desktop</Filename>
198 <Filename>ibus-setup-typing-booster.desktop</Filename>
199 <Filename>im-chooser.desktop</Filename>
200 <Filename>itweb-settings.desktop</Filename>
201 <Filename>jhbuild.desktop</Filename>
202 <Filename>javaws.desktop</Filename>
203 <Filename>java-1.7.0-openjdk-jconsole.desktop</Filename>
204 <Filename>java-1.7.0-openjdk-policytool.desktop</Filename>
205 <Filename>log4j-chainsaw.desktop</Filename>
206 <Filename>log4j-logfactor5.desktop</Filename>
207 <Filename>nm-connection-editor.desktop</Filename>
208 <Filename>orca.desktop</Filename>
209 <Filename>setroubleshoot.desktop</Filename>
210 <Filename>authconfig.desktop</Filename>
211 <Filename>system-config-date.desktop</Filename>
212 <Filename>system-config-firewall.desktop</Filename>
213 <Filename>system-config-keyboard.desktop</Filename>
214 <Filename>system-config-language.desktop</Filename>
215 <Filename>system-config-printer.desktop</Filename>
216 <Filename>system-config-users.desktop</Filename>
217 <Filename>vino-preferences.desktop</Filename>
218 </Include>
219 </Menu>
220
221 <!-- System Tools-->
222 <Menu>
223 <Name>System</Name>
224 <OnlyUnallocated/>
225 <Directory>System-Tools.directory</Directory>
226 <Include>
227 <And>
228 <Category>System</Category>
229 <Not><Category>Settings</Category></Not>
230 <Not><Filename>baobab.desktop</Filename></Not>
231 <Not><Filename>gnome-system-log.desktop</Filename></Not>
232 <Not><Filename>gnome-system-monitor.desktop</Filename></Not>
233 </And>
234 </Include>
235 <Menu>
236 <Name>Preferences</Name>
237 <Directory>Settings.directory</Directory>
238 <Include>
239 <And>
240 <Category>Settings</Category>
241 <Not>
242 <Or>
243 <Category>System</Category>
244 <Category>X-GNOME-Settings-Panel</Category>
245 <Filename>alacarte.desktop</Filename>
246 <Filename>caribou.desktop</Filename>
247 <Filename>dconf-editor.desktop</Filename>
248 <Filename>fedora-im-chooser.desktop</Filename>
249 <Filename>fedora-release-notes.desktop</Filename>
250 <Filename>firewall-config.desktop</Filename>
251 <Filename>flash-player-properties.desktop</Filename>
252 <Filename>gconf-editor.desktop</Filename>
253 <Filename>gnome-abrt.desktop</Filename>
254 <Filename>fedora-abrt.desktop</Filename>
255 <Filename>gnome-orca.desktop</Filename>
256 <Filename>gnome-power-statistics.desktop</Filename>
257 <Filename>gnome-user-share-properties.desktop</Filename>
258 <Filename>ibus.desktop</Filename>
259 <Filename>ibus-daemon.desktop</Filename>
260 <Filename>ibus-setup-anthy.desktop</Filename>
261 <Filename>ibus-setup.desktop</Filename>
262 <Filename>ibus-setup-hangul.desktop</Filename>
263 <Filename>ibus-setup-libbopomofo.desktop</Filename>
264 <Filename>ibus-setup-libpinyin.desktop</Filename>
265 <Filename>ibus-setup-m17n.desktop</Filename>
266 <Filename>ibus-setup-typing-booster.desktop</Filename>
267 <Filename>im-chooser.desktop</Filename>
268 <Filename>itweb-settings.desktop</Filename>
269 <Filename>jhbuild.desktop</Filename>
270 <Filename>javaws.desktop</Filename>
271 <Filename>java-1.7.0-openjdk-jconsole.desktop</Filename>
272 <Filename>java-1.7.0-openjdk-policytool.desktop</Filename>
273 <Filename>log4j-chainsaw.desktop</Filename>
274 <Filename>log4j-logfactor5.desktop</Filename>
275 <Filename>nm-connection-editor.desktop</Filename>
276 <Filename>orca.desktop</Filename>
277 <Filename>setroubleshoot.desktop</Filename>
278 <Filename>authconfig.desktop</Filename>
279 <Filename>system-config-date.desktop</Filename>
280 <Filename>system-config-firewall.desktop</Filename>
281 <Filename>system-config-keyboard.desktop</Filename>
282 <Filename>system-config-language.desktop</Filename>
283 <Filename>system-config-printer.desktop</Filename>
284 <Filename>system-config-users.desktop</Filename>
285 <Filename>vino-preferences.desktop</Filename>
286 </Or>
287 </Not>
288 </And>
289 </Include>
290 </Menu>
291 <Menu>
292 <Name>Administration</Name>
293 <Directory>Settings-System.directory</Directory>
294 <Include>
295 <And>
296 <Category>Settings</Category>
297 <Category>System</Category>
298 <Not>
299 <Or>
300 <Category>X-GNOME-Settings-Panel</Category>
301 <Filename>alacarte.desktop</Filename>
302 <Filename>caribou.desktop</Filename>
303 <Filename>dconf-editor.desktop</Filename>
304 <Filename>fedora-im-chooser.desktop</Filename>
305 <Filename>fedora-release-notes.desktop</Filename>
306 <Filename>firewall-config.desktop</Filename>
307 <Filename>flash-player-properties.desktop</Filename>
308 <Filename>gconf-editor.desktop</Filename>
309 <Filename>gnome-abrt.desktop</Filename>
310 <Filename>fedora-abrt.desktop</Filename>
311 <Filename>gnome-orca.desktop</Filename>
312 <Filename>gnome-power-statistics.desktop</Filename>
313 <Filename>gnome-user-share-properties.desktop</Filename>
314 <Filename>ibus.desktop</Filename>
315 <Filename>ibus-daemon.desktop</Filename>
316 <Filename>ibus-setup-anthy.desktop</Filename>
317 <Filename>ibus-setup.desktop</Filename>
318 <Filename>ibus-setup-hangul.desktop</Filename>
319 <Filename>ibus-setup-libbopomofo.desktop</Filename>
320 <Filename>ibus-setup-libpinyin.desktop</Filename>
321 <Filename>ibus-setup-m17n.desktop</Filename>
322 <Filename>ibus-setup-typing-booster.desktop</Filename>
323 <Filename>im-chooser.desktop</Filename>
324 <Filename>itweb-settings.desktop</Filename>
325 <Filename>jhbuild.desktop</Filename>
326 <Filename>javaws.desktop</Filename>
327 <Filename>java-1.7.0-openjdk-jconsole.desktop</Filename>
328 <Filename>java-1.7.0-openjdk-policytool.desktop</Filename>
329 <Filename>log4j-chainsaw.desktop</Filename>
330 <Filename>log4j-logfactor5.desktop</Filename>
331 <Filename>nm-connection-editor.desktop</Filename>
332 <Filename>orca.desktop</Filename>
333 <Filename>setroubleshoot.desktop</Filename>
334 <Filename>authconfig.desktop</Filename>
335 <Filename>system-config-date.desktop</Filename>
336 <Filename>system-config-firewall.desktop</Filename>
337 <Filename>system-config-keyboard.desktop</Filename>
338 <Filename>system-config-language.desktop</Filename>
339 <Filename>system-config-printer.desktop</Filename>
340 <Filename>system-config-users.desktop</Filename>
341 <Filename>vino-preferences.desktop</Filename>
342 </Or>
343 </Not>
344 </And>
345 </Include>
346 </Menu>
347 </Menu> <!-- End System Tools -->
348
349 <!-- System Settings -->
350 <Menu>
351 <Name>System Settings</Name>
352 <Directory>X-GNOME-SystemSettings.directory</Directory>
353 <Include>
354 <Category>X-GNOME-Settings-Panel</Category>
355 </Include>
356 </Menu>
357
358 <!-- Utilities submenu -->
359 <Menu>
360 <Name>Utilities</Name>
361 <Directory>X-GNOME-Utilities.directory</Directory>
362 <Include>
363 <Filename>file-roller.desktop</Filename>
364 <Filename>gnome-calculator.desktop</Filename>
365 <Filename>gnome-font-viewer.desktop</Filename>
366 <Filename>gucharmap.desktop</Filename>
367 <Filename>seahorse.desktop</Filename>
368 <Filename>gnome-terminal.desktop</Filename>
369 <Filename>deja-dup-preferences.desktop</Filename>
370 <Filename>gnome-dictionary.desktop</Filename>
371 <Filename>evince.desktop</Filename>
372 <Filename>eog.desktop</Filename>
373 <Filename>baobab.desktop</Filename>
374 <Filename>gnome-system-log.desktop</Filename>
375 <Filename>gnome-system-monitor.desktop</Filename>
376 <Filename>vinagre.desktop</Filename>
377 <Filename>gnome-tweak-tool.desktop</Filename>
378 <Filename>gnome-disks.desktop</Filename>
379 <Filename>gnome-screenshot.desktop</Filename>
380 <Filename>gnome-yelp.desktop</Filename>
381 <Filename>yelp.desktop</Filename>
382 <Filename>gnome-control-center.desktop</Filename>
383 </Include>
384 </Menu>
385
386 <!-- Other -->
387 <Menu>
388 <Name>Other</Name>
389 <Directory>X-GNOME-Other.directory</Directory>
390 <OnlyUnallocated/>
391 <Include>
392 <And>
393 <Not><Category>Core</Category></Not>
394 <Not><Category>Screensaver</Category></Not>
395
396 <!-- Really Fedora ??? -->
397 <Not><Filename>gnome-eog.desktop</Filename></Not>
398 <Not><Filename>gnome-file-roller.desktop</Filename></Not>
399 <Not><Filename>gnome-gucharmap.desktop</Filename></Not>
400 <Not><Filename>gcalctool.desktop</Filename></Not>
401 </And>
402 </Include>
403 </Menu> <!-- End Other -->
404
405 <Layout>
406 <Merge type="menus" />
407 <Menuname>Other</Menuname>
408 <Merge type="files" />
409 </Layout>
410
411 </Menu> <!-- End Applications -->
0 <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN"
1 "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd">
2
3 <Menu>
4
5 <Name>Applications</Name>
6 <Directory>X-GNOME-Menu-Applications.directory</Directory>
7
8 <!-- Scan legacy dirs first, as later items take priority -->
9 <LegacyDir>/etc/X11/applnk</LegacyDir>
10 <LegacyDir>/usr/share/gnome/apps</LegacyDir>
11
12 <!-- Read standard .directory and .desktop file locations -->
13 <DefaultAppDirs/>
14 <DefaultDirectoryDirs/>
15
16 <!-- Read in overrides and child menus from applications-merged/ -->
17 <DefaultMergeDirs/>
18
19 <!-- Accessories submenu -->
20 <Menu>
21 <Name>Accessories</Name>
22 <OnlyUnallocated/>
23 <Directory>Utility.directory</Directory>
24 <Include>
25 <And>
26 <Category>Utility</Category>
27 <!-- Accessibility spec must have either the Utility or Settings
28 category, and we display an accessibility submenu already for
29 the ones that do not have Settings, so don't display accessibility
30 applications here -->
31 <Not><Category>Accessibility</Category></Not>
32 <Not><Category>System</Category></Not>
33
34 <!-- Also exclude everything we put in the X-GNOME-Utilities
35 whitelist -->
36 <Not><Filename>file-roller.desktop</Filename></Not>
37 <Not><Filename>gnome-file-roller.desktop</Filename></Not>
38 <Not><Filename>deja-dup-preferences.desktop</Filename></Not>
39 <Not><Filename>gnome-calculator.desktop</Filename></Not>
40 <Not><Filename>gcalctool.desktop</Filename></Not>
41 <Not><Filename>gucharmap.desktop</Filename></Not>
42 <Not><Filename>gnome-gucharmap.desktop</Filename></Not>
43 <Not><Filename>gnome-font-viewer.desktop</Filename></Not>
44 <Not><Filename>seahorse.desktop</Filename></Not>
45 <Not><Filename>gnome-terminal.desktop</Filename></Not>
46 <Not><Filename>gnome-tweak-tool.desktop</Filename></Not>
47 <Not><Filename>gnome-disks.desktop</Filename></Not>
48 <Not><Filename>gnome-screenshot.desktop</Filename></Not>
49 <Not><Filename>gnome-yelp.desktop</Filename></Not>
50 <Not><Filename>yelp.desktop</Filename></Not>
51 <Not><Filename>gnome-control-center.desktop</Filename></Not>
52 </And>
53 </Include>
54 </Menu> <!-- End Accessories -->
55
56
57 <!-- Accessibility submenu -->
58 <Menu>
59 <Name>Universal Access</Name>
60 <OnlyUnallocated/>
61 <Directory>Utility-Accessibility.directory</Directory>
62 <Include>
63 <And>
64 <Category>Accessibility</Category>
65 <Not><Category>Settings</Category></Not>
66 </And>
67 </Include>
68 </Menu> <!-- End Accessibility -->
69
70 <!-- Development Tools -->
71 <Menu>
72 <Name>Development</Name>
73 <OnlyUnallocated/>
74 <Directory>Development.directory</Directory>
75 <Include>
76 <And>
77 <Category>Development</Category>
78 </And>
79 <Filename>emacs.desktop</Filename>
80 </Include>
81 </Menu> <!-- End Development Tools -->
82
83 <!-- Education -->
84 <Menu>
85 <Name>Education</Name>
86 <Directory>Education.directory</Directory>
87 <Include>
88 <And>
89 <Category>Education</Category>
90 </And>
91 </Include>
92 </Menu> <!-- End Education -->
93
94 <!-- Games -->
95 <Menu>
96 <Name>Games</Name>
97 <Directory>Game.directory</Directory>
98 <Include>
99 <And>
100 <Category>Game</Category>
101 </And>
102 </Include>
103 </Menu> <!-- End Games -->
104
105 <!-- Graphics -->
106 <Menu>
107 <Name>Graphics</Name>
108 <OnlyUnallocated/>
109 <Directory>Graphics.directory</Directory>
110 <Include>
111 <And>
112 <Category>Graphics</Category>
113 <Not><Filename>eog.desktop</Filename></Not>
114 <Not><Filename>gnome-eog.desktop</Filename></Not>
115 <Not><Filename>evince.desktop</Filename></Not>
116 </And>
117 </Include>
118 </Menu> <!-- End Graphics -->
119
120 <!-- Internet -->
121 <Menu>
122 <Name>Internet</Name>
123 <OnlyUnallocated/>
124 <Directory>Network.directory</Directory>
125 <Include>
126 <And>
127 <Category>Network</Category>
128 <Not><Category>X-GNOME-WebApplication</Category></Not>
129 <Not><Filename>vinagre.desktop</Filename></Not>
130 </And>
131 </Include>
132 </Menu> <!-- End Internet -->
133
134 <!-- Web Applications -->
135 <Menu>
136 <Name>Web Applications</Name>
137 <Directory>X-GNOME-WebApplications.directory</Directory>
138 <Include>
139 <And>
140 <Category>Network</Category>
141 <Category>X-GNOME-WebApplication</Category>
142 </And>
143 </Include>
144 </Menu>
145
146 <!-- Multimedia -->
147 <Menu>
148 <Name>Multimedia</Name>
149 <OnlyUnallocated/>
150 <Directory>AudioVideo.directory</Directory>
151 <Include>
152 <And>
153 <Category>AudioVideo</Category>
154 </And>
155 </Include>
156 </Menu> <!-- End Multimedia -->
157
158 <!-- Office -->
159 <Menu>
160 <Name>Office</Name>
161 <OnlyUnallocated/>
162 <Directory>Office.directory</Directory>
163 <Include>
164 <And>
165 <Category>Office</Category>
166 <Not><Filename>evince.desktop</Filename></Not>
167 <Not><Filename>gnome-dictionary.desktop</Filename></Not>
168 </And>
169 </Include>
170 </Menu> <!-- End Office -->
171
172 <!-- Sundry -->
173 <Menu>
174 <Name>Sundry</Name>
175 <Directory>X-GNOME-Sundry.directory</Directory>
176 <Include>
177 <Filename>alacarte.desktop</Filename>
178 <Filename>caribou.desktop</Filename>
179 <Filename>dconf-editor.desktop</Filename>
180 <Filename>fedora-im-chooser.desktop</Filename>
181 <Filename>fedora-release-notes.desktop</Filename>
182 <Filename>firewall-config.desktop</Filename>
183 <Filename>flash-player-properties.desktop</Filename>
184 <Filename>gconf-editor.desktop</Filename>
185 <Filename>gnome-abrt.desktop</Filename>
186 <Filename>fedora-abrt.desktop</Filename>
187 <Filename>gnome-orca.desktop</Filename>
188 <Filename>gnome-power-statistics.desktop</Filename>
189 <Filename>gnome-user-share-properties.desktop</Filename>
190 <Filename>ibus.desktop</Filename>
191 <Filename>ibus-daemon.desktop</Filename>
192 <Filename>ibus-setup-anthy.desktop</Filename>
193 <Filename>ibus-setup.desktop</Filename>
194 <Filename>ibus-setup-hangul.desktop</Filename>
195 <Filename>ibus-setup-libbopomofo.desktop</Filename>
196 <Filename>ibus-setup-libpinyin.desktop</Filename>
197 <Filename>ibus-setup-m17n.desktop</Filename>
198 <Filename>ibus-setup-typing-booster.desktop</Filename>
199 <Filename>im-chooser.desktop</Filename>
200 <Filename>itweb-settings.desktop</Filename>
201 <Filename>jhbuild.desktop</Filename>
202 <Filename>javaws.desktop</Filename>
203 <Filename>java-1.7.0-openjdk-jconsole.desktop</Filename>
204 <Filename>java-1.7.0-openjdk-policytool.desktop</Filename>
205 <Filename>log4j-chainsaw.desktop</Filename>
206 <Filename>log4j-logfactor5.desktop</Filename>
207 <Filename>nm-connection-editor.desktop</Filename>
208 <Filename>orca.desktop</Filename>
209 <Filename>setroubleshoot.desktop</Filename>
210 <Filename>authconfig.desktop</Filename>
211 <Filename>system-config-date.desktop</Filename>
212 <Filename>system-config-firewall.desktop</Filename>
213 <Filename>system-config-keyboard.desktop</Filename>
214 <Filename>system-config-language.desktop</Filename>
215 <Filename>system-config-printer.desktop</Filename>
216 <Filename>system-config-users.desktop</Filename>
217 <Filename>vino-preferences.desktop</Filename>
218 </Include>
219 </Menu>
220
221 <!-- System Tools-->
222 <Menu>
223 <Name>System</Name>
224 <OnlyUnallocated/>
225 <Directory>System-Tools.directory</Directory>
226 <Include>
227 <And>
228 <Category>System</Category>
229 <Not><Category>Settings</Category></Not>
230 <Not><Filename>baobab.desktop</Filename></Not>
231 <Not><Filename>gnome-system-log.desktop</Filename></Not>
232 <Not><Filename>gnome-system-monitor.desktop</Filename></Not>
233 </And>
234 </Include>
235 <Menu>
236 <Name>Preferences</Name>
237 <Directory>Settings.directory</Directory>
238 <Include>
239 <And>
240 <Category>Settings</Category>
241 <Not>
242 <Or>
243 <Category>System</Category>
244 <Category>X-GNOME-Settings-Panel</Category>
245 <Filename>alacarte.desktop</Filename>
246 <Filename>caribou.desktop</Filename>
247 <Filename>dconf-editor.desktop</Filename>
248 <Filename>fedora-im-chooser.desktop</Filename>
249 <Filename>fedora-release-notes.desktop</Filename>
250 <Filename>firewall-config.desktop</Filename>
251 <Filename>flash-player-properties.desktop</Filename>
252 <Filename>gconf-editor.desktop</Filename>
253 <Filename>gnome-abrt.desktop</Filename>
254 <Filename>fedora-abrt.desktop</Filename>
255 <Filename>gnome-orca.desktop</Filename>
256 <Filename>gnome-power-statistics.desktop</Filename>
257 <Filename>gnome-user-share-properties.desktop</Filename>
258 <Filename>ibus.desktop</Filename>
259 <Filename>ibus-daemon.desktop</Filename>
260 <Filename>ibus-setup-anthy.desktop</Filename>
261 <Filename>ibus-setup.desktop</Filename>
262 <Filename>ibus-setup-hangul.desktop</Filename>
263 <Filename>ibus-setup-libbopomofo.desktop</Filename>
264 <Filename>ibus-setup-libpinyin.desktop</Filename>
265 <Filename>ibus-setup-m17n.desktop</Filename>
266 <Filename>ibus-setup-typing-booster.desktop</Filename>
267 <Filename>im-chooser.desktop</Filename>
268 <Filename>itweb-settings.desktop</Filename>
269 <Filename>jhbuild.desktop</Filename>
270 <Filename>javaws.desktop</Filename>
271 <Filename>java-1.7.0-openjdk-jconsole.desktop</Filename>
272 <Filename>java-1.7.0-openjdk-policytool.desktop</Filename>
273 <Filename>log4j-chainsaw.desktop</Filename>
274 <Filename>log4j-logfactor5.desktop</Filename>
275 <Filename>nm-connection-editor.desktop</Filename>
276 <Filename>orca.desktop</Filename>
277 <Filename>setroubleshoot.desktop</Filename>
278 <Filename>authconfig.desktop</Filename>
279 <Filename>system-config-date.desktop</Filename>
280 <Filename>system-config-firewall.desktop</Filename>
281 <Filename>system-config-keyboard.desktop</Filename>
282 <Filename>system-config-language.desktop</Filename>
283 <Filename>system-config-printer.desktop</Filename>
284 <Filename>system-config-users.desktop</Filename>
285 <Filename>vino-preferences.desktop</Filename>
286 </Or>
287 </Not>
288 </And>
289 </Include>
290 </Menu>
291 <Menu>
292 <Name>Administration</Name>
293 <Directory>Settings-System.directory</Directory>
294 <Include>
295 <And>
296 <Category>Settings</Category>
297 <Category>System</Category>
298 <Not>
299 <Or>
300 <Category>X-GNOME-Settings-Panel</Category>
301 <Filename>alacarte.desktop</Filename>
302 <Filename>caribou.desktop</Filename>
303 <Filename>dconf-editor.desktop</Filename>
304 <Filename>fedora-im-chooser.desktop</Filename>
305 <Filename>fedora-release-notes.desktop</Filename>
306 <Filename>firewall-config.desktop</Filename>
307 <Filename>flash-player-properties.desktop</Filename>
308 <Filename>gconf-editor.desktop</Filename>
309 <Filename>gnome-abrt.desktop</Filename>
310 <Filename>fedora-abrt.desktop</Filename>
311 <Filename>gnome-orca.desktop</Filename>
312 <Filename>gnome-power-statistics.desktop</Filename>
313 <Filename>gnome-user-share-properties.desktop</Filename>
314 <Filename>ibus.desktop</Filename>
315 <Filename>ibus-daemon.desktop</Filename>
316 <Filename>ibus-setup-anthy.desktop</Filename>
317 <Filename>ibus-setup.desktop</Filename>
318 <Filename>ibus-setup-hangul.desktop</Filename>
319 <Filename>ibus-setup-libbopomofo.desktop</Filename>
320 <Filename>ibus-setup-libpinyin.desktop</Filename>
321 <Filename>ibus-setup-m17n.desktop</Filename>
322 <Filename>ibus-setup-typing-booster.desktop</Filename>
323 <Filename>im-chooser.desktop</Filename>
324 <Filename>itweb-settings.desktop</Filename>
325 <Filename>jhbuild.desktop</Filename>
326 <Filename>javaws.desktop</Filename>
327 <Filename>java-1.7.0-openjdk-jconsole.desktop</Filename>
328 <Filename>java-1.7.0-openjdk-policytool.desktop</Filename>
329 <Filename>log4j-chainsaw.desktop</Filename>
330 <Filename>log4j-logfactor5.desktop</Filename>
331 <Filename>nm-connection-editor.desktop</Filename>
332 <Filename>orca.desktop</Filename>
333 <Filename>setroubleshoot.desktop</Filename>
334 <Filename>authconfig.desktop</Filename>
335 <Filename>system-config-date.desktop</Filename>
336 <Filename>system-config-firewall.desktop</Filename>
337 <Filename>system-config-keyboard.desktop</Filename>
338 <Filename>system-config-language.desktop</Filename>
339 <Filename>system-config-printer.desktop</Filename>
340 <Filename>system-config-users.desktop</Filename>
341 <Filename>vino-preferences.desktop</Filename>
342 </Or>
343 </Not>
344 </And>
345 </Include>
346 </Menu>
347 </Menu> <!-- End System Tools -->
348
349 <!-- System Settings -->
350 <Menu>
351 <Name>System Settings</Name>
352 <Directory>X-GNOME-SystemSettings.directory</Directory>
353 <Include>
354 <Category>X-GNOME-Settings-Panel</Category>
355 </Include>
356 </Menu>
357
358 <!-- Utilities submenu -->
359 <Menu>
360 <Name>Utilities</Name>
361 <Directory>X-GNOME-Utilities.directory</Directory>
362 <Include>
363 <Filename>file-roller.desktop</Filename>
364 <Filename>gnome-calculator.desktop</Filename>
365 <Filename>gnome-font-viewer.desktop</Filename>
366 <Filename>gucharmap.desktop</Filename>
367 <Filename>seahorse.desktop</Filename>
368 <Filename>gnome-terminal.desktop</Filename>
369 <Filename>deja-dup-preferences.desktop</Filename>
370 <Filename>gnome-dictionary.desktop</Filename>
371 <Filename>evince.desktop</Filename>
372 <Filename>eog.desktop</Filename>
373 <Filename>baobab.desktop</Filename>
374 <Filename>gnome-system-log.desktop</Filename>
375 <Filename>gnome-system-monitor.desktop</Filename>
376 <Filename>vinagre.desktop</Filename>
377 <Filename>gnome-tweak-tool.desktop</Filename>
378 <Filename>gnome-disks.desktop</Filename>
379 <Filename>gnome-screenshot.desktop</Filename>
380 <Filename>gnome-yelp.desktop</Filename>
381 <Filename>yelp.desktop</Filename>
382 <Filename>gnome-control-center.desktop</Filename>
383 </Include>
384 </Menu>
385
386 <!-- Other -->
387 <Menu>
388 <Name>Other</Name>
389 <Directory>X-GNOME-Other.directory</Directory>
390 <OnlyUnallocated/>
391 <Include>
392 <And>
393 <Not><Category>Core</Category></Not>
394 <Not><Category>Screensaver</Category></Not>
395
396 <!-- Really Fedora ??? -->
397 <Not><Filename>gnome-eog.desktop</Filename></Not>
398 <Not><Filename>gnome-file-roller.desktop</Filename></Not>
399 <Not><Filename>gnome-gucharmap.desktop</Filename></Not>
400 <Not><Filename>gcalctool.desktop</Filename></Not>
401 </And>
402 </Include>
403 </Menu> <!-- End Other -->
404
405 <Layout>
406 <Merge type="menus" />
407 <Menuname>Other</Menuname>
408 <Merge type="files" />
409 </Layout>
410
411 <Include>
412 <Filename>ubuntu-software-center.desktop</Filename>
413 </Include>
414
415 <!-- Separator between menus and gnome-app-install -->
416 <Layout>
417 <Merge type="menus"/>
418 <Merge type="files"/>
419 <Separator/>
420 <Filename>ubuntu-software-center.desktop</Filename>
421 </Layout>
422
423 </Menu> <!-- End Applications -->
0 [Desktop Entry]
1 _Name=Education
2 Icon=applications-science
3 Type=Directory
0 [Desktop Entry]
1 _Name=Accessories
2 _Comment=Desktop accessories
3 Icon=applications-accessories
4 Type=Directory
0 <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN"
1 "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd">
2
3 <Menu>
4
5 <Name>Applications</Name>
6 <Directory>X-GNOME-Menu-Applications.directory</Directory>
7
8 <!-- Scan legacy dirs first, as later items take priority -->
9 <LegacyDir>/etc/X11/applnk</LegacyDir>
10 <LegacyDir>/usr/share/gnome/apps</LegacyDir>
11
12 <!-- Read standard .directory and .desktop file locations -->
13 <DefaultAppDirs/>
14 <DefaultDirectoryDirs/>
15
16 <!-- Read in overrides and child menus from applications-merged/ -->
17 <DefaultMergeDirs/>
18
19 <!-- Accessories submenu -->
20 <Menu>
21 <Name>Accessories</Name>
22 <OnlyUnallocated/>
23 <Directory>Utility.directory</Directory>
24 <Include>
25 <And>
26 <Category>Utility</Category>
27 <!-- Accessibility spec must have either the Utility or Settings
28 category, and we display an accessibility submenu already for
29 the ones that do not have Settings, so don't display accessibility
30 applications here -->
31 <Not><Category>Accessibility</Category></Not>
32 <Not><Category>System</Category></Not>
33
34 <!-- Also exclude everything we put in the X-GNOME-Utilities
35 whitelist -->
36 <Not><Filename>file-roller.desktop</Filename></Not>
37 <Not><Filename>gnome-file-roller.desktop</Filename></Not>
38 <Not><Filename>deja-dup-preferences.desktop</Filename></Not>
39 <Not><Filename>gnome-calculator.desktop</Filename></Not>
40 <Not><Filename>gcalctool.desktop</Filename></Not>
41 <Not><Filename>gucharmap.desktop</Filename></Not>
42 <Not><Filename>gnome-gucharmap.desktop</Filename></Not>
43 <Not><Filename>gnome-font-viewer.desktop</Filename></Not>
44 <Not><Filename>seahorse.desktop</Filename></Not>
45 <Not><Filename>gnome-terminal.desktop</Filename></Not>
46 <Not><Filename>gnome-tweak-tool.desktop</Filename></Not>
47 <Not><Filename>gnome-disks.desktop</Filename></Not>
48 <Not><Filename>gnome-screenshot.desktop</Filename></Not>
49 <Not><Filename>gnome-yelp.desktop</Filename></Not>
50 <Not><Filename>yelp.desktop</Filename></Not>
51 <Not><Filename>gnome-control-center.desktop</Filename></Not>
52 </And>
53 </Include>
54 </Menu> <!-- End Accessories -->
55
56
57 <!-- Accessibility submenu -->
58 <Menu>
59 <Name>Universal Access</Name>
60 <OnlyUnallocated/>
61 <Directory>Utility-Accessibility.directory</Directory>
62 <Include>
63 <And>
64 <Category>Accessibility</Category>
65 <Not><Category>Settings</Category></Not>
66 </And>
67 </Include>
68 </Menu> <!-- End Accessibility -->
69
70 <!-- Development Tools -->
71 <Menu>
72 <Name>Development</Name>
73 <OnlyUnallocated/>
74 <Directory>Development.directory</Directory>
75 <Include>
76 <And>
77 <Category>Development</Category>
78 </And>
79 <Filename>emacs.desktop</Filename>
80 </Include>
81 </Menu> <!-- End Development Tools -->
82
83 <!-- Education -->
84 <Menu>
85 <Name>Education</Name>
86 <Directory>Education.directory</Directory>
87 <Include>
88 <And>
89 <Category>Education</Category>
90 </And>
91 </Include>
92 </Menu> <!-- End Education -->
93
94 <!-- Games -->
95 <Menu>
96 <Name>Games</Name>
97 <Directory>Game.directory</Directory>
98 <Include>
99 <And>
100 <Category>Game</Category>
101 <Not><Category>ActionGame</Category></Not>
102 <Not><Category>AdventureGame</Category></Not>
103 <Not><Category>ArcadeGame</Category></Not>
104 <Not><Category>BoardGame</Category></Not>
105 <Not><Category>BlocksGame</Category></Not>
106 <Not><Category>CardGame</Category></Not>
107 <Not><Category>KidsGame</Category></Not>
108 <Not><Category>LogicGame</Category></Not>
109 <Not><Category>Simulation</Category></Not>
110 <Not><Category>SportsGame</Category></Not>
111 <Not><Category>StrategyGame</Category></Not>
112 </And>
113 </Include>
114 <DefaultLayout inline="true" inline_limit="6" inline_header="false">
115 <Merge type="menus"/>
116 <Merge type="files"/>
117 </DefaultLayout>
118 <Menu>
119 <Name>Action</Name>
120 <Directory>ActionGames.directory</Directory>
121 <Include>
122 <Category>ActionGame</Category>
123 </Include>
124 </Menu>
125 <Menu>
126 <Name>Adventure</Name>
127 <Directory>AdventureGames.directory</Directory>
128 <Include>
129 <Category>AdventureGame</Category>
130 </Include>
131 </Menu>
132 <Menu>
133 <Name>Arcade</Name>
134 <Directory>ArcadeGames.directory</Directory>
135 <Include>
136 <Category>ArcadeGame</Category>
137 </Include>
138 </Menu>
139 <Menu>
140 <Name>Board</Name>
141 <Directory>BoardGames.directory</Directory>
142 <Include>
143 <Category>BoardGame</Category>
144 </Include>
145 </Menu>
146 <Menu>
147 <Name>Blocks</Name>
148 <Directory>BlocksGames.directory</Directory>
149 <Include>
150 <Category>BlocksGame</Category>
151 </Include>
152 </Menu>
153 <Menu>
154 <Name>Cards</Name>
155 <Directory>CardGames.directory</Directory>
156 <Include>
157 <Category>CardGame</Category>
158 </Include>
159 </Menu>
160 <Menu>
161 <Name>Kids</Name>
162 <Directory>KidsGames.directory</Directory>
163 <Include>
164 <Category>KidsGame</Category>
165 </Include>
166 </Menu>
167 <Menu>
168 <Name>Logic</Name>
169 <Directory>LogicGames.directory</Directory>
170 <Include>
171 <Category>LogicGame</Category>
172 </Include>
173 </Menu>
174 <Menu>
175 <Name>Role Playing</Name>
176 <Directory>RolePlayingGames.directory</Directory>
177 <Include>
178 <Category>RolePlaying</Category>
179 </Include>
180 </Menu>
181 <Menu>
182 <Name>Simulation</Name>
183 <Directory>SimulationGames.directory</Directory>
184 <Include>
185 <Category>Simulation</Category>
186 </Include>
187 </Menu>
188 <Menu>
189 <Name>Sports</Name>
190 <Directory>SportsGames.directory</Directory>
191 <Include>
192 <Category>SportsGame</Category>
193 </Include>
194 </Menu>
195 <Menu>
196 <Name>Strategy</Name>
197 <Directory>StrategyGames.directory</Directory>
198 <Include>
199 <Category>StrategyGame</Category>
200 </Include>
201 </Menu>
202 </Menu> <!-- End Games -->
203
204 <!-- Graphics -->
205 <Menu>
206 <Name>Graphics</Name>
207 <OnlyUnallocated/>
208 <Directory>Graphics.directory</Directory>
209 <Include>
210 <And>
211 <Category>Graphics</Category>
212 <Not><Filename>eog.desktop</Filename></Not>
213 <Not><Filename>gnome-eog.desktop</Filename></Not>
214 <Not><Filename>evince.desktop</Filename></Not>
215 </And>
216 </Include>
217 </Menu> <!-- End Graphics -->
218
219 <!-- Internet -->
220 <Menu>
221 <Name>Internet</Name>
222 <OnlyUnallocated/>
223 <Directory>Network.directory</Directory>
224 <Include>
225 <And>
226 <Category>Network</Category>
227 <Not><Category>X-GNOME-WebApplication</Category></Not>
228 <Not><Filename>vinagre.desktop</Filename></Not>
229 </And>
230 </Include>
231 </Menu> <!-- End Internet -->
232
233 <!-- Web Applications -->
234 <Menu>
235 <Name>Web Applications</Name>
236 <Directory>X-GNOME-WebApplications.directory</Directory>
237 <Include>
238 <And>
239 <Category>Network</Category>
240 <Category>X-GNOME-WebApplication</Category>
241 </And>
242 </Include>
243 </Menu>
244
245 <!-- Multimedia -->
246 <Menu>
247 <Name>Multimedia</Name>
248 <OnlyUnallocated/>
249 <Directory>AudioVideo.directory</Directory>
250 <Include>
251 <And>
252 <Category>AudioVideo</Category>
253 </And>
254 </Include>
255 </Menu> <!-- End Multimedia -->
256
257 <!-- Office -->
258 <Menu>
259 <Name>Office</Name>
260 <OnlyUnallocated/>
261 <Directory>Office.directory</Directory>
262 <Include>
263 <And>
264 <Category>Office</Category>
265 <Not><Filename>evince.desktop</Filename></Not>
266 <Not><Filename>gnome-dictionary.desktop</Filename></Not>
267 </And>
268 </Include>
269 </Menu> <!-- End Office -->
270
271 <!-- Sundry -->
272 <Menu>
273 <Name>Sundry</Name>
274 <Directory>X-GNOME-Sundry.directory</Directory>
275 <Include>
276 <Filename>alacarte.desktop</Filename>
277 <Filename>caribou.desktop</Filename>
278 <Filename>dconf-editor.desktop</Filename>
279 <Filename>fedora-im-chooser.desktop</Filename>
280 <Filename>fedora-release-notes.desktop</Filename>
281 <Filename>firewall-config.desktop</Filename>
282 <Filename>flash-player-properties.desktop</Filename>
283 <Filename>gconf-editor.desktop</Filename>
284 <Filename>gnome-abrt.desktop</Filename>
285 <Filename>fedora-abrt.desktop</Filename>
286 <Filename>gnome-orca.desktop</Filename>
287 <Filename>gnome-power-statistics.desktop</Filename>
288 <Filename>gnome-user-share-properties.desktop</Filename>
289 <Filename>ibus.desktop</Filename>
290 <Filename>ibus-daemon.desktop</Filename>
291 <Filename>ibus-setup-anthy.desktop</Filename>
292 <Filename>ibus-setup.desktop</Filename>
293 <Filename>ibus-setup-hangul.desktop</Filename>
294 <Filename>ibus-setup-libbopomofo.desktop</Filename>
295 <Filename>ibus-setup-libpinyin.desktop</Filename>
296 <Filename>ibus-setup-m17n.desktop</Filename>
297 <Filename>ibus-setup-typing-booster.desktop</Filename>
298 <Filename>im-chooser.desktop</Filename>
299 <Filename>itweb-settings.desktop</Filename>
300 <Filename>jhbuild.desktop</Filename>
301 <Filename>javaws.desktop</Filename>
302 <Filename>java-1.7.0-openjdk-jconsole.desktop</Filename>
303 <Filename>java-1.7.0-openjdk-policytool.desktop</Filename>
304 <Filename>log4j-chainsaw.desktop</Filename>
305 <Filename>log4j-logfactor5.desktop</Filename>
306 <Filename>nm-connection-editor.desktop</Filename>
307 <Filename>orca.desktop</Filename>
308 <Filename>setroubleshoot.desktop</Filename>
309 <Filename>authconfig.desktop</Filename>
310 <Filename>system-config-date.desktop</Filename>
311 <Filename>system-config-firewall.desktop</Filename>
312 <Filename>system-config-keyboard.desktop</Filename>
313 <Filename>system-config-language.desktop</Filename>
314 <Filename>system-config-printer.desktop</Filename>
315 <Filename>system-config-users.desktop</Filename>
316 <Filename>vino-preferences.desktop</Filename>
317 </Include>
318 </Menu>
319
320 <!-- System Tools-->
321 <Menu>
322 <Name>System</Name>
323 <OnlyUnallocated/>
324 <Directory>System-Tools.directory</Directory>
325 <Include>
326 <And>
327 <Category>System</Category>
328 <Not><Category>Settings</Category></Not>
329 <Not><Category>Game</Category></Not>
330 <Not><Filename>baobab.desktop</Filename></Not>
331 <Not><Filename>gnome-system-log.desktop</Filename></Not>
332 <Not><Filename>gnome-system-monitor.desktop</Filename></Not>
333 </And>
334 </Include>
335 <Menu>
336 <Name>Preferences</Name>
337 <Directory>Settings.directory</Directory>
338 <Include>
339 <And>
340 <Category>Settings</Category>
341 <Not>
342 <Or>
343 <Category>System</Category>
344 <Category>X-GNOME-Settings-Panel</Category>
345 <Filename>alacarte.desktop</Filename>
346 <Filename>caribou.desktop</Filename>
347 <Filename>dconf-editor.desktop</Filename>
348 <Filename>fedora-im-chooser.desktop</Filename>
349 <Filename>fedora-release-notes.desktop</Filename>
350 <Filename>firewall-config.desktop</Filename>
351 <Filename>flash-player-properties.desktop</Filename>
352 <Filename>gconf-editor.desktop</Filename>
353 <Filename>gnome-abrt.desktop</Filename>
354 <Filename>fedora-abrt.desktop</Filename>
355 <Filename>gnome-orca.desktop</Filename>
356 <Filename>gnome-power-statistics.desktop</Filename>
357 <Filename>gnome-user-share-properties.desktop</Filename>
358 <Filename>ibus.desktop</Filename>
359 <Filename>ibus-daemon.desktop</Filename>
360 <Filename>ibus-setup-anthy.desktop</Filename>
361 <Filename>ibus-setup.desktop</Filename>
362 <Filename>ibus-setup-hangul.desktop</Filename>
363 <Filename>ibus-setup-libbopomofo.desktop</Filename>
364 <Filename>ibus-setup-libpinyin.desktop</Filename>
365 <Filename>ibus-setup-m17n.desktop</Filename>
366 <Filename>ibus-setup-typing-booster.desktop</Filename>
367 <Filename>im-chooser.desktop</Filename>
368 <Filename>itweb-settings.desktop</Filename>
369 <Filename>jhbuild.desktop</Filename>
370 <Filename>javaws.desktop</Filename>
371 <Filename>java-1.7.0-openjdk-jconsole.desktop</Filename>
372 <Filename>java-1.7.0-openjdk-policytool.desktop</Filename>
373 <Filename>log4j-chainsaw.desktop</Filename>
374 <Filename>log4j-logfactor5.desktop</Filename>
375 <Filename>nm-connection-editor.desktop</Filename>
376 <Filename>orca.desktop</Filename>
377 <Filename>setroubleshoot.desktop</Filename>
378 <Filename>authconfig.desktop</Filename>
379 <Filename>system-config-date.desktop</Filename>
380 <Filename>system-config-firewall.desktop</Filename>
381 <Filename>system-config-keyboard.desktop</Filename>
382 <Filename>system-config-language.desktop</Filename>
383 <Filename>system-config-printer.desktop</Filename>
384 <Filename>system-config-users.desktop</Filename>
385 <Filename>vino-preferences.desktop</Filename>
386 </Or>
387 </Not>
388 </And>
389 </Include>
390 </Menu>
391 <Menu>
392 <Name>Administration</Name>
393 <Directory>Settings-System.directory</Directory>
394 <Include>
395 <And>
396 <Category>Settings</Category>
397 <Category>System</Category>
398 <Not>
399 <Or>
400 <Category>X-GNOME-Settings-Panel</Category>
401 <Filename>alacarte.desktop</Filename>
402 <Filename>caribou.desktop</Filename>
403 <Filename>dconf-editor.desktop</Filename>
404 <Filename>fedora-im-chooser.desktop</Filename>
405 <Filename>fedora-release-notes.desktop</Filename>
406 <Filename>firewall-config.desktop</Filename>
407 <Filename>flash-player-properties.desktop</Filename>
408 <Filename>gconf-editor.desktop</Filename>
409 <Filename>gnome-abrt.desktop</Filename>
410 <Filename>fedora-abrt.desktop</Filename>
411 <Filename>gnome-orca.desktop</Filename>
412 <Filename>gnome-power-statistics.desktop</Filename>
413 <Filename>gnome-user-share-properties.desktop</Filename>
414 <Filename>ibus.desktop</Filename>
415 <Filename>ibus-daemon.desktop</Filename>
416 <Filename>ibus-setup-anthy.desktop</Filename>
417 <Filename>ibus-setup.desktop</Filename>
418 <Filename>ibus-setup-hangul.desktop</Filename>
419 <Filename>ibus-setup-libbopomofo.desktop</Filename>
420 <Filename>ibus-setup-libpinyin.desktop</Filename>
421 <Filename>ibus-setup-m17n.desktop</Filename>
422 <Filename>ibus-setup-typing-booster.desktop</Filename>
423 <Filename>im-chooser.desktop</Filename>
424 <Filename>itweb-settings.desktop</Filename>
425 <Filename>jhbuild.desktop</Filename>
426 <Filename>javaws.desktop</Filename>
427 <Filename>java-1.7.0-openjdk-jconsole.desktop</Filename>
428 <Filename>java-1.7.0-openjdk-policytool.desktop</Filename>
429 <Filename>log4j-chainsaw.desktop</Filename>
430 <Filename>log4j-logfactor5.desktop</Filename>
431 <Filename>nm-connection-editor.desktop</Filename>
432 <Filename>orca.desktop</Filename>
433 <Filename>setroubleshoot.desktop</Filename>
434 <Filename>authconfig.desktop</Filename>
435 <Filename>system-config-date.desktop</Filename>
436 <Filename>system-config-firewall.desktop</Filename>
437 <Filename>system-config-keyboard.desktop</Filename>
438 <Filename>system-config-language.desktop</Filename>
439 <Filename>system-config-printer.desktop</Filename>
440 <Filename>system-config-users.desktop</Filename>
441 <Filename>vino-preferences.desktop</Filename>
442 </Or>
443 </Not>
444 </And>
445 </Include>
446 </Menu>
447 </Menu> <!-- End System Tools -->
448
449 <!-- System Settings -->
450 <Menu>
451 <Name>System Settings</Name>
452 <Directory>X-GNOME-SystemSettings.directory</Directory>
453 <Include>
454 <Category>X-GNOME-Settings-Panel</Category>
455 </Include>
456 </Menu>
457
458 <!-- Utilities submenu -->
459 <Menu>
460 <Name>Utilities</Name>
461 <Directory>X-GNOME-Utilities.directory</Directory>
462 <Include>
463 <Filename>file-roller.desktop</Filename>
464 <Filename>gnome-calculator.desktop</Filename>
465 <Filename>gnome-font-viewer.desktop</Filename>
466 <Filename>gucharmap.desktop</Filename>
467 <Filename>seahorse.desktop</Filename>
468 <Filename>gnome-terminal.desktop</Filename>
469 <Filename>deja-dup-preferences.desktop</Filename>
470 <Filename>gnome-dictionary.desktop</Filename>
471 <Filename>evince.desktop</Filename>
472 <Filename>eog.desktop</Filename>
473 <Filename>baobab.desktop</Filename>
474 <Filename>gnome-system-log.desktop</Filename>
475 <Filename>gnome-system-monitor.desktop</Filename>
476 <Filename>vinagre.desktop</Filename>
477 <Filename>gnome-tweak-tool.desktop</Filename>
478 <Filename>gnome-disks.desktop</Filename>
479 <Filename>gnome-screenshot.desktop</Filename>
480 <Filename>gnome-yelp.desktop</Filename>
481 <Filename>yelp.desktop</Filename>
482 <Filename>gnome-control-center.desktop</Filename>
483 </Include>
484 </Menu>
485
486 <!-- Other -->
487 <Menu>
488 <Name>Other</Name>
489 <Directory>X-GNOME-Other.directory</Directory>
490 <OnlyUnallocated/>
491 <Include>
492 <And>
493 <Not><Category>Core</Category></Not>
494 <Not><Category>Screensaver</Category></Not>
495
496 <!-- Really Fedora ??? -->
497 <Not><Filename>gnome-eog.desktop</Filename></Not>
498 <Not><Filename>gnome-file-roller.desktop</Filename></Not>
499 <Not><Filename>gnome-gucharmap.desktop</Filename></Not>
500 <Not><Filename>gcalctool.desktop</Filename></Not>
501 </And>
502 </Include>
503 </Menu> <!-- End Other -->
504
505 <Layout>
506 <Merge type="menus" />
507 <Menuname>Other</Menuname>
508 <Merge type="files" />
509 </Layout>
510
511 <Include>
512 <Filename>ubuntu-software-center.desktop</Filename>
513 </Include>
514
515 <!-- Separator between menus and gnome-app-install -->
516 <Layout>
517 <Merge type="menus"/>
518 <Merge type="files"/>
519 <Separator/>
520 <Filename>ubuntu-software-center.desktop</Filename>
521 </Layout>
522
523 </Menu> <!-- End Applications -->
0 [Desktop Entry]
1 Name=System Settings
2 Icon=gnome-settings
3 Type=Directory
4 NoDisplay=true
0 # List of source files containing translatable strings.
1 # Please keep this file sorted alphabetically.
2 desktop-directories/AudioVideo.directory.in
3 desktop-directories/Development.directory.in
4 desktop-directories/Education.directory.in
5 desktop-directories/Game.directory.in
6 desktop-directories/Graphics.directory.in
7 desktop-directories/Network.directory.in
8 desktop-directories/Office.directory.in
9 desktop-directories/System-Tools.directory.in
10 desktop-directories/Utility-Accessibility.directory.in
11 desktop-directories/Utility.directory.in
12 desktop-directories/X-GNOME-Menu-Applications.directory.in
13 desktop-directories/X-GNOME-Other.directory.in
14 desktop-directories/X-GNOME-Sundry.directory.in
15 desktop-directories/X-GNOME-Utilities.directory.in
16 desktop-directories/X-GNOME-WebApplications.directory.in
0 01_default_prefix.patch
1 02_kill_debian_menu.patch
2 03_kde-legacydirs.patch
3 08_settings-menus.patch
4 09_app_install_entry.patch
5 09_games-menu.patch
6 11_science-menu.patch
7 50_add-gcc-apps.patch
8 70_ubuntu-directories.patch
9 git_restore_calculator.patch
10 ubuntu_gcc_translations.patch
0 <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN"
1 "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd">
2
3 <Menu>
4
5 <Name>Applications</Name>
6 <Directory>X-GNOME-Menu-Applications.directory</Directory>
7
8 <!-- Scan legacy dirs first, as later items take priority -->
9 <LegacyDir>/etc/X11/applnk</LegacyDir>
10 <LegacyDir>/usr/share/gnome/apps</LegacyDir>
11
12 <!-- Read standard .directory and .desktop file locations -->
13 <DefaultAppDirs/>
14 <DefaultDirectoryDirs/>
15
16 <!-- Read in overrides and child menus from applications-merged/ -->
17 <DefaultMergeDirs/>
18
19 <!-- Accessories submenu -->
20 <Menu>
21 <Name>Accessories</Name>
22 <OnlyUnallocated/>
23 <Directory>Utility.directory</Directory>
24 <Include>
25 <And>
26 <Category>Utility</Category>
27 <!-- Accessibility spec must have either the Utility or Settings
28 category, and we display an accessibility submenu already for
29 the ones that do not have Settings, so don't display accessibility
30 applications here -->
31 <Not><Category>Accessibility</Category></Not>
32 <Not><Category>System</Category></Not>
33
34 <!-- Also exclude everything we put in the X-GNOME-Utilities
35 whitelist -->
36 <Not><Filename>file-roller.desktop</Filename></Not>
37 <Not><Filename>gnome-file-roller.desktop</Filename></Not>
38 <Not><Filename>deja-dup-preferences.desktop</Filename></Not>
39 <Not><Filename>gnome-calculator.desktop</Filename></Not>
40 <Not><Filename>gcalctool.desktop</Filename></Not>
41 <Not><Filename>gucharmap.desktop</Filename></Not>
42 <Not><Filename>gnome-gucharmap.desktop</Filename></Not>
43 <Not><Filename>gnome-font-viewer.desktop</Filename></Not>
44 <Not><Filename>seahorse.desktop</Filename></Not>
45 <Not><Filename>gnome-terminal.desktop</Filename></Not>
46 <Not><Filename>gnome-tweak-tool.desktop</Filename></Not>
47 <Not><Filename>gnome-disks.desktop</Filename></Not>
48 <Not><Filename>gnome-screenshot.desktop</Filename></Not>
49 <Not><Filename>gnome-yelp.desktop</Filename></Not>
50 <Not><Filename>yelp.desktop</Filename></Not>
51 <Not><Filename>gnome-control-center.desktop</Filename></Not>
52 </And>
53 </Include>
54 </Menu> <!-- End Accessories -->
55
56
57 <!-- Accessibility submenu -->
58 <Menu>
59 <Name>Universal Access</Name>
60 <OnlyUnallocated/>
61 <Directory>Utility-Accessibility.directory</Directory>
62 <Include>
63 <And>
64 <Category>Accessibility</Category>
65 <Not><Category>Settings</Category></Not>
66 </And>
67 </Include>
68 </Menu> <!-- End Accessibility -->
69
70 <!-- Development Tools -->
71 <Menu>
72 <Name>Development</Name>
73 <OnlyUnallocated/>
74 <Directory>Development.directory</Directory>
75 <Include>
76 <And>
77 <Category>Development</Category>
78 </And>
79 <Filename>emacs.desktop</Filename>
80 </Include>
81 </Menu> <!-- End Development Tools -->
82
83 <!-- Education -->
84 <Menu>
85 <Name>Education</Name>
86 <Directory>Education.directory</Directory>
87 <Include>
88 <And>
89 <Category>Education</Category>
90 <Not><Category>Science</Category></Not>
91 </And>
92 </Include>
93 </Menu> <!-- End Education -->
94
95 <!-- Science -->
96 <Menu>
97 <Name>Science</Name>
98 <Directory>GnomeScience.directory</Directory>
99 <Include>
100 <And>
101 <Category>Education</Category>
102 <Category>Science</Category>
103 </And>
104 </Include>
105 </Menu> <!-- End Science -->
106
107 <!-- Games -->
108 <Menu>
109 <Name>Games</Name>
110 <Directory>Game.directory</Directory>
111 <Include>
112 <And>
113 <Category>Game</Category>
114 <Not><Category>ActionGame</Category></Not>
115 <Not><Category>AdventureGame</Category></Not>
116 <Not><Category>ArcadeGame</Category></Not>
117 <Not><Category>BoardGame</Category></Not>
118 <Not><Category>BlocksGame</Category></Not>
119 <Not><Category>CardGame</Category></Not>
120 <Not><Category>KidsGame</Category></Not>
121 <Not><Category>LogicGame</Category></Not>
122 <Not><Category>Simulation</Category></Not>
123 <Not><Category>SportsGame</Category></Not>
124 <Not><Category>StrategyGame</Category></Not>
125 </And>
126 </Include>
127 <DefaultLayout inline="true" inline_limit="6" inline_header="false">
128 <Merge type="menus"/>
129 <Merge type="files"/>
130 </DefaultLayout>
131 <Menu>
132 <Name>Action</Name>
133 <Directory>ActionGames.directory</Directory>
134 <Include>
135 <Category>ActionGame</Category>
136 </Include>
137 </Menu>
138 <Menu>
139 <Name>Adventure</Name>
140 <Directory>AdventureGames.directory</Directory>
141 <Include>
142 <Category>AdventureGame</Category>
143 </Include>
144 </Menu>
145 <Menu>
146 <Name>Arcade</Name>
147 <Directory>ArcadeGames.directory</Directory>
148 <Include>
149 <Category>ArcadeGame</Category>
150 </Include>
151 </Menu>
152 <Menu>
153 <Name>Board</Name>
154 <Directory>BoardGames.directory</Directory>
155 <Include>
156 <Category>BoardGame</Category>
157 </Include>
158 </Menu>
159 <Menu>
160 <Name>Blocks</Name>
161 <Directory>BlocksGames.directory</Directory>
162 <Include>
163 <Category>BlocksGame</Category>
164 </Include>
165 </Menu>
166 <Menu>
167 <Name>Cards</Name>
168 <Directory>CardGames.directory</Directory>
169 <Include>
170 <Category>CardGame</Category>
171 </Include>
172 </Menu>
173 <Menu>
174 <Name>Kids</Name>
175 <Directory>KidsGames.directory</Directory>
176 <Include>
177 <Category>KidsGame</Category>
178 </Include>
179 </Menu>
180 <Menu>
181 <Name>Logic</Name>
182 <Directory>LogicGames.directory</Directory>
183 <Include>
184 <Category>LogicGame</Category>
185 </Include>
186 </Menu>
187 <Menu>
188 <Name>Role Playing</Name>
189 <Directory>RolePlayingGames.directory</Directory>
190 <Include>
191 <Category>RolePlaying</Category>
192 </Include>
193 </Menu>
194 <Menu>
195 <Name>Simulation</Name>
196 <Directory>SimulationGames.directory</Directory>
197 <Include>
198 <Category>Simulation</Category>
199 </Include>
200 </Menu>
201 <Menu>
202 <Name>Sports</Name>
203 <Directory>SportsGames.directory</Directory>
204 <Include>
205 <Category>SportsGame</Category>
206 </Include>
207 </Menu>
208 <Menu>
209 <Name>Strategy</Name>
210 <Directory>StrategyGames.directory</Directory>
211 <Include>
212 <Category>StrategyGame</Category>
213 </Include>
214 </Menu>
215 </Menu> <!-- End Games -->
216
217 <!-- Graphics -->
218 <Menu>
219 <Name>Graphics</Name>
220 <OnlyUnallocated/>
221 <Directory>Graphics.directory</Directory>
222 <Include>
223 <And>
224 <Category>Graphics</Category>
225 <Not><Filename>eog.desktop</Filename></Not>
226 <Not><Filename>gnome-eog.desktop</Filename></Not>
227 <Not><Filename>evince.desktop</Filename></Not>
228 </And>
229 </Include>
230 </Menu> <!-- End Graphics -->
231
232 <!-- Internet -->
233 <Menu>
234 <Name>Internet</Name>
235 <OnlyUnallocated/>
236 <Directory>Network.directory</Directory>
237 <Include>
238 <And>
239 <Category>Network</Category>
240 <Not><Category>X-GNOME-WebApplication</Category></Not>
241 <Not><Filename>vinagre.desktop</Filename></Not>
242 </And>
243 </Include>
244 </Menu> <!-- End Internet -->
245
246 <!-- Web Applications -->
247 <Menu>
248 <Name>Web Applications</Name>
249 <Directory>X-GNOME-WebApplications.directory</Directory>
250 <Include>
251 <And>
252 <Category>Network</Category>
253 <Category>X-GNOME-WebApplication</Category>
254 </And>
255 </Include>
256 </Menu>
257
258 <!-- Multimedia -->
259 <Menu>
260 <Name>Multimedia</Name>
261 <OnlyUnallocated/>
262 <Directory>AudioVideo.directory</Directory>
263 <Include>
264 <And>
265 <Category>AudioVideo</Category>
266 </And>
267 </Include>
268 </Menu> <!-- End Multimedia -->
269
270 <!-- Office -->
271 <Menu>
272 <Name>Office</Name>
273 <OnlyUnallocated/>
274 <Directory>Office.directory</Directory>
275 <Include>
276 <And>
277 <Category>Office</Category>
278 <Not><Filename>evince.desktop</Filename></Not>
279 <Not><Filename>gnome-dictionary.desktop</Filename></Not>
280 </And>
281 </Include>
282 </Menu> <!-- End Office -->
283
284 <!-- Sundry -->
285 <Menu>
286 <Name>Sundry</Name>
287 <Directory>X-GNOME-Sundry.directory</Directory>
288 <Include>
289 <Filename>alacarte.desktop</Filename>
290 <Filename>caribou.desktop</Filename>
291 <Filename>dconf-editor.desktop</Filename>
292 <Filename>fedora-im-chooser.desktop</Filename>
293 <Filename>fedora-release-notes.desktop</Filename>
294 <Filename>firewall-config.desktop</Filename>
295 <Filename>flash-player-properties.desktop</Filename>
296 <Filename>gconf-editor.desktop</Filename>
297 <Filename>gnome-abrt.desktop</Filename>
298 <Filename>fedora-abrt.desktop</Filename>
299 <Filename>gnome-orca.desktop</Filename>
300 <Filename>gnome-power-statistics.desktop</Filename>
301 <Filename>gnome-user-share-properties.desktop</Filename>
302 <Filename>ibus.desktop</Filename>
303 <Filename>ibus-daemon.desktop</Filename>
304 <Filename>ibus-setup-anthy.desktop</Filename>
305 <Filename>ibus-setup.desktop</Filename>
306 <Filename>ibus-setup-hangul.desktop</Filename>
307 <Filename>ibus-setup-libbopomofo.desktop</Filename>
308 <Filename>ibus-setup-libpinyin.desktop</Filename>
309 <Filename>ibus-setup-m17n.desktop</Filename>
310 <Filename>ibus-setup-typing-booster.desktop</Filename>
311 <Filename>im-chooser.desktop</Filename>
312 <Filename>itweb-settings.desktop</Filename>
313 <Filename>jhbuild.desktop</Filename>
314 <Filename>javaws.desktop</Filename>
315 <Filename>java-1.7.0-openjdk-jconsole.desktop</Filename>
316 <Filename>java-1.7.0-openjdk-policytool.desktop</Filename>
317 <Filename>log4j-chainsaw.desktop</Filename>
318 <Filename>log4j-logfactor5.desktop</Filename>
319 <Filename>nm-connection-editor.desktop</Filename>
320 <Filename>orca.desktop</Filename>
321 <Filename>setroubleshoot.desktop</Filename>
322 <Filename>authconfig.desktop</Filename>
323 <Filename>system-config-date.desktop</Filename>
324 <Filename>system-config-firewall.desktop</Filename>
325 <Filename>system-config-keyboard.desktop</Filename>
326 <Filename>system-config-language.desktop</Filename>
327 <Filename>system-config-printer.desktop</Filename>
328 <Filename>system-config-users.desktop</Filename>
329 <Filename>vino-preferences.desktop</Filename>
330 </Include>
331 </Menu>
332
333 <!-- System Tools-->
334 <Menu>
335 <Name>System</Name>
336 <OnlyUnallocated/>
337 <Directory>System-Tools.directory</Directory>
338 <Include>
339 <And>
340 <Category>System</Category>
341 <Not><Category>Settings</Category></Not>
342 <Not><Category>Game</Category></Not>
343 <Not><Filename>baobab.desktop</Filename></Not>
344 <Not><Filename>gnome-system-log.desktop</Filename></Not>
345 <Not><Filename>gnome-system-monitor.desktop</Filename></Not>
346 </And>
347 </Include>
348 <Menu>
349 <Name>Preferences</Name>
350 <Directory>Settings.directory</Directory>
351 <Include>
352 <And>
353 <Category>Settings</Category>
354 <Not>
355 <Or>
356 <Category>System</Category>
357 <Category>X-GNOME-Settings-Panel</Category>
358 <Filename>alacarte.desktop</Filename>
359 <Filename>caribou.desktop</Filename>
360 <Filename>dconf-editor.desktop</Filename>
361 <Filename>fedora-im-chooser.desktop</Filename>
362 <Filename>fedora-release-notes.desktop</Filename>
363 <Filename>firewall-config.desktop</Filename>
364 <Filename>flash-player-properties.desktop</Filename>
365 <Filename>gconf-editor.desktop</Filename>
366 <Filename>gnome-abrt.desktop</Filename>
367 <Filename>fedora-abrt.desktop</Filename>
368 <Filename>gnome-orca.desktop</Filename>
369 <Filename>gnome-power-statistics.desktop</Filename>
370 <Filename>gnome-user-share-properties.desktop</Filename>
371 <Filename>ibus.desktop</Filename>
372 <Filename>ibus-daemon.desktop</Filename>
373 <Filename>ibus-setup-anthy.desktop</Filename>
374 <Filename>ibus-setup.desktop</Filename>
375 <Filename>ibus-setup-hangul.desktop</Filename>
376 <Filename>ibus-setup-libbopomofo.desktop</Filename>
377 <Filename>ibus-setup-libpinyin.desktop</Filename>
378 <Filename>ibus-setup-m17n.desktop</Filename>
379 <Filename>ibus-setup-typing-booster.desktop</Filename>
380 <Filename>im-chooser.desktop</Filename>
381 <Filename>itweb-settings.desktop</Filename>
382 <Filename>jhbuild.desktop</Filename>
383 <Filename>javaws.desktop</Filename>
384 <Filename>java-1.7.0-openjdk-jconsole.desktop</Filename>
385 <Filename>java-1.7.0-openjdk-policytool.desktop</Filename>
386 <Filename>log4j-chainsaw.desktop</Filename>
387 <Filename>log4j-logfactor5.desktop</Filename>
388 <Filename>nm-connection-editor.desktop</Filename>
389 <Filename>orca.desktop</Filename>
390 <Filename>setroubleshoot.desktop</Filename>
391 <Filename>authconfig.desktop</Filename>
392 <Filename>system-config-date.desktop</Filename>
393 <Filename>system-config-firewall.desktop</Filename>
394 <Filename>system-config-keyboard.desktop</Filename>
395 <Filename>system-config-language.desktop</Filename>
396 <Filename>system-config-printer.desktop</Filename>
397 <Filename>system-config-users.desktop</Filename>
398 <Filename>vino-preferences.desktop</Filename>
399 </Or>
400 </Not>
401 </And>
402 </Include>
403 </Menu>
404 <Menu>
405 <Name>Administration</Name>
406 <Directory>Settings-System.directory</Directory>
407 <Include>
408 <And>
409 <Category>Settings</Category>
410 <Category>System</Category>
411 <Not>
412 <Or>
413 <Category>X-GNOME-Settings-Panel</Category>
414 <Filename>alacarte.desktop</Filename>
415 <Filename>caribou.desktop</Filename>
416 <Filename>dconf-editor.desktop</Filename>
417 <Filename>fedora-im-chooser.desktop</Filename>
418 <Filename>fedora-release-notes.desktop</Filename>
419 <Filename>firewall-config.desktop</Filename>
420 <Filename>flash-player-properties.desktop</Filename>
421 <Filename>gconf-editor.desktop</Filename>
422 <Filename>gnome-abrt.desktop</Filename>
423 <Filename>fedora-abrt.desktop</Filename>
424 <Filename>gnome-orca.desktop</Filename>
425 <Filename>gnome-power-statistics.desktop</Filename>
426 <Filename>gnome-user-share-properties.desktop</Filename>
427 <Filename>ibus.desktop</Filename>
428 <Filename>ibus-daemon.desktop</Filename>
429 <Filename>ibus-setup-anthy.desktop</Filename>
430 <Filename>ibus-setup.desktop</Filename>
431 <Filename>ibus-setup-hangul.desktop</Filename>
432 <Filename>ibus-setup-libbopomofo.desktop</Filename>
433 <Filename>ibus-setup-libpinyin.desktop</Filename>
434 <Filename>ibus-setup-m17n.desktop</Filename>
435 <Filename>ibus-setup-typing-booster.desktop</Filename>
436 <Filename>im-chooser.desktop</Filename>
437 <Filename>itweb-settings.desktop</Filename>
438 <Filename>jhbuild.desktop</Filename>
439 <Filename>javaws.desktop</Filename>
440 <Filename>java-1.7.0-openjdk-jconsole.desktop</Filename>
441 <Filename>java-1.7.0-openjdk-policytool.desktop</Filename>
442 <Filename>log4j-chainsaw.desktop</Filename>
443 <Filename>log4j-logfactor5.desktop</Filename>
444 <Filename>nm-connection-editor.desktop</Filename>
445 <Filename>orca.desktop</Filename>
446 <Filename>setroubleshoot.desktop</Filename>
447 <Filename>authconfig.desktop</Filename>
448 <Filename>system-config-date.desktop</Filename>
449 <Filename>system-config-firewall.desktop</Filename>
450 <Filename>system-config-keyboard.desktop</Filename>
451 <Filename>system-config-language.desktop</Filename>
452 <Filename>system-config-printer.desktop</Filename>
453 <Filename>system-config-users.desktop</Filename>
454 <Filename>vino-preferences.desktop</Filename>
455 </Or>
456 </Not>
457 </And>
458 </Include>
459 </Menu>
460 </Menu> <!-- End System Tools -->
461
462 <!-- System Settings -->
463 <Menu>
464 <Name>System Settings</Name>
465 <Directory>X-GNOME-SystemSettings.directory</Directory>
466 <Include>
467 <Category>X-GNOME-Settings-Panel</Category>
468 </Include>
469 </Menu>
470
471 <!-- Utilities submenu -->
472 <Menu>
473 <Name>Utilities</Name>
474 <Directory>X-GNOME-Utilities.directory</Directory>
475 <Include>
476 <Filename>file-roller.desktop</Filename>
477 <Filename>gnome-calculator.desktop</Filename>
478 <Filename>gnome-font-viewer.desktop</Filename>
479 <Filename>gucharmap.desktop</Filename>
480 <Filename>seahorse.desktop</Filename>
481 <Filename>gnome-terminal.desktop</Filename>
482 <Filename>deja-dup-preferences.desktop</Filename>
483 <Filename>gnome-dictionary.desktop</Filename>
484 <Filename>evince.desktop</Filename>
485 <Filename>eog.desktop</Filename>
486 <Filename>baobab.desktop</Filename>
487 <Filename>gnome-system-log.desktop</Filename>
488 <Filename>gnome-system-monitor.desktop</Filename>
489 <Filename>vinagre.desktop</Filename>
490 <Filename>gnome-tweak-tool.desktop</Filename>
491 <Filename>gnome-disks.desktop</Filename>
492 <Filename>gnome-screenshot.desktop</Filename>
493 <Filename>gnome-yelp.desktop</Filename>
494 <Filename>yelp.desktop</Filename>
495 <Filename>gnome-control-center.desktop</Filename>
496 </Include>
497 </Menu>
498
499 <!-- Other -->
500 <Menu>
501 <Name>Other</Name>
502 <Directory>X-GNOME-Other.directory</Directory>
503 <OnlyUnallocated/>
504 <Include>
505 <And>
506 <Not><Category>Core</Category></Not>
507 <Not><Category>Screensaver</Category></Not>
508
509 <!-- Really Fedora ??? -->
510 <Not><Filename>gnome-eog.desktop</Filename></Not>
511 <Not><Filename>gnome-file-roller.desktop</Filename></Not>
512 <Not><Filename>gnome-gucharmap.desktop</Filename></Not>
513 <Not><Filename>gcalctool.desktop</Filename></Not>
514 </And>
515 </Include>
516 </Menu> <!-- End Other -->
517
518 <Layout>
519 <Merge type="menus" />
520 <Menuname>Other</Menuname>
521 <Merge type="files" />
522 </Layout>
523
524 <Include>
525 <Filename>ubuntu-software-center.desktop</Filename>
526 </Include>
527
528 <!-- Separator between menus and gnome-app-install -->
529 <Layout>
530 <Merge type="menus"/>
531 <Merge type="files"/>
532 <Separator/>
533 <Filename>ubuntu-software-center.desktop</Filename>
534 </Layout>
535
536 </Menu> <!-- End Applications -->
0 directorydir = $(datadir)/desktop-directories
1
2 directory_in_files = \
3 AudioVideo.directory.in \
4 Development.directory.in \
5 Education.directory.in \
6 Game.directory.in \
7 Graphics.directory.in \
8 Network.directory.in \
9 Office.directory.in \
10 System-Tools.directory.in \
11 Utility.directory.in \
12 Utility-Accessibility.directory.in \
13 X-GNOME-Other.directory.in \
14 X-GNOME-Menu-Applications.directory.in \
15 X-GNOME-Sundry.directory.in \
16 X-GNOME-Utilities.directory.in \
17 X-GNOME-WebApplications.directory.in \
18 X-GNOME-SystemSettings.directory.in
19
20 directory_DATA = $(directory_in_files:.directory.in=.directory)
21
22 @INTLTOOL_DIRECTORY_RULE@
23
24 EXTRA_DIST= $(directory_in_files)
25
26 DISTCLEANFILES = $(directory_DATA)
27
28 -include $(top_srcdir)/git.mk
0 # Makefile.in generated by automake 1.13.1 from Makefile.am.
1 # @configure_input@
2
3 # Copyright (C) 1994-2012 Free Software Foundation, Inc.
4
5 # This Makefile.in is free software; the Free Software Foundation
6 # gives unlimited permission to copy and/or distribute it,
7 # with or without modifications, as long as this notice is preserved.
8
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY, to the extent permitted by law; without
11 # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
12 # PARTICULAR PURPOSE.
13
14 @SET_MAKE@
15
16 VPATH = @srcdir@
17 am__make_dryrun = \
18 { \
19 am__dry=no; \
20 case $$MAKEFLAGS in \
21 *\\[\ \ ]*) \
22 echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
23 | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
24 *) \
25 for am__flg in $$MAKEFLAGS; do \
26 case $$am__flg in \
27 *=*|--*) ;; \
28 *n*) am__dry=yes; break;; \
29 esac; \
30 done;; \
31 esac; \
32 test $$am__dry = yes; \
33 }
34 pkgdatadir = $(datadir)/@PACKAGE@
35 pkgincludedir = $(includedir)/@PACKAGE@
36 pkglibdir = $(libdir)/@PACKAGE@
37 pkglibexecdir = $(libexecdir)/@PACKAGE@
38 am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
39 install_sh_DATA = $(install_sh) -c -m 644
40 install_sh_PROGRAM = $(install_sh) -c
41 install_sh_SCRIPT = $(install_sh) -c
42 INSTALL_HEADER = $(INSTALL_DATA)
43 transform = $(program_transform_name)
44 NORMAL_INSTALL = :
45 PRE_INSTALL = :
46 POST_INSTALL = :
47 NORMAL_UNINSTALL = :
48 PRE_UNINSTALL = :
49 POST_UNINSTALL = :
50 build_triplet = @build@
51 host_triplet = @host@
52 subdir = desktop-directories
53 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
54 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
55 am__aclocal_m4_deps = $(top_srcdir)/m4/intltool.m4 \
56 $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
57 $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
58 $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
59 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
60 $(ACLOCAL_M4)
61 mkinstalldirs = $(install_sh) -d
62 CONFIG_HEADER = $(top_builddir)/config.h
63 CONFIG_CLEAN_FILES =
64 CONFIG_CLEAN_VPATH_FILES =
65 AM_V_P = $(am__v_P_@AM_V@)
66 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
67 am__v_P_0 = false
68 am__v_P_1 = :
69 AM_V_GEN = $(am__v_GEN_@AM_V@)
70 am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
71 am__v_GEN_0 = @echo " GEN " $@;
72 am__v_GEN_1 =
73 AM_V_at = $(am__v_at_@AM_V@)
74 am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
75 am__v_at_0 = @
76 am__v_at_1 =
77 SOURCES =
78 DIST_SOURCES =
79 am__can_run_installinfo = \
80 case $$AM_UPDATE_INFO_DIR in \
81 n|no|NO) false;; \
82 *) (install-info --version) >/dev/null 2>&1;; \
83 esac
84 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
85 am__vpath_adj = case $$p in \
86 $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
87 *) f=$$p;; \
88 esac;
89 am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
90 am__install_max = 40
91 am__nobase_strip_setup = \
92 srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
93 am__nobase_strip = \
94 for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
95 am__nobase_list = $(am__nobase_strip_setup); \
96 for p in $$list; do echo "$$p $$p"; done | \
97 sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
98 $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
99 if (++n[$$2] == $(am__install_max)) \
100 { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
101 END { for (dir in files) print dir, files[dir] }'
102 am__base_list = \
103 sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
104 sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
105 am__uninstall_files_from_dir = { \
106 test -z "$$files" \
107 || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
108 || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
109 $(am__cd) "$$dir" && rm -f $$files; }; \
110 }
111 am__installdirs = "$(DESTDIR)$(directorydir)"
112 DATA = $(directory_DATA)
113 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
114 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
115 ACLOCAL = @ACLOCAL@
116 ALL_LINGUAS = @ALL_LINGUAS@
117 AMTAR = @AMTAR@
118 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
119 AR = @AR@
120 AS = @AS@
121 AUTOCONF = @AUTOCONF@
122 AUTOHEADER = @AUTOHEADER@
123 AUTOMAKE = @AUTOMAKE@
124 AWK = @AWK@
125 CATALOGS = @CATALOGS@
126 CATOBJEXT = @CATOBJEXT@
127 CC = @CC@
128 CCDEPMODE = @CCDEPMODE@
129 CFLAGS = @CFLAGS@
130 CPP = @CPP@
131 CPPFLAGS = @CPPFLAGS@
132 CYGPATH_W = @CYGPATH_W@
133 DATADIRNAME = @DATADIRNAME@
134 DEBUG_CFLAGS = @DEBUG_CFLAGS@
135 DEFS = @DEFS@
136 DEPDIR = @DEPDIR@
137 DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
138 DISABLE_DEPRECATED_CFLAGS = @DISABLE_DEPRECATED_CFLAGS@
139 DLLTOOL = @DLLTOOL@
140 DSYMUTIL = @DSYMUTIL@
141 DUMPBIN = @DUMPBIN@
142 ECHO_C = @ECHO_C@
143 ECHO_N = @ECHO_N@
144 ECHO_T = @ECHO_T@
145 EGREP = @EGREP@
146 EXEEXT = @EXEEXT@
147 FGREP = @FGREP@
148 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
149 GIO_UNIX_CFLAGS = @GIO_UNIX_CFLAGS@
150 GIO_UNIX_LIBS = @GIO_UNIX_LIBS@
151 GMOFILES = @GMOFILES@
152 GMSGFMT = @GMSGFMT@
153 GREP = @GREP@
154 INSTALL = @INSTALL@
155 INSTALL_DATA = @INSTALL_DATA@
156 INSTALL_PROGRAM = @INSTALL_PROGRAM@
157 INSTALL_SCRIPT = @INSTALL_SCRIPT@
158 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
159 INSTOBJEXT = @INSTOBJEXT@
160 INTLLIBS = @INTLLIBS@
161 INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
162 INTLTOOL_MERGE = @INTLTOOL_MERGE@
163 INTLTOOL_PERL = @INTLTOOL_PERL@
164 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
165 INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
166 INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
167 INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
168 INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
169 INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
170 INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
171 INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
172 INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
173 INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
174 INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
175 INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
176 INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
177 LD = @LD@
178 LDFLAGS = @LDFLAGS@
179 LIBOBJS = @LIBOBJS@
180 LIBS = @LIBS@
181 LIBTOOL = @LIBTOOL@
182 LIB_MENU_LT_VERSION = @LIB_MENU_LT_VERSION@
183 LIPO = @LIPO@
184 LN_S = @LN_S@
185 LTLIBOBJS = @LTLIBOBJS@
186 MAINT = @MAINT@
187 MAKEINFO = @MAKEINFO@
188 MANIFEST_TOOL = @MANIFEST_TOOL@
189 MKDIR_P = @MKDIR_P@
190 MKINSTALLDIRS = @MKINSTALLDIRS@
191 MSGFMT = @MSGFMT@
192 MSGFMT_OPTS = @MSGFMT_OPTS@
193 MSGMERGE = @MSGMERGE@
194 NM = @NM@
195 NMEDIT = @NMEDIT@
196 OBJDUMP = @OBJDUMP@
197 OBJEXT = @OBJEXT@
198 OTOOL = @OTOOL@
199 OTOOL64 = @OTOOL64@
200 PACKAGE = @PACKAGE@
201 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
202 PACKAGE_NAME = @PACKAGE_NAME@
203 PACKAGE_STRING = @PACKAGE_STRING@
204 PACKAGE_TARNAME = @PACKAGE_TARNAME@
205 PACKAGE_URL = @PACKAGE_URL@
206 PACKAGE_VERSION = @PACKAGE_VERSION@
207 PATH_SEPARATOR = @PATH_SEPARATOR@
208 PKG_CONFIG = @PKG_CONFIG@
209 PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
210 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
211 POFILES = @POFILES@
212 POSUB = @POSUB@
213 PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
214 PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
215 RANLIB = @RANLIB@
216 SED = @SED@
217 SET_MAKE = @SET_MAKE@
218 SHELL = @SHELL@
219 STRIP = @STRIP@
220 USE_NLS = @USE_NLS@
221 VERSION = @VERSION@
222 WARN_CFLAGS = @WARN_CFLAGS@
223 XGETTEXT = @XGETTEXT@
224 abs_builddir = @abs_builddir@
225 abs_srcdir = @abs_srcdir@
226 abs_top_builddir = @abs_top_builddir@
227 abs_top_srcdir = @abs_top_srcdir@
228 ac_ct_AR = @ac_ct_AR@
229 ac_ct_CC = @ac_ct_CC@
230 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
231 am__include = @am__include@
232 am__leading_dot = @am__leading_dot@
233 am__quote = @am__quote@
234 am__tar = @am__tar@
235 am__untar = @am__untar@
236 bindir = @bindir@
237 build = @build@
238 build_alias = @build_alias@
239 build_cpu = @build_cpu@
240 build_os = @build_os@
241 build_vendor = @build_vendor@
242 builddir = @builddir@
243 datadir = @datadir@
244 datarootdir = @datarootdir@
245 docdir = @docdir@
246 dvidir = @dvidir@
247 exec_prefix = @exec_prefix@
248 host = @host@
249 host_alias = @host_alias@
250 host_cpu = @host_cpu@
251 host_os = @host_os@
252 host_vendor = @host_vendor@
253 htmldir = @htmldir@
254 includedir = @includedir@
255 infodir = @infodir@
256 install_sh = @install_sh@
257 intltool__v_merge_options_ = @intltool__v_merge_options_@
258 intltool__v_merge_options_0 = @intltool__v_merge_options_0@
259 libdir = @libdir@
260 libexecdir = @libexecdir@
261 localedir = @localedir@
262 localstatedir = @localstatedir@
263 mandir = @mandir@
264 mkdir_p = @mkdir_p@
265 oldincludedir = @oldincludedir@
266 pdfdir = @pdfdir@
267 prefix = @prefix@
268 program_transform_name = @program_transform_name@
269 psdir = @psdir@
270 sbindir = @sbindir@
271 sharedstatedir = @sharedstatedir@
272 srcdir = @srcdir@
273 sysconfdir = @sysconfdir@
274 target_alias = @target_alias@
275 top_build_prefix = @top_build_prefix@
276 top_builddir = @top_builddir@
277 top_srcdir = @top_srcdir@
278 directorydir = $(datadir)/desktop-directories
279 directory_in_files = \
280 AudioVideo.directory.in \
281 Development.directory.in \
282 Education.directory.in \
283 Game.directory.in \
284 Graphics.directory.in \
285 Network.directory.in \
286 Office.directory.in \
287 System-Tools.directory.in \
288 Utility.directory.in \
289 Utility-Accessibility.directory.in \
290 X-GNOME-Other.directory.in \
291 X-GNOME-Menu-Applications.directory.in \
292 X-GNOME-Sundry.directory.in \
293 X-GNOME-Utilities.directory.in \
294 X-GNOME-WebApplications.directory.in \
295 X-GNOME-SystemSettings.directory.in
296
297 directory_DATA = $(directory_in_files:.directory.in=.directory)
298 EXTRA_DIST = $(directory_in_files)
299 DISTCLEANFILES = $(directory_DATA)
300 all: all-am
301
302 .SUFFIXES:
303 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
304 @for dep in $?; do \
305 case '$(am__configure_deps)' in \
306 *$$dep*) \
307 ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
308 && { if test -f $@; then exit 0; else break; fi; }; \
309 exit 1;; \
310 esac; \
311 done; \
312 echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign desktop-directories/Makefile'; \
313 $(am__cd) $(top_srcdir) && \
314 $(AUTOMAKE) --foreign desktop-directories/Makefile
315 .PRECIOUS: Makefile
316 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
317 @case '$?' in \
318 *config.status*) \
319 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
320 *) \
321 echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
322 cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
323 esac;
324
325 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
326 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
327
328 $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
329 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
330 $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
331 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
332 $(am__aclocal_m4_deps):
333
334 mostlyclean-libtool:
335 -rm -f *.lo
336
337 clean-libtool:
338 -rm -rf .libs _libs
339 install-directoryDATA: $(directory_DATA)
340 @$(NORMAL_INSTALL)
341 @list='$(directory_DATA)'; test -n "$(directorydir)" || list=; \
342 if test -n "$$list"; then \
343 echo " $(MKDIR_P) '$(DESTDIR)$(directorydir)'"; \
344 $(MKDIR_P) "$(DESTDIR)$(directorydir)" || exit 1; \
345 fi; \
346 for p in $$list; do \
347 if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
348 echo "$$d$$p"; \
349 done | $(am__base_list) | \
350 while read files; do \
351 echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(directorydir)'"; \
352 $(INSTALL_DATA) $$files "$(DESTDIR)$(directorydir)" || exit $$?; \
353 done
354
355 uninstall-directoryDATA:
356 @$(NORMAL_UNINSTALL)
357 @list='$(directory_DATA)'; test -n "$(directorydir)" || list=; \
358 files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
359 dir='$(DESTDIR)$(directorydir)'; $(am__uninstall_files_from_dir)
360 tags TAGS:
361
362 ctags CTAGS:
363
364 cscope cscopelist:
365
366
367 distdir: $(DISTFILES)
368 @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
369 topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
370 list='$(DISTFILES)'; \
371 dist_files=`for file in $$list; do echo $$file; done | \
372 sed -e "s|^$$srcdirstrip/||;t" \
373 -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
374 case $$dist_files in \
375 */*) $(MKDIR_P) `echo "$$dist_files" | \
376 sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
377 sort -u` ;; \
378 esac; \
379 for file in $$dist_files; do \
380 if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
381 if test -d $$d/$$file; then \
382 dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
383 if test -d "$(distdir)/$$file"; then \
384 find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
385 fi; \
386 if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
387 cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
388 find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
389 fi; \
390 cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
391 else \
392 test -f "$(distdir)/$$file" \
393 || cp -p $$d/$$file "$(distdir)/$$file" \
394 || exit 1; \
395 fi; \
396 done
397 check-am: all-am
398 check: check-am
399 all-am: Makefile $(DATA)
400 installdirs:
401 for dir in "$(DESTDIR)$(directorydir)"; do \
402 test -z "$$dir" || $(MKDIR_P) "$$dir"; \
403 done
404 install: install-am
405 install-exec: install-exec-am
406 install-data: install-data-am
407 uninstall: uninstall-am
408
409 install-am: all-am
410 @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
411
412 installcheck: installcheck-am
413 install-strip:
414 if test -z '$(STRIP)'; then \
415 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
416 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
417 install; \
418 else \
419 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
420 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
421 "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
422 fi
423 mostlyclean-generic:
424
425 clean-generic:
426
427 distclean-generic:
428 -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
429 -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
430 -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
431
432 maintainer-clean-generic:
433 @echo "This command is intended for maintainers to use"
434 @echo "it deletes files that may require special tools to rebuild."
435 clean: clean-am
436
437 clean-am: clean-generic clean-libtool mostlyclean-am
438
439 distclean: distclean-am
440 -rm -f Makefile
441 distclean-am: clean-am distclean-generic
442
443 dvi: dvi-am
444
445 dvi-am:
446
447 html: html-am
448
449 html-am:
450
451 info: info-am
452
453 info-am:
454
455 install-data-am: install-directoryDATA
456
457 install-dvi: install-dvi-am
458
459 install-dvi-am:
460
461 install-exec-am:
462
463 install-html: install-html-am
464
465 install-html-am:
466
467 install-info: install-info-am
468
469 install-info-am:
470
471 install-man:
472
473 install-pdf: install-pdf-am
474
475 install-pdf-am:
476
477 install-ps: install-ps-am
478
479 install-ps-am:
480
481 installcheck-am:
482
483 maintainer-clean: maintainer-clean-am
484 -rm -f Makefile
485 maintainer-clean-am: distclean-am maintainer-clean-generic
486
487 mostlyclean: mostlyclean-am
488
489 mostlyclean-am: mostlyclean-generic mostlyclean-libtool
490
491 pdf: pdf-am
492
493 pdf-am:
494
495 ps: ps-am
496
497 ps-am:
498
499 uninstall-am: uninstall-directoryDATA
500
501 .MAKE: install-am install-strip
502
503 .PHONY: all all-am check check-am clean clean-generic clean-libtool \
504 cscopelist-am ctags-am distclean distclean-generic \
505 distclean-libtool distdir dvi dvi-am html html-am info info-am \
506 install install-am install-data install-data-am \
507 install-directoryDATA install-dvi install-dvi-am install-exec \
508 install-exec-am install-html install-html-am install-info \
509 install-info-am install-man install-pdf install-pdf-am \
510 install-ps install-ps-am install-strip installcheck \
511 installcheck-am installdirs maintainer-clean \
512 maintainer-clean-generic mostlyclean mostlyclean-generic \
513 mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
514 uninstall-am uninstall-directoryDATA
515
516
517 @INTLTOOL_DIRECTORY_RULE@
518
519 -include $(top_srcdir)/git.mk
520
521 # Tell versions [3.59,3.63) of GNU make to not export all variables.
522 # Otherwise a system limit (for SysV at least) may be exceeded.
523 .NOEXPORT:
0 # List of source files containing translatable strings.
1 # Please keep this file sorted alphabetically.
2 desktop-directories/AudioVideo.directory.in
3 desktop-directories/Development.directory.in
4 desktop-directories/Education.directory.in
5 desktop-directories/Game.directory.in
6 desktop-directories/Graphics.directory.in
7 desktop-directories/Network.directory.in
8 desktop-directories/Office.directory.in
9 desktop-directories/System-Tools.directory.in
10 desktop-directories/Utility-Accessibility.directory.in
11 desktop-directories/Utility.directory.in
12 desktop-directories/X-GNOME-Menu-Applications.directory.in
13 desktop-directories/X-GNOME-Other.directory.in
14 desktop-directories/X-GNOME-Sundry.directory.in
15 desktop-directories/X-GNOME-Utilities.directory.in
16 desktop-directories/X-GNOME-WebApplications.directory.in
17 debian/desktop-files/ActionGames.directory.in
18 debian/desktop-files/AdventureGames.directory.in
19 debian/desktop-files/ArcadeGames.directory.in
20 debian/desktop-files/BlocksGames.directory.in
21 debian/desktop-files/BoardGames.directory.in
22 debian/desktop-files/CardGames.directory.in
23 debian/desktop-files/Debian.directory.in
24 debian/desktop-files/GnomeScience.directory.in
25 debian/desktop-files/KidsGames.directory.in
26 debian/desktop-files/LogicGames.directory.in
27 debian/desktop-files/RolePlayingGames.directory.in
28 debian/desktop-files/Settings-System.directory.in
29 debian/desktop-files/Settings.directory.in
30 debian/desktop-files/SimulationGames.directory.in
31 debian/desktop-files/SportsGames.directory.in
32 debian/desktop-files/StrategyGames.directory.in
00 AC_PREREQ(2.62)
11
2 AC_INIT([cinnamon-menus], [3.8.0])
2 AC_INIT([cinnamon-menus], [3.8.1])
33 AC_CONFIG_SRCDIR(libmenu/gmenu-tree.h)
44
55 m4_ifdef([AX_IS_RELEASE], [AX_IS_RELEASE([always])])
0 cinnamon-menus (3.8.1) tara; urgency=medium
1
2 [ Michael Webster ]
3 * Check for a valid GDesktopAppInfo before calling GDesktopAppInfo methods. Fix retry handling to only apply to new entries. Use g_timeout_add instead of g_idle_add for change signal accumulation.
4
5 -- Clement Lefebvre <root@linuxmint.com> Sun, 06 May 2018 14:38:48 +0100
6
7 cinnamon-menus (3.8.0) tara; urgency=medium
8
9 * Add CI configuration
10
11 -- Clement Lefebvre <root@linuxmint.com> Mon, 16 Apr 2018 12:17:38 +0100
12
13 cinnamon-menus (3.6.0) sylvia; urgency=medium
14
15 [ Jasper St. Pierre ]
16 * Revert "Memory leak fixes"
17 * Memory leak fixes
18 * entry-directories: Fix unref
19
20 [ Giovanni Campagna ]
21 * entry-directories: don't modify a list while iterating it
22 * entry-directories: protect event handling for directories
23
24 [ Florian Müllner ]
25 * libmenu: Remove support for legacy-dirs
26
27 [ Jasper St. Pierre ]
28 * entry-directories: Only log about invalidations if it was handled
29
30 -- Clement Lefebvre <root@linuxmint.com> Mon, 23 Oct 2017 13:20:27 +0100
31
32 cinnamon-menus (3.4.0) sonya; urgency=medium
33
34 [ leigh123linux ]
35 * remove autogenerated files and remove aclocal command from autogen
36
37 -- Clement Lefebvre <root@linuxmint.com> Wed, 03 May 2017 11:46:01 +0100
38
39 cinnamon-menus (3.2.0) serena; urgency=medium
40
41 [ Maximiliano Curia ]
42 * Migrate away from gnome-common deprecated vars and macros
43
44 [ Clement Lefebvre ]
45 * Fixed build
46
47 [ Maximiliano Curia ]
48 * Drop gtkdocize invocation
49 * Make AX_ macros optional
50
51 -- Clement Lefebvre <root@linuxmint.com> Mon, 07 Nov 2016 10:36:18 +0000
52
53 cinnamon-menus (3.0.2) sarah; urgency=medium
54
55 [ Michael Webster ]
56 * Fix a couple issues with incorrect result evaluations when loading desktop files caused by 44ee2de737e53b0
57 * Revert 44ee2de737e53b and go back to loading .desktop files *as* GDesktopAppInfo - this is the only way g_desktop_app_info_get_filename() will work properly.
58
59 -- Clement Lefebvre <root@linuxmint.com> Mon, 30 May 2016 15:45:57 +0100
60
61 cinnamon-menus (3.0.1) sarah; urgency=medium
62
63 [ Michael Webster ]
64 * entry-directories.c: Monitor mimeinfo.cache file and re-attempt failed .desktop files when it changes (which is usually just after the .desktop file is added, causing loading to fail due to unavailable GAppInfo). See inline comments.
65 * Follow-up to previous commit - retry only those desktop files that failed because of appinfo problems.
66 * desktop-entries.c: Refactor to eliminate double-loading of desktop file. Use g_key_file_load_from_file, followed by g_desktop_app_info_new_from_keyfile.
67
68 -- Clement Lefebvre <root@linuxmint.com> Mon, 23 May 2016 12:54:12 +0100
69
70 cinnamon-menus (3.0.0) sarah; urgency=medium
71
72 [ monsta ]
73 * configure.ac: drop obsolete macro
74
75 -- Clement Lefebvre <root@linuxmint.com> Sat, 23 Apr 2016 15:56:27 +0100
76
77 cinnamon-menus (2.8.0) rosa; urgency=medium
78
79 * 2.8.0
80
81 -- Clement Lefebvre <root@linuxmint.com> Fri, 16 Oct 2015 14:02:11 +0100
82
83 cinnamon-menus (2.6.0) rafaela; urgency=medium
84
85 * 2.6.0
86
87 -- Clement Lefebvre <root@linuxmint.com> Tue, 19 May 2015 17:05:48 +0200
88
89 cinnamon-menus (2.5.0) unstable; urgency=medium
90
91 * Bump for development
92
93 -- Michael Webster <miketwebster@gmail.com> Sat, 11 Apr 2015 09:07:20 -0400
94
95 cinnamon-menus (2.4.2) rebecca; urgency=medium
96
97 * Added missing gnome-common in build-dependencies (needed by GNOME_COMPILE_WARNINGS in configure.ac)
98
99 -- Clement Lefebvre <root@linuxmint.com> Tue, 31 Mar 2015 12:26:33 +0200
100
101 cinnamon-menus (2.4.1) rebecca; urgency=medium
102
103 * Merge debian folder improvements from debian git
104 * gir1.2-cmenu-3.0.install based on gir libdir
105
106 -- Clement Lefebvre <root@linuxmint.com> Tue, 13 Jan 2015 12:07:31 +0100
107
108 cinnamon-menus (2.4.0) rebecca; urgency=medium
109
110 * 2.4.0
111
112 -- Clement Lefebvre <root@linuxmint.com> Thu, 30 Oct 2014 15:22:32 +0100
113
114 cinnamon-menus (2.3.0) unstable; urgency=medium
115
116 * 2.3.0
117
118 -- Clement Lefebvre <root@linuxmint.com> Fri, 27 Jun 2014 14:27:33 +0100
119
120 cinnamon-menus (2.2.0) qiana; urgency=medium
121
122 * 2.2.0
123
124 -- Clement Lefebvre <root@linuxmint.com> Sat, 12 Apr 2014 11:09:28 +0100
125
126 cinnamon-menus (2.1) petra; urgency=low
127
128 * Rename
129
130 -- Michael Webster <miketwebster@gmail.com> Mon, 20 Jan 2014 10:19:41 -0500
131
132 gnome-menus (3.8.0-1ubuntu5) saucy; urgency=low
133
134 * debian/patches/ubuntu_gcc_translations.patch: revert dropping of
135 gnome-control-center categories, they got deprecated in g-c-c 3.8 but
136 we are still using 3.6. That should fix the issue where the settings
137 categories show as untranslated (lp: #1232534).
138
139 -- Sebastien Bacher <seb128@ubuntu.com> Wed, 09 Oct 2013 15:39:21 +0200
140
141 gnome-menus (3.8.0-1ubuntu4) saucy; urgency=low
142
143 * Update some of the directory icon names (LP: #1201128)
144
145 -- Jeremy Bicha <jbicha@ubuntu.com> Sun, 08 Sep 2013 14:31:02 -0400
146
147 gnome-menus (3.8.0-1ubuntu3) saucy; urgency=low
148
149 * gnome-menus.maintscript:
150 - Clean up after rename from /etc/xdg/menus/applications.menu
151 to /etc/xdg/menus/gnome-applications.menu
152 * debian/gnome-menus.postinst, debian/gnome-menus.prerm:
153 - Remove since they may cause issues with ubuntu-gnome-default-settings
154 * debian/patches/08_settings-menus.patch:
155 + Exclude Sundry items so that they aren't duplicated in the menus
156
157 -- Jeremy Bicha <jbicha@ubuntu.com> Fri, 14 Jun 2013 16:57:54 -0400
158
159 gnome-menus (3.8.0-1ubuntu2) saucy; urgency=medium
160
161 * debian/patches/01_default_prefix.patch:
162 - Re-enabled as its absense is causing problems for GNOME Shell
163 (LP: #1189722)
164
165 -- Jeremy Bicha <jbicha@ubuntu.com> Wed, 12 Jun 2013 16:22:35 -0400
166
167 gnome-menus (3.8.0-1ubuntu1) saucy; urgency=low
168
169 * Merge with Debian, remaining changes:
170 - debian/gnome-menus.postinst:
171 + Disable blacklist to not break old applications
172 - debian/gnome-menus.triggers: Drop "gmenucache".
173 - debian/patches/series: Disable 01_default_prefix.patch
174 - debian/patches/09_app_install_entry.patch:
175 + Include Software Center in menus
176 - debian/patches/70_ubuntu-directories.patch
177 + Add Ubuntu-specific directories back to POTFILES.in
178 * Dropped changes:
179 - debian/patches/22_directory-suffix-for-icons.patch
180 - debian/gnome-menus.maintscript:
181 + ensure conffile is removed on upgrade (not needed after 12.04 LTS)
182 * Refreshed patches
183 * debian/patches/50_add-gcc-apps.patch
184 - Unhide Settings panels in GNOME Shell since we're sticking with Settings
185 3.6 for now. Settings 3.8 includes a GNOME Shell 3.8 search provider.
186
187 -- Jeremy Bicha <jbicha@ubuntu.com> Sat, 08 Jun 2013 16:15:46 -0400
188
189 gnome-menus (3.8.0-1) unstable; urgency=low
190
191 [ Josselin Mouette ]
192 * Switch to interest-noawait for triggers.
193
194 [ Andreas Henriksson ]
195 * New upstream release.
196 * Upload to unstable.
197
198 -- Andreas Henriksson <andreas@fatal.se> Sat, 25 May 2013 16:41:40 +0200
199
200 gnome-menus (3.7.90-1) experimental; urgency=low
201
202 [ Josselin Mouette ]
203 * Team upload
204 * New upstream release.
205 * gnome-menus-blacklist: patch from Fabian Greffrath to handle
206 correctly menu files with missing ending newlines. Closes: #692141.
207 * Drop Debian menu support entirely. In the case it gets enabled by
208 mistake by users, it breaks the shell beyond all repair.
209 Closes: #694356.
210 * 02_kill_debian_menu.patch: new patch. Completely remove Debian menu
211 entries by discarding them at the parsing stage. This should work
212 around bug #696530 in menu-xdg.
213 * gnome-menus.postinst: clean up the desktop files once upon upgrades,
214 in order to get rid of files generated by a buggy script.
215
216 [ Dmitrijs Ledkovs ]
217 * Port gnome-menus-blacklist to python3.
218
219 [ Sjoerd Simons ]
220 * New upstream release (3.7.90)
221 * debian/patches/10_use-default-python-path.patch,
222 debian/patches/21_default-python-in-shebang.patch:
223 + Dropped, simple-editor is no longer part of gnome-menus
224 * debian/patches/*: refreshed
225
226 -- Sjoerd Simons <sjoerd@debian.org> Sat, 23 Mar 2013 20:51:31 +0100
227
228 gnome-menus (3.6.0-2) experimental; urgency=low
229
230 * Team upload
231 * Move to debhelper compat level 9, for compressed debug symbols
232 * Add libgnome-menus-3-0-dbg
233
234 -- Simon McVittie <smcv@debian.org> Thu, 25 Oct 2012 13:00:52 +0100
235
236 gnome-menus (3.6.0-1) experimental; urgency=low
237
238 [ Josselin Mouette ]
239 * Update blacklist for OpenJDK and Icedtea control panels.
240 Closes: #679565.
241
242 [ Sjoerd Simons ]
243 * New upstream release (3.6.0)
244
245 -- Sjoerd Simons <sjoerd@debian.org> Sun, 14 Oct 2012 18:42:49 +0200
246
247 gnome-menus (3.4.2-3) unstable; urgency=low
248
249 * 61_nodisplay_recurse.patch: backported from upstream git. Add a
250 function to check for NoDisplay=true recursively. This is needed for
251 gnome-shell.
252 * Update symbols file accordingly.
253
254 -- Josselin Mouette <joss@debian.org> Sat, 23 Jun 2012 20:28:18 +0200
255
256 gnome-menus (3.4.2-2) unstable; urgency=low
257
258 * Blacklist imagemagick. Closes: #678406.
259 * 60_missing_function.patch: backported from upstream git. Add a
260 missing function in the library. Closes: #676566.
261 * Update symbols file.
262
263 -- Josselin Mouette <joss@debian.org> Sat, 23 Jun 2012 19:02:38 +0200
264
265 gnome-menus (3.4.2-1) unstable; urgency=low
266
267 [ Josselin Mouette ]
268 * menus.blacklist: update to the latest KDE versions.
269 Closes: #650017, #650019.
270
271 [ Michael Biebl ]
272 * New upstream release.
273 * Change section of gir1.2-gmenu-3.0 to introspection.
274 * debian/gnome-menus.maintscript: Use new versioning scheme as recommended
275 by dpkg-maintscript-helper which better handles local modifications and
276 (bin)NMUs.
277 * debian/patches/05_debian_menu.patch: Refreshed.
278 * Drop explicit Build-Depends on gir1.2-glib-2.0 and bump
279 libgirepository1.0-dev accordingly.
280 * Bump Stanards-Version to 3.9.3.
281 * debian/menus.blacklist:
282 - Remove stale entries which are no longer relevant, mostly KDE3 related.
283 - Remove KDE entries which use OnlyShowIn=KDE;
284 - Add notes for which .desktop files bugs have been filed. Once they are
285 fixed the corresponding entries should be removed again.
286 - Add Thunar (XFCE) and related applications to blacklist.
287
288 -- Michael Biebl <biebl@debian.org> Sat, 19 May 2012 08:11:53 +0200
289
290 gnome-menus (3.2.0.1-2) unstable; urgency=low
291
292 [ Jordi Mallach ]
293 * Update po-up/ca.po.
294
295 [ Michael Biebl ]
296 * Upload to unstable.
297
298 -- Michael Biebl <biebl@debian.org> Sun, 20 Nov 2011 14:18:58 +0100
299
300 gnome-menus (3.2.0.1-1) experimental; urgency=low
301
302 [ Sjoerd Simons ]
303 * New upstream release
304 * Partial sync from Ubuntu, ensure we're using the same package names and
305 initial 3.2.0 packaging
306 * debian/patches/01_default_prefix.patch: Refreshed
307 * debian/libgnome-menu-3-0.symbols: Add symbols file
308 * debian/gnome-menus.install: Install gmenu-simple-editor
309 * Remove pysupport depends, gnome-menus bindings go via GI now.
310
311 [ Michael Biebl ]
312 * debian/rules:
313 - Call dh_python2 for gnome-menus, so python:Depends is set.
314 * debian/control.in:
315 - Bump Build-Depends on python to (>= 2.6.6-3~) for dh_python2.
316
317 [ Sjoerd Simons ]
318 * Stop installing gmenu-simple-editor
319
320 -- Sjoerd Simons <sjoerd@debian.org> Fri, 21 Oct 2011 22:26:35 +0200
321
322 gnome-menus (3.0.1-3) unstable; urgency=low
323
324 [ Josselin Mouette ]
325 * Add xterm to the blacklist.
326
327 [ Michael Biebl ]
328 * Use the .maintscript facility provided by dh_installdeb to cleanup the old
329 conffiles.
330 * Update the last unfixed version to 3.0.1-2 as we missed to remove the old
331 conffile for users upgrading from 2.30.3-2+b1. Closes: #645446
332
333 -- Michael Biebl <biebl@debian.org> Wed, 19 Oct 2011 23:21:39 +0200
334
335 gnome-menus (3.0.1-2) unstable; urgency=low
336
337 * Upload to unstable.
338 * debian/control.in:
339 - Set pkg-gnome-maintainers@lists.alioth.debian.org as Maintainer.
340 - Remove obsolete Build-Depends on dpkg-dev.
341 - Remove old Conflicts and Replaces.
342 - Bump Standards-Version to 3.9.2. No further changes.
343 - Add Vcs-* fields.
344 * Bump debhelper compatibility level to 8.
345 - Update Build-Depends on debhelper.
346 - Strip debian/tmp/ from .install files.
347 * debian/watch:
348 - Update to version 3.
349 - Switch to .xz tarballs.
350
351 -- Michael Biebl <biebl@debian.org> Fri, 14 Oct 2011 08:52:20 +0200
352
353 gnome-menus (3.0.1-1) experimental; urgency=low
354
355 * Break alacarte < 0.13.2-2 (version without support for
356 settings.menu).
357 * New upstream release.
358 * 08_settings-menus.patch: new patch. Move the old settings and system
359 settings to submenus in the “system” submenu. This is merely so that
360 they have a place until we clean them up entirely.
361 + desktop-files/Settings{,-System}.directory.in: taken from the 2.30
362 package.
363 + Update translations accordingly.
364 * po-up/fr.po: add a missing French translation.
365 * Clean up old comments in translations.
366 * 09_games-menu.patch: refreshed.
367
368 -- Josselin Mouette <joss@debian.org> Sat, 04 Jun 2011 22:13:14 +0200
369
370 gnome-menus (3.0.0-1) experimental; urgency=low
371
372 [ Josselin Mouette ]
373 * Add Sun Java VisualVM to the blacklist.
374 * Update qtconfig names.
375
376 [ Raphaël Hertzog ]
377 * New upstream release (3.0.0).
378 * Disable 06_menus_rename.patch and 08_menus_prefix.patch as they are
379 replaced with the new XDG_MENU_PREFIX feature supported by upstream.
380 * Do not try to install settings.menu, it's gone.
381 * Add some copyright notices to debian/copyright to please lintian.
382 * Add Build-Depends on gobject-introspection (>= 0.9.5) to match
383 configure requirements.
384
385 [ Josselin Mouette ]
386 * Break gnome-panel and gnome-control-center < 2.91 since
387 settings.menu is gone.
388 * 01_default_prefix.patch: new patch. Provide backwards compatibility
389 with previous versions by using "gnome-" as a default value for
390 XDG_MENU_PREFIX.
391 * Re-introduce the gir package.
392 * Use dpkg-maintscript-helper to cleanup conffiles.
393
394 -- Josselin Mouette <joss@debian.org> Mon, 11 Apr 2011 01:04:12 +0200
395
396 gnome-menus (2.30.3-2) unstable; urgency=low
397
398 * Remove gir1.0-gmenu-2.0 since nothing uses it, to ease the gir1.2
399 transition.
400
401 -- Emilio Pozuelo Monfort <pochu@debian.org> Wed, 16 Feb 2011 20:15:51 +0000
402
403 gnome-menus (2.30.3-1) unstable; urgency=low
404
405 * New upstream translation and bugfix release.
406 * 06_menus_rename.patch: refreshed. Note that upstream uses a
407 different fix but it relies on an environment variable
408 (XDG_MENU_PREFIX) and only applies to applications.menu.
409
410 -- Josselin Mouette <joss@debian.org> Sat, 18 Sep 2010 10:08:06 +0200
411
412 gnome-menus (2.30.2-1) unstable; urgency=low
413
414 [ Emilio Pozuelo Monfort ]
415 * debian/control.in,
416 debian/rules:
417 - Switch to CDBS' python-autotools.mk.
418 * debian/control.in,
419 debian/rules,
420 debian/source/format:
421 - Switch to source format 3.0 (quilt).
422
423 [ Josselin Mouette ]
424 * Add foo2zjs and its obnoxious icon to the blacklist.
425 * New upstream translation release.
426
427 -- Josselin Mouette <joss@debian.org> Tue, 20 Jul 2010 23:21:32 +0200
428
429 gnome-menus (2.30.0-1) unstable; urgency=low
430
431 * New upstream release.
432 * Now include gir1.0-gmenu-2.0, moved from gir-repository.
433
434 -- Josselin Mouette <joss@debian.org> Sat, 03 Apr 2010 23:19:34 +0200
435
436 gnome-menus (2.28.0.1-4) unstable; urgency=low
437
438 * debian/python-gmenu.install:
439 - Install the extension for python2.6 too. Thanks Jakub Wilk.
440 Closes: #573303.
441
442 -- Emilio Pozuelo Monfort <pochu@debian.org> Wed, 10 Mar 2010 15:55:51 +0100
443
444 gnome-menus (2.28.0.1-3) unstable; urgency=low
445
446 * Unbreak gnome-menus purge (ACKed by Joss)
447
448 -- Marc 'HE' Brockschmidt <he@debian.org> Tue, 12 Jan 2010 10:30:20 +0100
449
450 gnome-menus (2.28.0.1-2) unstable; urgency=low
451
452 * gnome-menus-blacklist: new script. Implements a blacklist of menu
453 entries that won't be shown by default, until the packages shipping
454 them are fixed to use NotShowIn=GNOME.
455 * menus.blacklist: the configuration file for this script.
456 * gnome-menus.triggers, gnome-menus.postinst: re-run it every time
457 something has changed in /usr/share/applications.
458 * gnome-menus.install: install this.
459 * gnome-menus.prerm: clean up before removing.
460
461 -- Josselin Mouette <joss@debian.org> Sat, 09 Jan 2010 13:18:59 +0100
462
463 gnome-menus (2.28.0.1-1) unstable; urgency=low
464
465 * New upstream release.
466 * Standards-Version is 3.8.3, no changes needed.
467 * debian/watch: don't uupdate.
468
469 -- Emilio Pozuelo Monfort <pochu@debian.org> Wed, 04 Nov 2009 18:34:41 +0100
470
471 gnome-menus (2.28.0-1) unstable; urgency=low
472
473 * New upstream release.
474 * Bump shlibs for the library.
475 * 12_submenus_inherit.patch, 12_merge_duplicates.patch: dropped,
476 merged upstream.
477 * Update list of installed files.
478 * Dropped dependency on python-glade2.
479
480 -- Josselin Mouette <joss@debian.org> Sat, 26 Sep 2009 01:44:51 +0200
481
482 gnome-menus (2.26.1-2.1) unstable; urgency=low
483
484 * Non-maintainer upload.
485 * Update simplified Chinese translation for menu.
486
487 -- Deng Xiyue <manphiz-guest@users.alioth.debian.org> Wed, 01 Jul 2009 14:47:15 +0800
488
489 gnome-menus (2.26.1-2) unstable; urgency=low
490
491 * 12_merge_duplicates.patch: use the version provided by upstream
492 instead of my gross hack. Thanks a lot, Vincent.
493 * 12_submenus_inherit.patch: stolen upstream. Make children correctly
494 inherit their parents’ layout. Necessary for
495 12_merge_duplicates.patch to work.
496 * Point to versioned GPL.
497
498 -- Josselin Mouette <joss@debian.org> Sat, 27 Jun 2009 13:01:24 +0200
499
500 gnome-menus (2.26.1-1) unstable; urgency=low
501
502 * New upstream release.
503 * python-gmenu.examples: add gnome-menus-ls.py.
504 * gnome-menus.install: don’t ship the example in here.
505 * 03_kde-legacydirs.patch: refreshed.
506
507 -- Josselin Mouette <joss@debian.org> Wed, 17 Jun 2009 22:54:01 +0200
508
509 gnome-menus (2.24.2-2) unstable; urgency=low
510
511 * Upload to unstable.
512
513 -- Josselin Mouette <joss@debian.org> Thu, 12 Mar 2009 13:04:00 +0100
514
515 gnome-menus (2.24.2-1) experimental; urgency=low
516
517 [ Loic Minier ]
518 * Drop Encoding=UTF-8 from debian/desktop-files/*.directory.in; deprecated.
519 * Don't purge /usr/lib/python2.?/site-packages/GMenuSimpleEditor during
520 first configuration.
521
522 [ Josselin Mouette ]
523 * New upstream release.
524 * Bump intltool requirement; drop the libxml-parser-perl one.
525 * Bump shlibs version to 2.23.3.
526 * 01_preferences-legacydir.patch, 02_applications-legacydir.patch,
527 04_settings-legacydir.patch: dropped, obsolete.
528 * Don’t rename preferences.menu, it doesn’t exist anymore.
529 * gnome-menus.preinst: remove gnome-preferences.menu upon upgrade.
530 * 06_menus_rename.patch: drop obsolete part.
531 * 08_menus_prefix.patch: refreshed.
532 * 11_science-menu.patch: updated to apply cleanly.
533 * 12_merge_duplicates.patch: do not re-sort merged menus that are not
534 inlined.
535
536 -- Josselin Mouette <joss@debian.org> Fri, 26 Dec 2008 17:43:03 +0100
537
538 gnome-menus (2.22.2-4) unstable; urgency=low
539
540 * 12_merge_duplicates.patch: also merge entries which appear more than
541 twice. Closes: #494667.
542
543 -- Josselin Mouette <joss@debian.org> Fri, 29 Aug 2008 11:21:11 +0200
544
545 gnome-menus (2.22.2-3) unstable; urgency=low
546
547 * Rename Science.directory to GnomeScience.directory. Closes: #491184.
548
549 -- Josselin Mouette <joss@debian.org> Fri, 18 Jul 2008 18:14:21 +0200
550
551 gnome-menus (2.22.2-2) unstable; urgency=low
552
553 * debian/po-up/ro.po: new Romanian translation from Eddy Petrișor.
554 Closes: #489070.
555 * 11_science-menu.patch: new patch.
556 + Split Science out of the Education menu.
557 + Use "science" icon for Science, "accessories" for Education, and
558 "utilities" for Accessories, since that fits better how the icons
559 were designed.
560 * Update translations accordingly.
561 * Standards version is 3.8.0.
562 * 09_games-menu.patch: lower the inline limit to 6.
563
564 -- Josselin Mouette <joss@debian.org> Tue, 15 Jul 2008 12:34:21 +0200
565
566 gnome-menus (2.22.2-1) unstable; urgency=low
567
568 * New upstream release.
569 * 11_accessibility_accessories.patch: dropped, merged upstream.
570
571 -- Josselin Mouette <joss@debian.org> Thu, 29 May 2008 00:52:40 +0200
572
573 gnome-menus (2.22.1-3) unstable; urgency=low
574
575 * 12_merge_duplicates.patch: when merging subdirectories without the
576 inline_header property, sort again the entries after the merge.
577 Closes: #447823. Also filter out duplicates. Closes: #444587.
578
579 -- Josselin Mouette <joss@debian.org> Tue, 13 May 2008 13:14:12 +0200
580
581 gnome-menus (2.22.1-2) unstable; urgency=low
582
583 * 09_games-menu.patch: don't use the flawed <OnlyUnallocated> marker,
584 simply filter out all subcategories of the games menu. This should
585 avoid issues when the user or another menu system displays these
586 entries elsewhere. Closes: #479761.
587 * Fix capitalization of Python in the description.
588 * Move the .po updating process from the clean target to the update-po
589 target.
590 * Switch to python-support.
591 * python-gmenu.postinst: work around python-central not removing the
592 old files during upgrades.
593
594 -- Josselin Mouette <joss@debian.org> Tue, 06 May 2008 20:52:16 +0200
595
596 gnome-menus (2.22.1-1) unstable; urgency=low
597
598 * New upstream bugfix release.
599
600 -- Sebastian Dröge <slomo@debian.org> Tue, 08 Apr 2008 12:59:28 +0200
601
602 gnome-menus (2.22.0-1) unstable; urgency=low
603
604 [ Josselin Mouette ]
605 * 11_accessibility_accessories.patch: new patch; exclude accessibility
606 tools from the Accessories directory, they are already in the
607 Universal Access menu.
608
609 [ Sebastian Dröge ]
610 * New upstream stable release:
611 + debian/control.in:
612 - Update build dependencies.
613 + debian/patches/07_gnomevfs.patch:
614 - Dropped, not necessary anymore as GIO is used for monitoring now.
615 + debian/patches/70_reautogen.patch:
616 - Dropped, not necessary anymore.
617
618 -- Sebastian Dröge <slomo@debian.org> Tue, 11 Mar 2008 17:12:21 +0100
619
620 gnome-menus (2.20.3-1) unstable; urgency=low
621
622 * New upstream release with translation updates only:
623 + debian/patches/70_reautogen.patch:
624 - Regenerated for the new version.
625 * debian/control.in:
626 + Update Standards-Version to 3.7.3, no additional changes needed.
627
628 -- Sebastian Dröge <slomo@debian.org> Thu, 10 Jan 2008 10:53:18 +0100
629
630 gnome-menus (2.20.2-1) unstable; urgency=low
631
632 * New upstream bugfix release with translation updates:
633 + debian/patches/70_reautogen.patch:
634 - Regenerated for the new version.
635
636 -- Sebastian Dröge <slomo@debian.org> Tue, 27 Nov 2007 06:27:02 +0100
637
638 gnome-menus (2.20.1-1) unstable; urgency=low
639
640 * New upstream bugfix release:
641 + debian/patches/70_reautogen.patch:
642 - Regenerated for the new version.
643
644 -- Sebastian Dröge <slomo@debian.org> Fri, 26 Oct 2007 20:16:34 +0200
645
646 gnome-menus (2.20.0-2) unstable; urgency=low
647
648 * debian/patches/07_gnomevfs.patch:
649 + Include gnome-vfs-utils.h to fix implicit pointer conversion which
650 breaks on archs where sizeof(void*)>sizeof(int). Thanks to
651 Dann Frazier for the patch (Closes: #443339).
652
653 -- Sebastian Dröge <slomo@debian.org> Thu, 20 Sep 2007 20:20:12 +0200
654
655 gnome-menus (2.20.0-1) unstable; urgency=low
656
657 [ Loic Minier ]
658 * Expand tabs in control.
659 * Cleanup rules.
660 * Update path 07_gnomevfs to use GnomeVFS to escape URIs; solves handling of
661 pathnames with spaces; from Ubuntu; thanks Sébastien Bacher.
662
663 [ Sebastian Dröge ]
664 * New upstream release.
665 * Upload to unstable, drop check-dist include.
666 * debian/patches/70_reautogen.patch:
667 + Updated for the new version.
668
669 -- Sebastian Dröge <slomo@debian.org> Thu, 20 Sep 2007 11:16:44 +0200
670
671 gnome-menus (2.19.6-1) experimental; urgency=low
672
673 * New patch, but disabled by default, 20_show-admin-tools-for-admin-group,
674 permits hiding menu entries requiring root rights when the user isn't in
675 the admin group; found in the Ubuntu package.
676 * New upstream release series; these are development releases, the API may
677 still change incompatibly; no API change in this release though.
678 - Target at experimental; include check-dist.mk.
679 - Refresh patches 09_games-menu, 20_show-admin-tools-for-admin-group to
680 apply cleanly.
681 - Update relibtoolizing patch, 70_reautogen; run intltoolize too.
682 - New patch, 21_default-python-in-shebang, fixes shebang of
683 gmenu-simple-editor to use the default Python version.
684
685 -- Loic Minier <lool@dooz.org> Fri, 03 Aug 2007 11:55:44 +0200
686
687 gnome-menus (2.18.3-2) unstable; urgency=low
688
689 [ Josselin Mouette ]
690 * Debian.directory: don't display the Debian menu by default. It can
691 be enabled with the menu editor.
692 * Convert patches to quilt; build-depend on quilt.
693 * Remove pycompat and the dh_python call.
694 * Make the included menu translatable; build-depend on intltool.
695 * 09_games-menu.patch: split the games menu in submenus following the
696 desktop specification keywords. Use a default layout that doesn't
697 show them unless there are at least 8 games in the submenu. This
698 should avoid showing submenus by default while making the menu
699 usable for people with lots of games installed.
700 * The desktop-files/ directory contains desktop entries for these
701 submenus.
702 * The po-up/ directory contains translations for these entries.
703
704 [ Christian Perrier ]
705 * Translations for po-up/:
706 - Picked 56 PO files from po-sections/ in the menu package.
707 Updates:
708 - Punjabi. Closes: #433570, #433571
709 - Korean. Closes: #433576
710 - Tamil. Closes: #433588
711 - Gujarati. Closes: #433595
712 - Thai. Closes: #433600
713 - Spanish. Closes: #433601
714 - Hungarian. Closes: #433605
715 - Simplified Chinese. Closes: #433606
716 - Basque. Closes: #433610
717 - Polish. Closes: #433614
718 - Bulgarian. Closes: #433617
719 - German. Closes: #433628
720 - Brazilian Portuguese. Closes: #433680
721 - Wolof. Closes: #433696, #433702
722 - Indonesian. Closes: #433764
723 - Vietnamese. Closes: #433795
724 - Swedish. Closes: #433930
725 - Marathi.
726 - Czech. Closes: #434001
727 - Simplified Chinese. Closes: #433606
728 - Russian. Closes: #434780
729 - German. Closes: #434785
730
731 [ Josselin Mouette ]
732 * Translations for po-up/:
733 - Lithuanian. Closes: #434805.
734 - Portuguese. Closes: #435032.
735 * Minor fixes in French translation.
736
737 -- Josselin Mouette <joss@debian.org> Sun, 29 Jul 2007 18:57:54 +0200
738
739 gnome-menus (2.18.3-1) unstable; urgency=low
740
741 * New upstream stable release; no API change.
742 - Update autotools patch, 70_reautogen.
743
744 -- Loic Minier <lool@dooz.org> Tue, 03 Jul 2007 19:58:18 +0200
745
746 gnome-menus (2.18.2-1) unstable; urgency=low
747
748 * New upstream stable release; no API change.
749 - Let python-gmenu depend on python-gtk2 as GMenuSimpleEditor uses it.
750 - Update relibtoolizing patch which is required; add comments on how to
751 generate the patch.
752
753 -- Loic Minier <lool@dooz.org> Mon, 28 May 2007 15:41:52 +0200
754
755 gnome-menus (2.18.0-2) unstable; urgency=low
756
757 * Fix .orig file in patch 07_gnomevfs; fixes FTBFS on double build;
758 closes: #424341.
759 * Wrap build-deps and deps.
760
761 -- Loic Minier <lool@dooz.org> Wed, 16 May 2007 16:37:00 +0200
762
763 gnome-menus (2.18.0-1) unstable; urgency=low
764
765 * New upstream release.
766 * 07_gnomevfs.patch, 70_reautogen.patch: updated from the Ubuntu package.
767 gnome-vfs will still be used as default backend until inotify support is
768 enabled upstream by default.
769
770 -- Sebastian Dröge <slomo@debian.org> Wed, 25 Apr 2007 06:26:26 +0200
771
772 gnome-menus (2.16.1-3) unstable; urgency=medium
773
774 [ Loic Minier ]
775 * Add a get-orig-source target to retrieve the upstream tarball.
776
777 [ Josselin Mouette ]
778 * 06_menus_rename.patch: reinstate the renaming in the menu editor, as
779 we are lacking an interface for *saving* a renamed menu.
780 Closes: #411246.
781
782 -- Josselin Mouette <joss@debian.org> Sat, 17 Feb 2007 14:14:35 +0100
783
784 gnome-menus (2.16.1-2) unstable; urgency=low
785
786 * 08_menus_prefix.patch:
787 + Only rename the specific menus we are renaming, avoid lookups
788 for gnome-anything.menu (closes: #403165, #403456).
789 + Strip the "gnome-" part specifically when opening the merged
790 directory.
791
792 -- Josselin Mouette <joss@debian.org> Thu, 21 Dec 2006 20:15:49 +0100
793
794 gnome-menus (2.16.1-1) unstable; urgency=low
795
796 * New upstream translation release.
797 * 08_menus_prefix.patch: try "gnome-" as a prefix for menu files
798 instead of renaming them explicitly. This should make
799 applications-merged/ work as expected.
800 * 06_menus_rename.patch: only keep the gnome-preferences renaming.
801 * Build-depend on python-central 0.5 to please lintian.
802 * Bump shlibs version to 2.16.1-1 to allow relying on this feature.
803
804 -- Josselin Mouette <joss@debian.org> Mon, 4 Dec 2006 22:36:55 +0100
805
806 gnome-menus (2.16.0-2) unstable; urgency=low
807
808 * Upload to unstable.
809
810 -- Loic Minier <lool@dooz.org> Thu, 19 Oct 2006 11:41:08 +0200
811
812 gnome-menus (2.16.0-1) experimental; urgency=low
813
814 * New upstream release; no API change.
815
816 -- Loic Minier <lool@dooz.org> Mon, 25 Sep 2006 16:42:44 +0200
817
818 gnome-menus (2.15.91-1) experimental; urgency=low
819
820 * New upstream development releases, with API additions.
821 - Target at experimental.
822 - Bump up shlibs to >= 2.15.4.
823 - Update patches: 03_kde-legacydirs, 04_settings-legacydir,
824 05_debian_menu, 06_menus_rename, 07_gnomevfs, 70_reautogen.
825 * Add CDBS' utils.
826
827 -- Loic Minier <lool@dooz.org> Sun, 13 Aug 2006 19:04:07 +0200
828
829 gnome-menus (2.14.3-1) unstable; urgency=low
830
831 * New upstream release, no API change.
832 - Update patch 70_reautogen.
833
834 -- Loic Minier <lool@dooz.org> Tue, 8 Aug 2006 11:02:56 +0200
835
836 gnome-menus (2.14.0-8) unstable; urgency=low
837
838 * Add debian/control to the pyversions -r call since it's mandatory, even if
839 the man page claims it's optional.
840
841 -- Loic Minier <lool@dooz.org> Sat, 5 Aug 2006 20:53:29 +0200
842
843 gnome-menus (2.14.0-7) unstable; urgency=low
844
845 * Let python-gmenu also Conflict with gnome-menus << 2.14.0-3, since the
846 historical Replace is not honored in Python packages following the newer
847 policy; thanks Josselin Mouette. (Closes: #381426)
848
849 -- Loic Minier <lool@dooz.org> Sat, 5 Aug 2006 20:02:52 +0200
850
851 gnome-menus (2.14.0-6) unstable; urgency=low
852
853 * Fix 07_gnomevfs patch which shipped a backup file.
854
855 -- Loic Minier <lool@dooz.org> Thu, 27 Jul 2006 22:42:24 +0200
856
857 gnome-menus (2.14.0-5) unstable; urgency=medium
858
859 * Add ${python:Provides} to python-gmenu.
860 * Build python-gmenu for all available versions of Python >= 2.3;
861 build-depend on python-all-dev.
862 * Remove trailing spaces.
863 * Move relibtoolizing patch (08_reautogen) to apply later, at 70_reautogen.
864 * New patch to use the default python path in gmenu-simple-editor, thanks
865 Joe Wreschnig.
866
867 -- Loic Minier <lool@dooz.org> Thu, 27 Jul 2006 22:32:19 +0200
868
869 gnome-menus (2.14.0-4) unstable; urgency=low
870
871 * Fix watch file.
872 * Update to new Python policy. (Closes: #373435)
873 - Bump up debhelper build-dep to 5.0.37.2.
874 - Set Python compatibility level to 2.
875 - Add XB-Python-Version to python-gmenu and gnome-menus.
876 - Add a python-central (>= 0.4.17) build-dep.
877 - Bump up cdbs build-dep to >= 0.4.43.
878 - Add a XS-Python-Version: current as gnome-menus is the only package to
879 depend on python-gmenu.
880 - Call dh_pycentral to fill XB-Python-Version and add a pycentral dep.
881 - Move the fixup snippet for the executable bit from binary-post-install
882 to binary-install, before dh_pycentral moves the files around.
883
884 -- Loic Minier <lool@dooz.org> Thu, 13 Jul 2006 20:15:34 +0200
885
886 gnome-menus (2.14.0-3) unstable; urgency=low
887
888 * Drop *.la files from libgnome-menu-dev as these were removed from its
889 reverse dependencies.
890 * Bump up Standards-Version to 3.7.2.
891 * Add even more ${misc:Depends}.
892 * Make package binNMU-safe.
893 - Add a dpkg-dev >= 1.13.19 build-dep.
894 - Use ${binary:Version} in inter-dependencies.
895 * Bump up Debhelper compatibility level to 5.
896 * Set executable bit on Python files with a shebang to make lintian happy.
897 * Install /usr/lib/python*/site-packages/GMenuSimpleEditor in python-gmenu
898 and not gnome-menus; let python-gmenu Replace gnome-menus << 2.14.0-3.
899
900 -- Loic Minier <lool@dooz.org> Thu, 22 Jun 2006 15:28:27 +0200
901
902 gnome-menus (2.14.0-2) unstable; urgency=low
903
904 [ Loic Minier ]
905 * Sync with overrides.
906 - Set libgnome-menu-dev Section to libdevel.
907 [debian/control, debian/control.in]
908 - Set python-gmenu Section to python.
909 [debian/control, debian/control.in]
910
911 [ Josselin Mouette ]
912 * 07_gnomevfs.patch: use gnome-vfs instead of fam for monitoring.
913 This should be the end of the "menu disappeared" bugs.
914 * 08_reautogen.patch: the re-autogenisation that follows.
915 * control.in: replace dependencies and build-dependencies on fam by
916 gnome-vfs. Entirely remove the dependency for the -dev package, it's
917 not needed for a backend.
918
919 -- Josselin Mouette <joss@debian.org> Sat, 20 May 2006 07:11:17 +0200
920
921 gnome-menus (2.14.0-1) unstable; urgency=low
922
923 * New upstream version
924 * Renamed the patches to use .patch instead of .diff
925 * debian/control.in:
926 - dropped gnomevfs requirement it doesn't use it
927 * debian/libgnome-menu2.shlibs:
928 - updated shlibs version
929 * debian/patches/06_menus_rename.patch:
930 - updated
931 * debian/patches/07_relibtoolise.patch:
932 - not required
933 * debian/watch:
934 - updated
935
936 [ J.H.M. Dassen (Ray) ]
937 * [patches/07_relibtoolise.diff] Added to do away with unneeded direct
938 library dependencies in the gnome-menus package.
939
940 [ Josselin Mouette ]
941 * Acknowledge NMU:
942 + Add python-glade2 depends for gnome-menus (Closes: #347176).
943
944 -- Sebastien Bacher <seb128@debian.org> Sat, 29 Apr 2006 15:26:42 +0200
945
946 gnome-menus (2.12.0-2) unstable; urgency=low
947
948 * debian/control.in:
949 - depend on ${python:Depends}.
950 * Upload to unstable.
951
952 -- Josselin Mouette <joss@debian.org> Mon, 2 Jan 2006 14:03:46 +0100
953
954 gnome-menus (2.12.0-1) experimental; urgency=low
955
956 * New upstream version:
957 - ship a menu editor (Closes: #332976).
958 - use Education instead of Edutainment (Closes: #314491).
959 * debian/control.in:
960 - new python-gmenu package.
961 - updated for the soname change.
962 - updated the Build-Depends/Depends for the new packages.
963 - updated the Standards-Version.
964 * debian/gnome-menus.install:
965 - updated for new files.
966 * debian/patches/04_settings-legacydir.diff:
967 - updated.
968 * debian/patches/06_menus_rename.diff:
969 - updated.
970 * debian/rules:
971 - use dh_python.
972 * debian/watch:
973 - updated
974
975 -- Sebastien Bacher <seb128@debian.org> Mon, 17 Oct 2005 14:45:15 +0200
976
977 gnome-menus (2.10.2-1) unstable; urgency=low
978
979 * New upstream version:
980 - make user .desktop files correctly override system ones.
981 - remove <LegacyDir> from settings menu.
982 - fix memory leaks on re-load.
983 - fix issue with duplicate sub-menus.
984
985 -- Sebastien Bacher <seb128@debian.org> Tue, 28 Jun 2005 11:19:50 +0200
986
987 gnome-menus (2.10.1-3) unstable; urgency=low
988
989 * debian/patches/04_settings-legacydir.diff:
990 - don't use LegacyDir for the Desktop menu (Closes: #304326).
991
992 -- Sebastien Bacher <seb128@debian.org> Tue, 14 Jun 2005 14:24:47 +0200
993
994 gnome-menus (2.10.1-2) unstable; urgency=low
995
996 * Upload to unstable.
997 * debian/patches/06_menus_rename.diff:
998 - patch for the menus rename.
999 * debian/rules:
1000 - renamed menu files to not conflict with other desktops
1001 (Closes: #307098).
1002
1003 -- Sebastien Bacher <seb128@debian.org> Tue, 7 Jun 2005 19:47:00 +0200
1004
1005 gnome-menus (2.10.1-1) experimental; urgency=low
1006
1007 * Initial upload to debian.
1008
1009 -- Sebastien Bacher <seb128@debian.org> Wed, 23 Mar 2005 18:35:08 +0100
1010
1011 gnome-menus (2.10.1-0ubuntu1) hoary; urgency=low
1012
1013 * New upstream release:
1014 - add support for new "type" argument to <MergeFile>.
1015 - monitor <MergeDir>s for changes.
1016 - make user desktop entries override system ones.
1017 - make .directory files in <LegacyDir>s be pulled in.
1018 - fix weirdess with [KDE Desktop Entry] files.
1019 - fix <LegacyDir>s which don't contain any entries in the toplevel.
1020 - make sure items in <LegacyDir>s as allocated.
1021 - make <LegacyDir>s with a prefix work correctly.
1022 * debian/patches/03_kde-legacydirs.diff:
1023 - don't use KDELegacyDirs.
1024
1025 -- Sebastien Bacher <seb128@canonical.com> Wed, 23 Mar 2005 15:28:55 +0100
1026
1027 gnome-menus (2.10.0-0ubuntu1) hoary; urgency=low
1028
1029 * New upstream release.
1030 * debian/watch:
1031 - updated.
1032
1033 -- Sebastien Bacher <seb128@canonical.com> Mon, 7 Mar 2005 16:09:23 +0100
1034
1035 gnome-menus (2.9.92-0ubuntu1) hoary; urgency=low
1036
1037 * New upstream release:
1038 - fix issue with file monitoring and subdirs of <AppDir> (Hoary: #5934).
1039
1040 -- Sebastien Bacher <seb128@canonical.com> Tue, 1 Mar 2005 12:39:23 +0100
1041
1042 gnome-menus (2.9.90-0ubuntu1) hoary; urgency=low
1043
1044 * New upstream release:
1045 - do not include the Core category in the Other menu (Hoary: #5484).
1046 * debian/patches/06_launchbox.diff:
1047 - removed, these changes are in the new version.
1048
1049 -- Sebastien Bacher <seb128@canonical.com> Tue, 25 Jan 2005 19:24:59 +0100
1050
1051 gnome-menus (2.9.4-0ubuntu2) hoary; urgency=low
1052
1053 * debian/patches/06_launchbox.diff:
1054 - added the patch for GNOME launch box.
1055
1056 -- Sebastien Bacher <seb128@canonical.com> Thu, 20 Jan 2005 13:09:25 +0100
1057
1058 gnome-menus (2.9.4-0ubuntu1) hoary; urgency=low
1059
1060 * New upstream release:
1061 - new menus layout.
1062 - reload menus correctly when they are deleted/updated .
1063 * debian/patches/03_menu_layout.diff:
1064 - removed, the changes are included upstream.
1065
1066 -- Sebastien Bacher <seb128@canonical.com> Tue, 11 Jan 2005 00:18:45 +0100
1067
1068 gnome-menus (2.9.3-0ubuntu1) hoary; urgency=low
1069
1070 * New upstream release.
1071 * debian/patches/05_debian_menu.diff:
1072 - patch for the Debian menu.
1073
1074 -- Sebastien Bacher <seb128@canonical.com> Tue, 21 Dec 2004 22:34:04 +0100
1075
1076 gnome-menus (2.9.2cvs041212-0ubuntu4) hoary; urgency=low
1077
1078 * The Applications menu has an entry for the Debian menu now. If you want to
1079 get it you only need to install menu and menu-xdg.
1080 * layout/applications.menu:
1081 - added an entry for the Debian menu.
1082 * debian/Debian.directory:
1083 - added.
1084 * debian/gnome-menus.install:
1085 - install Debian.directory.
1086
1087 -- Sebastien Bacher <seb128@debian.org> Sun, 19 Dec 2004 21:32:34 +0100
1088
1089 gnome-menus (2.9.2cvs041212-0ubuntu3) hoary; urgency=low
1090
1091 * control.in: should have been kdelibs-data not kdelibs
1092
1093 -- Chris Halls <chris.halls@credativ.co.uk> Wed, 15 Dec 2004 00:29:08 +0000
1094
1095 gnome-menus (2.9.2cvs041212-0ubuntu2) hoary; urgency=low
1096
1097 * control.in: gnome-menus Replaces pre-hoary kdelibs-data (file conflict)
1098
1099 -- Chris Halls <chris.halls@credativ.co.uk> Tue, 14 Dec 2004 18:51:16 +0000
1100
1101 gnome-menus (2.9.2cvs041212-0ubuntu1) hoary; urgency=low
1102
1103 * CVS snapshot.
1104 * debian/patches/03_menu_layout.diff:
1105 - patch by Vincent Untz <vincent@vuntz.net> for the new menu layout.
1106 * debian/patches/04_settings-legacydir.diff:
1107 - merged the old capplet .desktop locations here too.
1108
1109 -- Sebastien Bacher <seb128@canonical.com> Sun, 12 Dec 2004 19:44:20 +0100
1110
1111 gnome-menus (2.9.2-0ubuntu3) hoary; urgency=low
1112
1113 * debian/patches/*:
1114 - Merge the old capplet .desktop locations.
1115
1116 -- Jeff Waugh <jeff.waugh@canonical.com> Tue, 7 Dec 2004 16:55:37 +0100
1117
1118 gnome-menus (2.9.2-0ubuntu2) hoary; urgency=low
1119
1120 * debian/control.in:
1121 - updated the Build-Depends.
1122
1123 -- Sebastien Bacher <seb128@canonical.com> Tue, 30 Nov 2004 19:21:39 +0100
1124
1125 gnome-menus (2.9.2-0ubuntu1) hoary; urgency=low
1126
1127 * Initial Release.
1128
1129 -- Sebastien Bacher <seb128@canonical.com> Tue, 30 Nov 2004 12:49:00 +0100
1130
0 Source: cinnamon-menus
1 Section: x11
2 Priority: optional
3 Maintainer: Clement Lefebvre <root@linuxmint.com>
4 Build-Depends: debhelper (>= 9),
5 dh-autoreconf,
6 autoconf-archive,
7 dh-python,
8 gnome-common,
9 gnome-pkg-tools,
10 gobject-introspection (>= 0.9.12-4~),
11 intltool (>= 0.40.0),
12 libgirepository1.0-dev (>= 0.10.7-1~),
13 libglib2.0-dev (>= 2.30.0),
14 python3 (>= 3.1)
15 Standards-Version: 3.9.5
16 X-Python3-Version: >= 3.1
17
18 Package: libcinnamon-menu-3-0
19 Architecture: any
20 Depends: ${misc:Depends}, ${shlibs:Depends}
21 Description: Cinnamon implementation of the freedesktop menu specification
22 The package contains an implementation of the draft
23 "Desktop Menu Specification" from freedesktop.org:
24 .
25 http://www.freedesktop.org/Standards/menu-spec
26 .
27 This package contains the shared library.
28
29 Package: libcinnamon-menu-3-0-dbg
30 Section: debug
31 Priority: extra
32 Architecture: any
33 Depends: libcinnamon-menu-3-0 (= ${binary:Version}), ${misc:Depends}
34 Description: Cinnamon implementation of the freedesktop menu specification
35 The package contains an implementation of the draft
36 "Desktop Menu Specification" from freedesktop.org:
37 .
38 http://www.freedesktop.org/Standards/menu-spec
39 .
40 This package contains debugging symbols.
41
42 Package: libcinnamon-menu-3-dev
43 Architecture: any
44 Section: libdevel
45 Depends: gir1.2-cmenu-3.0 (= ${binary:Version}),
46 libcinnamon-menu-3-0 (= ${binary:Version}),
47 libglib2.0-dev (>= 2.30.0),
48 ${misc:Depends}
49 Replaces: gir-repository-dev (<< 0.6.5-6)
50 Description: Cinnamon implementation of the freedesktop menu specification
51 The package contains an implementation of the draft
52 "Desktop Menu Specification" from freedesktop.org:
53 .
54 http://www.freedesktop.org/Standards/menu-spec
55 .
56 This package contains the development headers.
57
58 Package: gir1.2-cmenu-3.0
59 Section: introspection
60 Architecture: any
61 Depends: ${gir:Depends}, ${misc:Depends}, ${shlibs:Depends}
62 Conflicts: gobject-introspection-repository
63 Description: GObject introspection data for the Cinnamon menu library
64 This package contains introspection data for Cinnamon menu, an
65 implementation of the desktop menu specification from freedesktop.org.
66 .
67 It can be used by languages supporting dynamic bindings with
68 the GIRepository format.
0 Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
1 Upstream-Name: cinnamon-menus
2 Upstream-Contact: Linux Mint Project <root@linuxmint.com>
3 Source: https://github.com/linuxmint/cinnamon-menus.git
4
5 Files: *
6 Copyright: 1996-2011, Free Software Foundation, Inc.
7 License: GPL-2+
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12 .
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17 .
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 .
22 On Debian systems, the complete text of the GNU General Public License
23 version 2 can be found in `/usr/share/common-licenses/GPL-2'.
24
25 Files: libmenu/desktop-entries.c
26 libmenu/desktop-entries.h
27 libmenu/entry-directories.c
28 libmenu/entry-directories.h
29 libmenu/gmenu-tree.c
30 libmenu/gmenu-tree.h
31 libmenu/menu-layout.c
32 libmenu/menu-layout.h
33 libmenu/menu-monitor.c
34 libmenu/menu-monitor.h
35 libmenu/menu-util.c
36 libmenu/menu-util.h
37 Copyright: 2006, Mark McLoughlin
38 2002-2011, Red Hat, Inc
39 2007, Sebastian Dröge
40 2008, Vincent Untz
41 License: LGPL-2+
42
43 Files: libmenu/canonicalize.*
44 Copyright: 1996-2002, Free Software Foundation, Inc
45 2002, Red Hat, Inc. (trivial port to GLib)
46 License: LGPL-2.1+
47 The GNU C Library is free software; you can redistribute it and/or modify it
48 under the terms of the GNU Lesser General Public License as published by the
49 Free Software Foundation; either version 2.1 of the License, or (at your
50 option) any later version.
51 .
52 The GNU C Library is distributed in the hope that it will be useful, but
53 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
54 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
55 for more details.
56 .
57 You should have received a copy of the GNU Lesser General Public License
58 along with the GNU C Library; if not, write to the Free Software Foundation,
59 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
60 .
61 On Debian systems, the complete text of the GNU Lesser General Public License
62 version 2.1 can be found in `/usr/share/common-licenses/LGPL-2.1'.
63
64 Files: ltmain.sh
65 Copyright: 1996-2011, Free Software Foundation, Inc.
66 License: GPL-2+ or license of distributed software
67 GNU Libtool is free software; you can redistribute it and/or modify
68 it under the terms of the GNU General Public License as published by
69 the Free Software Foundation; either version 2 of the License, or
70 (at your option) any later version.
71 .
72 As a special exception to the GNU General Public License,
73 if you distribute this file as part of a program or library that
74 is built using GNU Libtool, you may include this file under the
75 same distribution terms that you use for the rest of that program.
76 .
77 GNU Libtool is distributed in the hope that it will be useful, but
78 WITHOUT ANY WARRANTY; without even the implied warranty of
79 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
80 General Public License for more details.
81 .
82 You should have received a copy of the GNU General Public License
83 along with GNU Libtool; see the file COPYING. If not, a copy
84 can be downloaded from http://www.gnu.org/licenses/gpl.html,
85 or obtained by writing to the Free Software Foundation, Inc.,
86 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
87 .
88 On Debian systems, the complete text of the GNU General Public License
89 version 2 can be found in `/usr/share/common-licenses/GPL-2'.
90
91 Files: debian/*
92 Copyright: 2014, Clement Lefebvre
93 2014, Maximiliano Curia <maxy@debian.org>
94 License: LGPL-2+
95
96 License: LGPL-2+
97 This library is free software; you can redistribute it and/or modify it under
98 the terms of the GNU Lesser General Public License as published by the Free
99 Software Foundation; either version 2 of the License, or (at your option) any
100 later version.
101 .
102 This library is distributed in the hope that it will be useful, but WITHOUT
103 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
104 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
105 details.
106 .
107 You should have received a copy of the GNU Lesser General Public License
108 along with this library; if not, write to the Free Software Foundation, Inc.,
109 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
110 .
111 On Debian systems, the complete text of the GNU Lesser General Public License
112 version 2 can be found in `/usr/share/common-licenses/LGPL-2'.
0 TYPELIBDIR/girepository-1.0
0 libcinnamon-menu-3.so.0 libcinnamon-menu-3-0 #MINVER#
1 gmenu_tree_alias_get_aliased_directory@Base 2.2.0
2 gmenu_tree_alias_get_aliased_entry@Base 2.2.0
3 gmenu_tree_alias_get_aliased_item_type@Base 2.2.0
4 gmenu_tree_alias_get_directory@Base 2.2.0
5 gmenu_tree_alias_get_parent@Base 2.2.0
6 gmenu_tree_alias_get_tree@Base 2.2.0
7 gmenu_tree_alias_get_type@Base 2.2.0
8 gmenu_tree_directory_get_comment@Base 2.2.0
9 gmenu_tree_directory_get_desktop_file_path@Base 2.2.0
10 gmenu_tree_directory_get_generic_name@Base 2.2.0
11 gmenu_tree_directory_get_icon@Base 2.2.0
12 gmenu_tree_directory_get_is_nodisplay@Base 2.2.0
13 gmenu_tree_directory_get_menu_id@Base 2.2.0
14 gmenu_tree_directory_get_name@Base 2.2.0
15 gmenu_tree_directory_get_parent@Base 2.2.0
16 gmenu_tree_directory_get_tree@Base 2.2.0
17 gmenu_tree_directory_get_type@Base 2.2.0
18 gmenu_tree_directory_iter@Base 2.2.0
19 gmenu_tree_directory_make_path@Base 2.2.0
20 gmenu_tree_entry_get_app_info@Base 2.2.0
21 gmenu_tree_entry_get_desktop_file_id@Base 2.2.0
22 gmenu_tree_entry_get_desktop_file_path@Base 2.2.0
23 gmenu_tree_entry_get_is_excluded@Base 2.2.0
24 gmenu_tree_entry_get_is_nodisplay_recurse@Base 2.2.0
25 gmenu_tree_entry_get_is_unallocated@Base 2.2.0
26 gmenu_tree_entry_get_parent@Base 2.2.0
27 gmenu_tree_entry_get_tree@Base 2.2.0
28 gmenu_tree_entry_get_type@Base 2.2.0
29 gmenu_tree_flags_get_type@Base 2.2.0
30 gmenu_tree_get_canonical_menu_path@Base 2.2.0
31 gmenu_tree_get_directory_from_path@Base 2.2.0
32 gmenu_tree_get_entry_by_id@Base 2.2.0
33 gmenu_tree_get_root_directory@Base 2.2.0
34 gmenu_tree_get_type@Base 2.2.0
35 gmenu_tree_header_get_directory@Base 2.2.0
36 gmenu_tree_header_get_parent@Base 2.2.0
37 gmenu_tree_header_get_tree@Base 2.2.0
38 gmenu_tree_header_get_type@Base 2.2.0
39 gmenu_tree_item_ref@Base 2.2.0
40 gmenu_tree_item_unref@Base 2.2.0
41 gmenu_tree_iter_get_alias@Base 2.2.0
42 gmenu_tree_iter_get_directory@Base 2.2.0
43 gmenu_tree_iter_get_entry@Base 2.2.0
44 gmenu_tree_iter_get_header@Base 2.2.0
45 gmenu_tree_iter_get_separator@Base 2.2.0
46 gmenu_tree_iter_get_type@Base 2.2.0
47 gmenu_tree_iter_next@Base 2.2.0
48 gmenu_tree_iter_ref@Base 2.2.0
49 gmenu_tree_iter_unref@Base 2.2.0
50 gmenu_tree_load_sync@Base 2.2.0
51 gmenu_tree_new@Base 2.2.0
52 gmenu_tree_new_for_path@Base 2.2.0
53 gmenu_tree_separator_get_parent@Base 2.2.0
54 gmenu_tree_separator_get_tree@Base 2.2.0
55 gmenu_tree_separator_get_type@Base 2.2.0
0 usr/include
1 usr/lib/*/*.so
2 usr/lib/*/pkgconfig
3 usr/share/gir-1.0
0 --- a/libmenu/gmenu-tree.c
1 +++ b/libmenu/gmenu-tree.c
2 @@ -391,6 +391,16 @@
3 }
4 }
5
6 +static char *
7 +prefix_menu_name (const char *orig_name)
8 +{
9 + char *prefix;
10 + prefix = g_getenv ("XDG_MENU_PREFIX");
11 + if (prefix == NULL)
12 + prefix = "gnome-";
13 + return g_strconcat (prefix, orig_name, NULL);
14 +}
15 +
16 static gboolean
17 gmenu_tree_canonicalize_path (GMenuTree *tree,
18 GError **error)
19 @@ -416,6 +426,9 @@
20 menu_file = tree->basename;
21 xdg_menu_prefix = g_getenv ("XDG_MENU_PREFIX");
22
23 + if (xdg_menu_prefix == NULL)
24 + xdg_menu_prefix = "gnome-";
25 +
26 if (xdg_menu_prefix != NULL)
27 {
28 gchar *prefixed_basename;
29 @@ -2077,13 +2090,10 @@
30 found = FALSE;
31 menu_file = g_strconcat (menu_name, ".menu", NULL);
32
33 - if (strcmp (menu_file, "applications.menu") == 0 &&
34 - g_getenv ("XDG_MENU_PREFIX"))
35 + if (strcmp (menu_file, "applications.menu") == 0)
36 {
37 char *prefixed_basename;
38 - prefixed_basename = g_strdup_printf ("%s%s",
39 - g_getenv ("XDG_MENU_PREFIX"),
40 - menu_file);
41 + prefixed_basename = prefix_menu_name (menu_file);
42 found = load_parent_merge_file_from_basename (tree, loaded_menu_files,
43 layout, prefixed_basename,
44 canonical_basedir);
0 Index: gnome-menus-3.4.2/libmenu/desktop-entries.c
1 ===================================================================
2 --- gnome-menus-3.4.2.orig/libmenu/desktop-entries.c 2011-10-24 13:48:12.000000000 +0200
3 +++ gnome-menus-3.4.2/libmenu/desktop-entries.c 2013-01-02 21:11:23.617525227 +0100
4 @@ -250,6 +250,8 @@ desktop_entry_load_directory (DesktopEnt
5 static gboolean
6 desktop_entry_load (DesktopEntry *entry)
7 {
8 + if (strstr (entry->path, "/menu-xdg/"))
9 + return FALSE;
10 if (entry->type == DESKTOP_ENTRY_DESKTOP)
11 {
12 DesktopEntryDesktop *entry_desktop = (DesktopEntryDesktop*)entry;
0 --- a/layout/gnome-applications.menu
1 +++ b/layout/gnome-applications.menu
2 @@ -7,7 +7,6 @@
3 <Directory>X-GNOME-Menu-Applications.directory</Directory>
4
5 <!-- Scan legacy dirs first, as later items take priority -->
6 - <KDELegacyDirs/>
7 <LegacyDir>/etc/X11/applnk</LegacyDir>
8 <LegacyDir>/usr/share/gnome/apps</LegacyDir>
9
0 Index: gnome-menus-3.8.0/layout/gnome-applications.menu
1 ===================================================================
2 --- gnome-menus-3.8.0.orig/layout/gnome-applications.menu 2013-06-14 15:48:17.509604188 -0400
3 +++ gnome-menus-3.8.0/layout/gnome-applications.menu 2013-06-14 15:57:09.689581931 -0400
4 @@ -233,6 +233,118 @@
5 <Not><Filename>gnome-system-monitor.desktop</Filename></Not>
6 </And>
7 </Include>
8 + <Menu>
9 + <Name>Preferences</Name>
10 + <Directory>Settings.directory</Directory>
11 + <Include>
12 + <And>
13 + <Category>Settings</Category>
14 + <Not>
15 + <Or>
16 + <Category>System</Category>
17 + <Category>X-GNOME-Settings-Panel</Category>
18 + <Filename>alacarte.desktop</Filename>
19 + <Filename>caribou.desktop</Filename>
20 + <Filename>dconf-editor.desktop</Filename>
21 + <Filename>fedora-im-chooser.desktop</Filename>
22 + <Filename>fedora-release-notes.desktop</Filename>
23 + <Filename>firewall-config.desktop</Filename>
24 + <Filename>flash-player-properties.desktop</Filename>
25 + <Filename>gconf-editor.desktop</Filename>
26 + <Filename>gnome-abrt.desktop</Filename>
27 + <Filename>fedora-abrt.desktop</Filename>
28 + <Filename>gnome-orca.desktop</Filename>
29 + <Filename>gnome-power-statistics.desktop</Filename>
30 + <Filename>gnome-user-share-properties.desktop</Filename>
31 + <Filename>ibus.desktop</Filename>
32 + <Filename>ibus-daemon.desktop</Filename>
33 + <Filename>ibus-setup-anthy.desktop</Filename>
34 + <Filename>ibus-setup.desktop</Filename>
35 + <Filename>ibus-setup-hangul.desktop</Filename>
36 + <Filename>ibus-setup-libbopomofo.desktop</Filename>
37 + <Filename>ibus-setup-libpinyin.desktop</Filename>
38 + <Filename>ibus-setup-m17n.desktop</Filename>
39 + <Filename>ibus-setup-typing-booster.desktop</Filename>
40 + <Filename>im-chooser.desktop</Filename>
41 + <Filename>itweb-settings.desktop</Filename>
42 + <Filename>jhbuild.desktop</Filename>
43 + <Filename>javaws.desktop</Filename>
44 + <Filename>java-1.7.0-openjdk-jconsole.desktop</Filename>
45 + <Filename>java-1.7.0-openjdk-policytool.desktop</Filename>
46 + <Filename>log4j-chainsaw.desktop</Filename>
47 + <Filename>log4j-logfactor5.desktop</Filename>
48 + <Filename>nm-connection-editor.desktop</Filename>
49 + <Filename>orca.desktop</Filename>
50 + <Filename>setroubleshoot.desktop</Filename>
51 + <Filename>authconfig.desktop</Filename>
52 + <Filename>system-config-date.desktop</Filename>
53 + <Filename>system-config-firewall.desktop</Filename>
54 + <Filename>system-config-keyboard.desktop</Filename>
55 + <Filename>system-config-language.desktop</Filename>
56 + <Filename>system-config-printer.desktop</Filename>
57 + <Filename>system-config-users.desktop</Filename>
58 + <Filename>vino-preferences.desktop</Filename>
59 + </Or>
60 + </Not>
61 + </And>
62 + </Include>
63 + </Menu>
64 + <Menu>
65 + <Name>Administration</Name>
66 + <Directory>Settings-System.directory</Directory>
67 + <Include>
68 + <And>
69 + <Category>Settings</Category>
70 + <Category>System</Category>
71 + <Not>
72 + <Or>
73 + <Category>X-GNOME-Settings-Panel</Category>
74 + <Filename>alacarte.desktop</Filename>
75 + <Filename>caribou.desktop</Filename>
76 + <Filename>dconf-editor.desktop</Filename>
77 + <Filename>fedora-im-chooser.desktop</Filename>
78 + <Filename>fedora-release-notes.desktop</Filename>
79 + <Filename>firewall-config.desktop</Filename>
80 + <Filename>flash-player-properties.desktop</Filename>
81 + <Filename>gconf-editor.desktop</Filename>
82 + <Filename>gnome-abrt.desktop</Filename>
83 + <Filename>fedora-abrt.desktop</Filename>
84 + <Filename>gnome-orca.desktop</Filename>
85 + <Filename>gnome-power-statistics.desktop</Filename>
86 + <Filename>gnome-user-share-properties.desktop</Filename>
87 + <Filename>ibus.desktop</Filename>
88 + <Filename>ibus-daemon.desktop</Filename>
89 + <Filename>ibus-setup-anthy.desktop</Filename>
90 + <Filename>ibus-setup.desktop</Filename>
91 + <Filename>ibus-setup-hangul.desktop</Filename>
92 + <Filename>ibus-setup-libbopomofo.desktop</Filename>
93 + <Filename>ibus-setup-libpinyin.desktop</Filename>
94 + <Filename>ibus-setup-m17n.desktop</Filename>
95 + <Filename>ibus-setup-typing-booster.desktop</Filename>
96 + <Filename>im-chooser.desktop</Filename>
97 + <Filename>itweb-settings.desktop</Filename>
98 + <Filename>jhbuild.desktop</Filename>
99 + <Filename>javaws.desktop</Filename>
100 + <Filename>java-1.7.0-openjdk-jconsole.desktop</Filename>
101 + <Filename>java-1.7.0-openjdk-policytool.desktop</Filename>
102 + <Filename>log4j-chainsaw.desktop</Filename>
103 + <Filename>log4j-logfactor5.desktop</Filename>
104 + <Filename>nm-connection-editor.desktop</Filename>
105 + <Filename>orca.desktop</Filename>
106 + <Filename>setroubleshoot.desktop</Filename>
107 + <Filename>authconfig.desktop</Filename>
108 + <Filename>system-config-date.desktop</Filename>
109 + <Filename>system-config-firewall.desktop</Filename>
110 + <Filename>system-config-keyboard.desktop</Filename>
111 + <Filename>system-config-language.desktop</Filename>
112 + <Filename>system-config-printer.desktop</Filename>
113 + <Filename>system-config-users.desktop</Filename>
114 + <Filename>vino-preferences.desktop</Filename>
115 + </Or>
116 + </Not>
117 + </And>
118 + </Include>
119 + </Menu>
120 </Menu> <!-- End System Tools -->
121
122 <!-- System Settings -->
0 Description: Include Software Center in menus
1
2 Index: gnome-menus-3.8.0/layout/gnome-applications.menu
3 ===================================================================
4 --- gnome-menus-3.8.0.orig/layout/gnome-applications.menu 2013-06-04 18:22:04.293014377 -0400
5 +++ gnome-menus-3.8.0/layout/gnome-applications.menu 2013-06-04 18:22:04.293014377 -0400
6 @@ -325,4 +325,16 @@
7 <Merge type="files" />
8 </Layout>
9
10 +<Include>
11 + <Filename>ubuntu-software-center.desktop</Filename>
12 +</Include>
13 +
14 +<!-- Separator between menus and gnome-app-install -->
15 +<Layout>
16 + <Merge type="menus"/>
17 + <Merge type="files"/>
18 + <Separator/>
19 + <Filename>ubuntu-software-center.desktop</Filename>
20 +</Layout>
21 +
22 </Menu> <!-- End Applications -->
0 --- a/layout/gnome-applications.menu
1 +++ b/layout/gnome-applications.menu
2 @@ -99,8 +99,107 @@
3 <Include>
4 <And>
5 <Category>Game</Category>
6 - </And>
7 - </Include>
8 + <Not><Category>ActionGame</Category></Not>
9 + <Not><Category>AdventureGame</Category></Not>
10 + <Not><Category>ArcadeGame</Category></Not>
11 + <Not><Category>BoardGame</Category></Not>
12 + <Not><Category>BlocksGame</Category></Not>
13 + <Not><Category>CardGame</Category></Not>
14 + <Not><Category>KidsGame</Category></Not>
15 + <Not><Category>LogicGame</Category></Not>
16 + <Not><Category>Simulation</Category></Not>
17 + <Not><Category>SportsGame</Category></Not>
18 + <Not><Category>StrategyGame</Category></Not>
19 + </And>
20 + </Include>
21 + <DefaultLayout inline="true" inline_limit="6" inline_header="false">
22 + <Merge type="menus"/>
23 + <Merge type="files"/>
24 + </DefaultLayout>
25 + <Menu>
26 + <Name>Action</Name>
27 + <Directory>ActionGames.directory</Directory>
28 + <Include>
29 + <Category>ActionGame</Category>
30 + </Include>
31 + </Menu>
32 + <Menu>
33 + <Name>Adventure</Name>
34 + <Directory>AdventureGames.directory</Directory>
35 + <Include>
36 + <Category>AdventureGame</Category>
37 + </Include>
38 + </Menu>
39 + <Menu>
40 + <Name>Arcade</Name>
41 + <Directory>ArcadeGames.directory</Directory>
42 + <Include>
43 + <Category>ArcadeGame</Category>
44 + </Include>
45 + </Menu>
46 + <Menu>
47 + <Name>Board</Name>
48 + <Directory>BoardGames.directory</Directory>
49 + <Include>
50 + <Category>BoardGame</Category>
51 + </Include>
52 + </Menu>
53 + <Menu>
54 + <Name>Blocks</Name>
55 + <Directory>BlocksGames.directory</Directory>
56 + <Include>
57 + <Category>BlocksGame</Category>
58 + </Include>
59 + </Menu>
60 + <Menu>
61 + <Name>Cards</Name>
62 + <Directory>CardGames.directory</Directory>
63 + <Include>
64 + <Category>CardGame</Category>
65 + </Include>
66 + </Menu>
67 + <Menu>
68 + <Name>Kids</Name>
69 + <Directory>KidsGames.directory</Directory>
70 + <Include>
71 + <Category>KidsGame</Category>
72 + </Include>
73 + </Menu>
74 + <Menu>
75 + <Name>Logic</Name>
76 + <Directory>LogicGames.directory</Directory>
77 + <Include>
78 + <Category>LogicGame</Category>
79 + </Include>
80 + </Menu>
81 + <Menu>
82 + <Name>Role Playing</Name>
83 + <Directory>RolePlayingGames.directory</Directory>
84 + <Include>
85 + <Category>RolePlaying</Category>
86 + </Include>
87 + </Menu>
88 + <Menu>
89 + <Name>Simulation</Name>
90 + <Directory>SimulationGames.directory</Directory>
91 + <Include>
92 + <Category>Simulation</Category>
93 + </Include>
94 + </Menu>
95 + <Menu>
96 + <Name>Sports</Name>
97 + <Directory>SportsGames.directory</Directory>
98 + <Include>
99 + <Category>SportsGame</Category>
100 + </Include>
101 + </Menu>
102 + <Menu>
103 + <Name>Strategy</Name>
104 + <Directory>StrategyGames.directory</Directory>
105 + <Include>
106 + <Category>StrategyGame</Category>
107 + </Include>
108 + </Menu>
109 </Menu> <!-- End Games -->
110
111 <!-- Graphics -->
112 @@ -223,6 +322,7 @@
113 <And>
114 <Category>System</Category>
115 <Not><Category>Settings</Category></Not>
116 + <Not><Category>Game</Category></Not>
117 <Not><Filename>baobab.desktop</Filename></Not>
118 <Not><Filename>gnome-system-log.desktop</Filename></Not>
119 <Not><Filename>gnome-system-monitor.desktop</Filename></Not>
0 --- a/layout/gnome-applications.menu
1 +++ b/layout/gnome-applications.menu
2 @@ -88,10 +88,23 @@
3 <Include>
4 <And>
5 <Category>Education</Category>
6 + <Not><Category>Science</Category></Not>
7 </And>
8 </Include>
9 </Menu> <!-- End Education -->
10
11 + <!-- Science -->
12 + <Menu>
13 + <Name>Science</Name>
14 + <Directory>GnomeScience.directory</Directory>
15 + <Include>
16 + <And>
17 + <Category>Education</Category>
18 + <Category>Science</Category>
19 + </And>
20 + </Include>
21 + </Menu> <!-- End Science -->
22 +
23 <!-- Games -->
24 <Menu>
25 <Name>Games</Name>
26 --- a/desktop-directories/Education.directory.in
27 +++ b/desktop-directories/Education.directory.in
28 @@ -1,4 +1,4 @@
29 [Desktop Entry]
30 _Name=Education
31 -Icon=applications-science
32 +Icon=applications-accessories
33 Type=Directory
34 --- a/desktop-directories/Utility.directory.in
35 +++ b/desktop-directories/Utility.directory.in
36 @@ -1,5 +1,5 @@
37 [Desktop Entry]
38 _Name=Accessories
39 _Comment=Desktop accessories
40 -Icon=applications-accessories
41 +Icon=applications-utilities
42 Type=Directory
0 --- gnome-menus-2.19.6.orig/libmenu/desktop-entries.c 2007-07-30 22:06:51.000000000 +0200
1 +++ gnome-menus-2.19.6/libmenu/desktop-entries.c 2007-08-03 11:38:29.000000000 +0200
2 @@ -24,6 +24,7 @@
3 #include <string.h>
4
5 #include "menu-util.h"
6 +#include "user-is-sudoer.h"
7
8 #define DESKTOP_ENTRY_GROUP "Desktop Entry"
9 #define KDE_DESKTOP_ENTRY_GROUP "KDE Desktop Entry"
10 @@ -33,7 +34,8 @@
11 DESKTOP_ENTRY_NO_DISPLAY = 1 << 0,
12 DESKTOP_ENTRY_HIDDEN = 1 << 1,
13 DESKTOP_ENTRY_SHOW_IN_GNOME = 1 << 2,
14 - DESKTOP_ENTRY_TRYEXEC_FAILED = 1 << 3
15 + DESKTOP_ENTRY_TRYEXEC_FAILED = 1 << 3,
16 + DESKTOP_ENTRY_ROOT_REQUIRED = 1 << 4
17 };
18
19 struct DesktopEntry
20 @@ -50,7 +52,7 @@
21 gboolean terminal;
22
23 guint type : 2;
24 - guint flags : 4;
25 + guint flags : 5;
26 guint refcount : 24;
27 };
28
29 @@ -75,9 +77,20 @@
30 gboolean hidden;
31 gboolean show_in_gnome;
32 gboolean tryexec_failed;
33 + gboolean root_required_flag;
34 char *tryexec;
35 guint flags;
36 int i;
37 +
38 + static gboolean sudoer_flag_set = FALSE;
39 + static gboolean sudoer_flag = TRUE;
40 +
41 + /* If we don't know yet whether the user is sudoer or not, let's see */
42 + if (!sudoer_flag_set)
43 + {
44 + sudoer_flag = user_is_sudoer ();
45 + sudoer_flag_set = TRUE;
46 + }
47
48 error = NULL;
49 no_display = g_key_file_get_boolean (key_file,
50 @@ -157,6 +170,47 @@
51 g_free (tryexec);
52 }
53
54 + error = NULL;
55 + root_required_flag = g_key_file_get_boolean (key_file,
56 + desktop_entry_group,
57 + "X-KDE-SubstituteUID",
58 + &error);
59 +
60 + if (error)
61 + {
62 + root_required_flag = FALSE;
63 + g_error_free (error);
64 + }
65 + else {
66 + if (root_required_flag) {
67 + char *username = NULL;
68 + username = g_key_file_get_value (key_file,
69 + desktop_entry_group,
70 + "X-KDE-Username",
71 + NULL);
72 +
73 + if (!username || (username && !strcmp (username, "root")))
74 + root_required_flag = TRUE;
75 + else
76 + root_required_flag = FALSE;
77 + g_free (username);
78 + }
79 + else
80 + root_required_flag = FALSE;
81 + }
82 +
83 + /*
84 + * If the desktop entry has the field and indeed requires root
85 + * privilege and the user isn't sudoer, then the entry needs to be
86 + * hidden.
87 + */
88 +
89 + if (root_required_flag
90 + && (!sudoer_flag))
91 + {
92 + no_display = TRUE;
93 + }
94 +
95 flags = 0;
96 if (no_display)
97 flags |= DESKTOP_ENTRY_NO_DISPLAY;
98 @@ -166,6 +220,8 @@
99 flags |= DESKTOP_ENTRY_SHOW_IN_GNOME;
100 if (tryexec_failed)
101 flags |= DESKTOP_ENTRY_TRYEXEC_FAILED;
102 + if (root_required_flag)
103 + flags |= DESKTOP_ENTRY_ROOT_REQUIRED;
104
105 return flags;
106 }
107 @@ -297,13 +353,14 @@
108
109 #undef GET_LOCALE_STRING
110
111 - menu_verbose ("Desktop entry \"%s\" (%s, %s, %s) flags: NoDisplay=%s, Hidden=%s, ShowInGNOME=%s, TryExecFailed=%s\n",
112 + menu_verbose ("Desktop entry \"%s\" (%s, %s, %s) flags: NoDisplay=%s, Hidden=%s, RootRequired: %s, ShowInGNOME=%s, TryExecFailed=%s\n",
113 retval->basename,
114 retval->name,
115 retval->comment ? retval->comment : "(null)",
116 retval->icon ? retval->icon : "(null)",
117 retval->flags & DESKTOP_ENTRY_NO_DISPLAY ? "(true)" : "(false)",
118 retval->flags & DESKTOP_ENTRY_HIDDEN ? "(true)" : "(false)",
119 + retval->flags & DESKTOP_ENTRY_ROOT_REQUIRED ? "(true)" : "(false)",
120 retval->flags & DESKTOP_ENTRY_SHOW_IN_GNOME ? "(true)" : "(false)",
121 retval->flags & DESKTOP_ENTRY_TRYEXEC_FAILED ? "(true)" : "(false)");
122
123 --- gnome-menus-2.19.6.orig/libmenu/Makefile.am 2007-08-03 11:38:07.000000000 +0200
124 +++ gnome-menus-2.19.6/libmenu/Makefile.am 2007-08-03 11:38:29.000000000 +0200
125 @@ -35,6 +35,8 @@
126 menu-monitor-backend.h \
127 menu-util.c \
128 menu-util.h \
129 + user-is-sudoer.c \
130 + user-is-sudoer.h \
131 $(MONITOR_BACKEND_SOURCES) \
132 $(NULL)
133
134 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
135 +++ gnome-menus-2.19.6/libmenu/user-is-sudoer.c 2007-08-03 11:38:29.000000000 +0200
136 @@ -0,0 +1,58 @@
137 +/*
138 + * user-is-sudoer.c:
139 + *
140 + * Copyright (C) 2005 Manu Cornet
141 + *
142 + * This program is free software; you can redistribute it and/or
143 + * modify it under the terms of the GNU General Public License as
144 + * published by the Free Software Foundation; either version 2 of the
145 + * License, or (at your option) any later version.
146 + *
147 + * This program is distributed in the hope that it will be useful, but
148 + * WITHOUT ANY WARRANTY; without even the implied warranty of
149 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
150 + * General Public License for more details.
151 + *
152 + * You should have received a copy of the GNU General Public License
153 + * along with this program; if not, write to the Free Software
154 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
155 + * 02111-1307, USA.
156 + *
157 + * Authors:
158 + * Manu Cornet <manu@manucornet.net>
159 + */
160 +
161 +#include <glib.h>
162 +#include <string.h>
163 +#include <unistd.h>
164 +#include <sys/types.h>
165 +#include <grp.h>
166 +#include "user-is-sudoer.h"
167 +
168 +#define ADMIN_GROUP_NAME "admin"
169 +
170 +gboolean
171 +user_is_sudoer (void)
172 +{
173 + const gchar *user_name;
174 + int i = 0;
175 + struct group *group;
176 +
177 + if (getuid() == 0 || g_getenv ("USER_IS_ADMIN"))
178 + return TRUE;
179 +
180 + group = getgrnam (ADMIN_GROUP_NAME);
181 +
182 + if (!group)
183 + return TRUE;
184 + else {
185 + user_name = g_get_user_name ();
186 +
187 + while (group->gr_mem[i]) {
188 + if (!strcmp (user_name, group->gr_mem[i++]))
189 + return TRUE;
190 + }
191 + }
192 +
193 + return FALSE;
194 +}
195 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
196 +++ gnome-menus-2.19.6/libmenu/user-is-sudoer.h 2007-08-03 11:38:29.000000000 +0200
197 @@ -0,0 +1,20 @@
198 +/*
199 + * This library is free software; you can redistribute it and/or
200 + * modify it under the terms of the GNU Lesser General Public
201 + * License as published by the Free Software Foundation; either
202 + * version 2 of the License, or (at your option) any later version.
203 + *
204 + * This library is distributed in the hope that it will be useful,
205 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
206 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
207 + * Lesser General Public License for more details.
208 + *
209 + * You should have received a copy of the GNU Lesser General Public
210 + * License along with this library; if not, write to the
211 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
212 + * Boston, MA 02111-1307, USA.
213 + */
214 +
215 +#include <glib.h>
216 +
217 +gboolean user_is_sudoer (void);
0 Index: gnome-menus-3.7.90/desktop-directories/X-GNOME-SystemSettings.directory.in
1 ===================================================================
2 --- gnome-menus-3.7.90.orig/desktop-directories/X-GNOME-SystemSettings.directory.in 2013-02-15 20:48:56.000000000 -0500
3 +++ gnome-menus-3.7.90/desktop-directories/X-GNOME-SystemSettings.directory.in 2013-03-03 01:12:40.241503804 -0500
4 @@ -2,4 +2,3 @@
5 Name=System Settings
6 Icon=gnome-settings
7 Type=Directory
8 -NoDisplay=true
0 Index: gnome-menus-3.7.90/po/POTFILES.in
1 ===================================================================
2 --- gnome-menus-3.7.90.orig/po/POTFILES.in 2013-02-19 18:39:14.000000000 -0500
3 +++ gnome-menus-3.7.90/po/POTFILES.in 2013-03-03 00:59:16.629486723 -0500
4 @@ -15,3 +15,19 @@
5 desktop-directories/X-GNOME-Sundry.directory.in
6 desktop-directories/X-GNOME-Utilities.directory.in
7 desktop-directories/X-GNOME-WebApplications.directory.in
8 +debian/desktop-files/ActionGames.directory.in
9 +debian/desktop-files/AdventureGames.directory.in
10 +debian/desktop-files/ArcadeGames.directory.in
11 +debian/desktop-files/BlocksGames.directory.in
12 +debian/desktop-files/BoardGames.directory.in
13 +debian/desktop-files/CardGames.directory.in
14 +debian/desktop-files/Debian.directory.in
15 +debian/desktop-files/GnomeScience.directory.in
16 +debian/desktop-files/KidsGames.directory.in
17 +debian/desktop-files/LogicGames.directory.in
18 +debian/desktop-files/RolePlayingGames.directory.in
19 +debian/desktop-files/Settings-System.directory.in
20 +debian/desktop-files/Settings.directory.in
21 +debian/desktop-files/SimulationGames.directory.in
22 +debian/desktop-files/SportsGames.directory.in
23 +debian/desktop-files/StrategyGames.directory.in
0 From 599c7b05c432b1571a7105f1ebf6bbe30c36dbdf Mon Sep 17 00:00:00 2001
1 From: Kalev Lember <kalevlember@gmail.com>
2 Date: Thu, 28 Mar 2013 21:54:34 +0000
3 Subject: Adapt for gnome-calculator -> gcalctool desktop file rename
4
5 gnome-calculator.desktop was renamed back to gcalctool.desktop, at the
6 very last minute before the 3.8.0 release.
7
8 https://bugzilla.gnome.org/show_bug.cgi?id=696816
9 ---
10 diff --git a/layout/gnome-applications.menu b/layout/gnome-applications.menu
11 index 84d13ed..503f9ca 100644
12 --- a/layout/gnome-applications.menu
13 +++ b/layout/gnome-applications.menu
14 @@ -38,7 +38,6 @@
15 <Not><Filename>file-roller.desktop</Filename></Not>
16 <Not><Filename>gnome-file-roller.desktop</Filename></Not>
17 <Not><Filename>deja-dup-preferences.desktop</Filename></Not>
18 - <Not><Filename>gnome-calculator.desktop</Filename></Not>
19 <Not><Filename>gcalctool.desktop</Filename></Not>
20 <Not><Filename>gucharmap.desktop</Filename></Not>
21 <Not><Filename>gnome-gucharmap.desktop</Filename></Not>
22 @@ -251,7 +250,7 @@
23 <Directory>X-GNOME-Utilities.directory</Directory>
24 <Include>
25 <Filename>file-roller.desktop</Filename>
26 - <Filename>gnome-calculator.desktop</Filename>
27 + <Filename>gcalctool.desktop</Filename>
28 <Filename>gnome-font-viewer.desktop</Filename>
29 <Filename>gucharmap.desktop</Filename>
30 <Filename>seahorse.desktop</Filename>
31 @@ -287,7 +286,6 @@
32 <Not><Filename>gnome-eog.desktop</Filename></Not>
33 <Not><Filename>gnome-file-roller.desktop</Filename></Not>
34 <Not><Filename>gnome-gucharmap.desktop</Filename></Not>
35 - <Not><Filename>gcalctool.desktop</Filename></Not>
36 </And>
37 </Include>
38 </Menu> <!-- End Other -->
39
0 01_default_prefix.patch
1 02_kill_debian_menu.patch
2 03_kde-legacydirs.patch
3 08_settings-menus.patch
4 09_app_install_entry.patch
5 09_games-menu.patch
6 11_science-menu.patch
7 50_add-gcc-apps.patch
8 70_ubuntu-directories.patch
9 git_restore_calculator.patch
10 ubuntu_gcc_translations.patch
0 # Description: revert dropping of gnome-control-center categories, they got
1 # deprecated in g-c-c 3.8 but we are still using 3.6. We can drop those
2 # changes once we do the update.
3 # Ubuntu: https://bugs.launchpad.net/ubuntu/+source/gnome-menus/+bug/1232534
4 Index: gnome-menus-3.8.0/desktop-directories/Hardware.directory.in
5 ===================================================================
6 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
7 +++ gnome-menus-3.8.0/desktop-directories/Hardware.directory.in 2013-10-09 15:21:15.269679845 +0200
8 @@ -0,0 +1,5 @@
9 +[Desktop Entry]
10 +_Name=Hardware
11 +_Comment=Settings for several hardware devices
12 +Icon=preferences-desktop-peripherals
13 +Type=Directory
14 Index: gnome-menus-3.8.0/desktop-directories/Makefile.am
15 ===================================================================
16 --- gnome-menus-3.8.0.orig/desktop-directories/Makefile.am 2013-10-09 15:21:15.277679844 +0200
17 +++ gnome-menus-3.8.0/desktop-directories/Makefile.am 2013-10-09 15:21:15.269679845 +0200
18 @@ -1,5 +1,11 @@
19 directorydir = $(datadir)/desktop-directories
20
21 +# Should be moved to gnome-control-center:
22 +directory_in_controlcenterfiles = \
23 + Hardware.directory.in \
24 + Personal.directory.in \
25 + System.directory.in
26 +
27 directory_in_files = \
28 AudioVideo.directory.in \
29 Development.directory.in \
30 @@ -16,7 +22,8 @@
31 X-GNOME-Sundry.directory.in \
32 X-GNOME-Utilities.directory.in \
33 X-GNOME-WebApplications.directory.in \
34 - X-GNOME-SystemSettings.directory.in
35 + X-GNOME-SystemSettings.directory.in \
36 + $(directory_in_controlcenterfiles)
37
38 directory_DATA = $(directory_in_files:.directory.in=.directory)
39
40 Index: gnome-menus-3.8.0/desktop-directories/Makefile.in
41 ===================================================================
42 --- gnome-menus-3.8.0.orig/desktop-directories/Makefile.in 2013-10-09 15:21:15.277679844 +0200
43 +++ gnome-menus-3.8.0/desktop-directories/Makefile.in 2013-10-09 15:21:15.273679844 +0200
44 @@ -277,6 +277,13 @@
45 top_builddir = @top_builddir@
46 top_srcdir = @top_srcdir@
47 directorydir = $(datadir)/desktop-directories
48 +
49 +# Should be moved to gnome-control-center:
50 +directory_in_controlcenterfiles = \
51 + Hardware.directory.in \
52 + Personal.directory.in \
53 + System.directory.in
54 +
55 directory_in_files = \
56 AudioVideo.directory.in \
57 Development.directory.in \
58 @@ -293,7 +300,8 @@
59 X-GNOME-Sundry.directory.in \
60 X-GNOME-Utilities.directory.in \
61 X-GNOME-WebApplications.directory.in \
62 - X-GNOME-SystemSettings.directory.in
63 + X-GNOME-SystemSettings.directory.in \
64 + $(directory_in_controlcenterfiles)
65
66 directory_DATA = $(directory_in_files:.directory.in=.directory)
67 EXTRA_DIST = $(directory_in_files)
68 Index: gnome-menus-3.8.0/desktop-directories/Personal.directory.in
69 ===================================================================
70 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
71 +++ gnome-menus-3.8.0/desktop-directories/Personal.directory.in 2013-10-09 15:21:15.273679844 +0200
72 @@ -0,0 +1,6 @@
73 +[Desktop Entry]
74 +# Translators: this is Personal as in "Personal settings"
75 +_Name=Personal
76 +_Comment=Personal settings
77 +Icon=preferences-desktop-personal
78 +Type=Directory
79 Index: gnome-menus-3.8.0/desktop-directories/System.directory.in
80 ===================================================================
81 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
82 +++ gnome-menus-3.8.0/desktop-directories/System.directory.in 2013-10-09 15:21:15.273679844 +0200
83 @@ -0,0 +1,5 @@
84 +[Desktop Entry]
85 +_Name=System
86 +_Comment=System settings
87 +Icon=preferences-system
88 +Type=Directory
89 Index: gnome-menus-3.8.0/po/POTFILES.in
90 ===================================================================
91 --- gnome-menus-3.8.0.orig/po/POTFILES.in 2013-10-09 15:21:15.277679844 +0200
92 +++ gnome-menus-3.8.0/po/POTFILES.in 2013-10-09 15:21:15.273679844 +0200
93 @@ -31,3 +31,7 @@
94 debian/desktop-files/SimulationGames.directory.in
95 debian/desktop-files/SportsGames.directory.in
96 debian/desktop-files/StrategyGames.directory.in
97 +desktop-directories/Hardware.directory.in
98 +desktop-directories/Personal.directory.in
99 +desktop-directories/System.directory.in
100 +
0 #!/usr/bin/make -f
1
2 export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
3 DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
4 TYPELIBDIR=$(shell pkg-config gobject-introspection-1.0 --variable libdir | sed -e 's/.//')
5
6 %:
7 dh $@ --parallel --with=autoreconf,python3
8
9 override_dh_strip:
10 dh_strip --dbg-package=libcinnamon-menu-3-0-dbg
11
12 override_dh_install:
13 sed 's@TYPELIBDIR@${TYPELIBDIR}@' debian/gir1.2-cmenu-3.0.install.in > debian/gir1.2-cmenu-3.0.install
14 dh_install --list-missing
15
16 override_dh_auto_clean:
17 -dh_auto_clean
0 3.0 (native)
274274 const char *categories_str;
275275
276276 entry_desktop->appinfo = g_desktop_app_info_new_from_filename (entry->path);
277 if (!entry_desktop->appinfo ||
278 !g_app_info_get_name (G_APP_INFO (entry_desktop->appinfo)) ||
279 !g_app_info_get_executable (G_APP_INFO (entry_desktop->appinfo)))
277 if (!G_IS_DESKTOP_APP_INFO (((DesktopEntryDesktop*)entry)->appinfo))
280278 {
281279 menu_verbose ("Failed to load \"%s\"\n", entry->path);
282280 return DESKTOP_ENTRY_LOAD_FAIL_APPINFO;
572570 desktop_entry_get_name (DesktopEntry *entry)
573571 {
574572 if (entry->type == DESKTOP_ENTRY_DESKTOP)
575 return g_app_info_get_name (G_APP_INFO (((DesktopEntryDesktop*)entry)->appinfo));
573 {
574 g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (((DesktopEntryDesktop*)entry)->appinfo), NULL);
575 return g_app_info_get_name (G_APP_INFO (((DesktopEntryDesktop*)entry)->appinfo));
576 }
577
576578 return ((DesktopEntryDirectory*)entry)->name;
577579 }
578580
580582 desktop_entry_get_generic_name (DesktopEntry *entry)
581583 {
582584 if (entry->type == DESKTOP_ENTRY_DESKTOP)
583 return g_desktop_app_info_get_generic_name (((DesktopEntryDesktop*)entry)->appinfo);
585 {
586 g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (((DesktopEntryDesktop*)entry)->appinfo), NULL);
587 return g_desktop_app_info_get_generic_name (((DesktopEntryDesktop*)entry)->appinfo);
588 }
589
584590 return ((DesktopEntryDirectory*)entry)->generic_name;
585591 }
586592
588594 desktop_entry_get_comment (DesktopEntry *entry)
589595 {
590596 if (entry->type == DESKTOP_ENTRY_DESKTOP)
591 return g_app_info_get_description (G_APP_INFO (((DesktopEntryDesktop*)entry)->appinfo));
597 {
598 g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (((DesktopEntryDesktop*)entry)->appinfo), NULL);
599 return g_app_info_get_description (G_APP_INFO (((DesktopEntryDesktop*)entry)->appinfo));
600 }
601
592602 return ((DesktopEntryDirectory*)entry)->comment;
593603 }
594604
596606 desktop_entry_get_icon (DesktopEntry *entry)
597607 {
598608 if (entry->type == DESKTOP_ENTRY_DESKTOP)
599 return g_app_info_get_icon (G_APP_INFO (((DesktopEntryDesktop*)entry)->appinfo));
609 {
610 g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (((DesktopEntryDesktop*)entry)->appinfo), NULL);
611 return g_app_info_get_icon (G_APP_INFO (((DesktopEntryDesktop*)entry)->appinfo));
612 }
613
600614 return ((DesktopEntryDirectory*)entry)->icon;
601615 }
602616
604618 desktop_entry_get_no_display (DesktopEntry *entry)
605619 {
606620 if (entry->type == DESKTOP_ENTRY_DESKTOP)
607 return g_desktop_app_info_get_nodisplay (((DesktopEntryDesktop*)entry)->appinfo);
621 {
622 g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (((DesktopEntryDesktop*)entry)->appinfo), FALSE);
623 return g_desktop_app_info_get_nodisplay (((DesktopEntryDesktop*)entry)->appinfo);
624 }
625
608626 return ((DesktopEntryDirectory*)entry)->nodisplay;
609627 }
610628
612630 desktop_entry_get_hidden (DesktopEntry *entry)
613631 {
614632 if (entry->type == DESKTOP_ENTRY_DESKTOP)
615 return g_desktop_app_info_get_is_hidden (((DesktopEntryDesktop*)entry)->appinfo);
633 {
634 g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (((DesktopEntryDesktop*)entry)->appinfo), FALSE);
635 return g_desktop_app_info_get_is_hidden (((DesktopEntryDesktop*)entry)->appinfo);
636 }
637
616638 return ((DesktopEntryDirectory*)entry)->hidden;
617639 }
618640
352352 if (strcmp (desktop_entry_get_basename (tmp->data), basename) == 0)
353353 {
354354 if (!desktop_entry_reload (tmp->data))
355 {
356 dir->entries = g_slist_delete_link (dir->entries, tmp);
357 }
355 {
356 dir->entries = g_slist_delete_link (dir->entries, tmp);
357 }
358358
359359 return TRUE;
360360 }
362362 tmp = tmp->next;
363363 }
364364
365 return cached_dir_add_entry (dir, basename, path);
365 return FALSE;
366366 }
367367
368368 static gboolean
519519 cached_dir_queue_monitor_event (dir->parent);
520520 }
521521
522 if (monitors_idle_handler == 0)
523 {
524 monitors_idle_handler = g_idle_add ((GSourceFunc) emit_monitors_in_idle, NULL);
525 }
522 if (monitors_idle_handler > 0)
523 {
524 g_source_remove (monitors_idle_handler);
525 }
526
527 monitors_idle_handler = g_timeout_add (100, (GSourceFunc) emit_monitors_in_idle, NULL);
526528 }
527529
528530 static void
549551 switch (event)
550552 {
551553 case MENU_MONITOR_EVENT_CREATED:
554 handled = cached_dir_add_entry (dir, basename, path);
555 break;
552556 case MENU_MONITOR_EVENT_CHANGED:
553557 handled = cached_dir_update_entry (dir, basename, path);
554558 break;
145145 {
146146 pending_events = g_slist_append (pending_events, event_info);
147147
148 if (events_idle_handler == 0)
149 {
150 events_idle_handler = g_idle_add ((GSourceFunc) emit_events_in_idle, NULL);
151 }
148 if (events_idle_handler > 0)
149 {
150 g_source_remove (events_idle_handler);
151 }
152
153 events_idle_handler = g_timeout_add (100, (GSourceFunc) emit_events_in_idle, NULL);
152154 }
153155
154156 static inline char *