~ubuntu-branches/ubuntu/oneiric/gnome-menus/oneiric-201106291711

« back to all changes in this revision

Viewing changes to libmenu/entry-directories.c

  • Committer: Bazaar Package Importer
  • Author(s): Rodrigo Moya, Josselin Mouette, Rodrigo Moya
  • Date: 2011-05-16 12:24:57 UTC
  • mfrom: (1.1.55 upstream) (2.1.14 experimental)
  • Revision ID: james.westby@ubuntu.com-20110516122457-xsdc47g3cj6d3cra
Tags: 3.0.0-0ubuntu1
[ Josselin Mouette ]
* Break alacarte < 0.13.2-2 (version without support for 
  settings.menu).

[ Rodrigo Moya ]
* Rebase on Debian, remaining Ubuntu changes:
* debian/control:
  - Use Standards-Version: 3.8.4
  - Depends: python-xdg for update-gnome-menus-cache
  - Add python-gmenu-dbg package
* debian/gnome-menus.triggers:
  - Add gmenucache trigger
* debian/gnome-menus.postinst:
  - Disable blacklist to not break old applications
* debian/update-gnome-menus-cache:
  - Script to update the menu cache
* debian/python-gmenu.postinst:
  - Add code to generate the menu cache
* debian/patches/06_menus_rename.patch:
  - Rename applications.menu to gnome-applications.menu
* debian/patches/09_app_install_entry.patch:
  - Include Software Center in menus
* debian/patches/22_desktop-cache.patch:
  - Support a desktop.<localename>.cache file in e. g.
    /usr/share/applications/ to speed up menu loading. Those
    are generated with update-gnome-menus-cache <dir>.
* debian/patches/23_add_inherited_gnome_session.patch:
  - Add inherited GNOME session
* debian/patches/*:
  - Add missing descriptions to Ubuntu-specific patches
* debian/patches/series:
  - Disable 01_default_prefix.patch, which is Debian specific

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#include <errno.h>
26
26
#include <sys/types.h>
27
27
#include <dirent.h>
 
28
#include <locale.h>
28
29
 
29
30
#include "menu-util.h"
30
31
#include "menu-monitor.h"
74
75
  gpointer                   user_data;
75
76
};
76
77
 
 
78
static void     cached_dir_add_reference          (CachedDir *dir);
 
79
static void     cached_dir_remove_reference       (CachedDir *dir);
77
80
static void     cached_dir_free                   (CachedDir  *dir);
78
81
static gboolean cached_dir_load_entries_recursive (CachedDir  *dir,
79
82
                                                   const char *dirname);
261
264
}
262
265
 
263
266
static gboolean
 
267
cached_dir_add_keyfile_entry (CachedDir  *dir,
 
268
                              GKeyFile   *keyfile,
 
269
                              const char *group,
 
270
                              const char *path)
 
271
{
 
272
  DesktopEntry *entry;
 
273
  gchar **dirsplit;
 
274
 
 
275
  entry = desktop_entry_new_from_keyfile (keyfile, group, path);
 
276
  if (entry == NULL)
 
277
    return FALSE;
 
278
 
 
279
  /* subdirectory? */
 
280
  dirsplit = g_strsplit (group, "/", 2);
 
281
  if (dirsplit[1] == NULL)
 
282
    dir->entries = g_slist_prepend (dir->entries, entry);
 
283
  else 
 
284
    {
 
285
      CachedDir *subdir;
 
286
      subdir = find_subdir (dir, dirsplit[0]);
 
287
      if (subdir == NULL)
 
288
        {
 
289
          subdir = cached_dir_new(dirsplit[0]);
 
290
          subdir->parent = dir;
 
291
          dir->subdirs = g_slist_prepend (dir->subdirs, subdir);
 
292
        }
 
293
 
 
294
      subdir->entries = g_slist_prepend (subdir->entries, entry);
 
295
    }
 
296
 
 
297
  g_strfreev (dirsplit);
 
298
 
 
299
  return TRUE;
 
300
}
 
301
 
 
302
static gboolean
264
303
cached_dir_update_entry (CachedDir  *dir,
265
304
                         const char *basename,
266
305
                         const char *path)
363
402
  return FALSE;
364
403
}
365
404
 
 
405
static guint   monitors_idle_handler = 0;
 
406
static GSList *pending_monitors_dirs = NULL;
 
407
 
366
408
static void
367
409
cached_dir_invoke_monitors (CachedDir *dir)
368
410
{
379
421
      tmp = next;
380
422
    }
381
423
 
 
424
  /* we explicitly don't invoke monitors of the parent since an
 
425
   * event has been queued for it too */
 
426
}
 
427
 
 
428
static gboolean
 
429
emit_monitors_in_idle (void)
 
430
{
 
431
  GSList *monitors_to_emit;
 
432
  GSList *tmp;
 
433
 
 
434
  monitors_to_emit = pending_monitors_dirs;
 
435
 
 
436
  pending_monitors_dirs = NULL;
 
437
  monitors_idle_handler = 0;
 
438
 
 
439
  tmp = monitors_to_emit;
 
440
  while (tmp != NULL)
 
441
    {
 
442
      CachedDir *dir = tmp->data;
 
443
 
 
444
      cached_dir_invoke_monitors (dir);
 
445
      cached_dir_remove_reference (dir);
 
446
 
 
447
      tmp = tmp->next;
 
448
    }
 
449
 
 
450
  g_slist_free (monitors_to_emit);
 
451
 
 
452
  return FALSE;
 
453
}
 
454
 
 
455
static void
 
456
cached_dir_queue_monitor_event (CachedDir *dir)
 
457
{
 
458
  GSList *tmp;
 
459
 
 
460
  tmp = pending_monitors_dirs;
 
461
  while (tmp != NULL)
 
462
    {
 
463
      CachedDir *d    = tmp->data;
 
464
      GSList    *next = tmp->next;
 
465
 
 
466
      if (dir->parent == d->parent &&
 
467
          g_strcmp0 (dir->name, d->name) == 0)
 
468
        break;
 
469
 
 
470
      tmp = next;
 
471
    }
 
472
 
 
473
  /* not found, so let's queue it */
 
474
  if (tmp == NULL)
 
475
    {
 
476
      cached_dir_add_reference (dir);
 
477
      pending_monitors_dirs = g_slist_append (pending_monitors_dirs, dir);
 
478
    }
 
479
 
382
480
  if (dir->parent)
383
481
    {
384
 
      cached_dir_invoke_monitors (dir->parent);
 
482
      cached_dir_queue_monitor_event (dir->parent);
 
483
    }
 
484
 
 
485
  if (monitors_idle_handler == 0)
 
486
    {
 
487
      monitors_idle_handler = g_idle_add ((GSourceFunc) emit_monitors_in_idle, NULL);
385
488
    }
386
489
}
387
490
 
457
560
          _entry_directory_list_empty_desktop_cache ();
458
561
        }
459
562
 
460
 
      cached_dir_invoke_monitors (dir);
 
563
      cached_dir_queue_monitor_event (dir);
461
564
    }
462
565
}
463
566
 
475
578
}
476
579
 
477
580
static gboolean
 
581
cached_dir_load_entries_from_cache_file (CachedDir *dir, 
 
582
                                         const char *dirname)
 
583
{
 
584
  gchar                cache_file[PATH_MAX];
 
585
  char                 *locale, *s;
 
586
  GKeyFile             *kf;
 
587
  gchar                **names;
 
588
  gchar                **i;
 
589
 
 
590
  /* ignore cache if we have $LANGUAGE */
 
591
  locale = g_getenv ("LANGUAGE");
 
592
  if (locale != NULL && *locale != '\0')
 
593
    {
 
594
      menu_verbose ("cached_dir_load_entries_from_cache_file(): $LANGUAGE present, not using cache\n");
 
595
      return FALSE;
 
596
    }
 
597
 
 
598
  locale = g_strdup (setlocale (LC_MESSAGES, NULL));
 
599
  if (locale == NULL)
 
600
    {
 
601
      menu_verbose ("cached_dir_load_entries_from_cache_file(): setlocale() failed, aborting\n");
 
602
      return FALSE;
 
603
    }
 
604
 
 
605
  /* canonicalize .UTF-8 to .utf8 (only happens at end of string) */
 
606
  s = strstr (locale, ".UTF-8");
 
607
  if (s != NULL)
 
608
      strcpy (s, ".utf8");
 
609
 
 
610
  g_snprintf (cache_file, sizeof(cache_file), "%s/desktop.%s.cache", dirname, locale);
 
611
  g_free (locale);
 
612
 
 
613
  menu_verbose ("Attempting to read entries from cache file %s\n",
 
614
                cache_file);
 
615
  
 
616
  kf = g_key_file_new ();
 
617
  if (!g_key_file_load_from_file (kf, cache_file, G_KEY_FILE_NONE, NULL))
 
618
    return FALSE;
 
619
 
 
620
  names = g_key_file_get_groups(kf, NULL);
 
621
  for (i = names; *i != NULL; ++i)
 
622
      cached_dir_add_keyfile_entry (dir, kf, *i, dirname);
 
623
 
 
624
  g_strfreev (names);
 
625
  g_key_file_free (kf);
 
626
 
 
627
  return TRUE;
 
628
}
 
629
 
 
630
static gboolean
478
631
cached_dir_load_entries_recursive (CachedDir  *dir,
479
632
                                   const char *dirname)
480
633
{
491
644
  menu_verbose ("Attempting to read entries from %s (full path %s)\n",
492
645
                dir->name, dirname);
493
646
 
 
647
  if (cached_dir_load_entries_from_cache_file (dir, dirname))
 
648
    {
 
649
      menu_verbose ("Got from file cache\n");
 
650
      cached_dir_ensure_monitor (dir, dirname);
 
651
      dir->have_read_entries = TRUE;
 
652
      return TRUE;
 
653
    }
 
654
 
494
655
  dp = opendir (dirname);
495
656
  if (dp == NULL)
496
657
    {