Hello community,
here is the log from the commit of package cinnamon-menus for openSUSE:Factory checked in at 2016-05-29 03:11:47
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/cinnamon-menus (Old)
and /work/SRC/openSUSE:Factory/.cinnamon-menus.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cinnamon-menus"
Changes:
--------
--- /work/SRC/openSUSE:Factory/cinnamon-menus/cinnamon-menus.changes 2016-04-28 17:01:20.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.cinnamon-menus.new/cinnamon-menus.changes 2016-05-29 03:12:56.000000000 +0200
@@ -1,0 +2,12 @@
+Tue May 24 16:25:54 UTC 2016 - sor.alexei@meowr.ru
+
+- Update to version 3.0.1:
+ * 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).
+ * 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.
+
+-------------------------------------------------------------------
Old:
----
cinnamon-menus-3.0.0.tar.gz
New:
----
cinnamon-menus-3.0.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ cinnamon-menus.spec ++++++
--- /var/tmp/diff_new_pack.Iuk1CA/_old 2016-05-29 03:12:57.000000000 +0200
+++ /var/tmp/diff_new_pack.Iuk1CA/_new 2016-05-29 03:12:57.000000000 +0200
@@ -20,7 +20,7 @@
%define soname libcinnamon-menu-3
%define sover 0
Name: cinnamon-menus
-Version: 3.0.0
+Version: 3.0.1
Release: 0
Summary: A menu system for the Cinnamon Desktop
License: LGPL-2.1+
++++++ cinnamon-menus-3.0.0.tar.gz -> cinnamon-menus-3.0.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinnamon-menus-3.0.0/configure.ac new/cinnamon-menus-3.0.1/configure.ac
--- old/cinnamon-menus-3.0.0/configure.ac 2016-04-23 16:57:07.000000000 +0200
+++ new/cinnamon-menus-3.0.1/configure.ac 2016-05-23 13:55:09.000000000 +0200
@@ -1,6 +1,6 @@
AC_PREREQ(2.62)
-AC_INIT([cinnamon-menus], [3.0.0])
+AC_INIT([cinnamon-menus], [3.0.1])
AC_CONFIG_SRCDIR(libmenu/gmenu-tree.h)
AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinnamon-menus-3.0.0/debian/changelog new/cinnamon-menus-3.0.1/debian/changelog
--- old/cinnamon-menus-3.0.0/debian/changelog 2016-04-23 16:57:07.000000000 +0200
+++ new/cinnamon-menus-3.0.1/debian/changelog 2016-05-23 13:55:09.000000000 +0200
@@ -1,3 +1,12 @@
+cinnamon-menus (3.0.1) sarah; urgency=medium
+
+ [ Michael Webster ]
+ * 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.
+ * Follow-up to previous commit - retry only those desktop files that failed because of appinfo problems.
+ * 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.
+
+ -- Clement Lefebvre Mon, 23 May 2016 12:54:12 +0100
+
cinnamon-menus (3.0.0) sarah; urgency=medium
[ monsta ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinnamon-menus-3.0.0/libmenu/desktop-entries.c new/cinnamon-menus-3.0.1/libmenu/desktop-entries.c
--- old/cinnamon-menus-3.0.0/libmenu/desktop-entries.c 2016-04-23 16:57:07.000000000 +0200
+++ new/cinnamon-menus-3.0.1/libmenu/desktop-entries.c 2016-05-23 13:55:09.000000000 +0200
@@ -263,72 +263,89 @@
return TRUE;
}
-static gboolean
+static DesktopEntryResultCode
desktop_entry_load (DesktopEntry *entry)
{
+ DesktopEntryResultCode rescode = DESKTOP_ENTRY_LOAD_FAIL_OTHER;
+
if (strstr (entry->path, "/menu-xdg/"))
- return FALSE;
+ return rescode;
+
if (entry->type == DESKTOP_ENTRY_DESKTOP)
{
GKeyFile *key_file = NULL;
DesktopEntryDesktop *entry_desktop = (DesktopEntryDesktop*)entry;
- const char *categories_str;
- entry_desktop->appinfo = g_desktop_app_info_new_from_filename (entry->path);
- if (!entry_desktop->appinfo ||
- !g_app_info_get_name (G_APP_INFO (entry_desktop->appinfo)) ||
- !g_app_info_get_executable (G_APP_INFO (entry_desktop->appinfo)))
- {
- menu_verbose ("Failed to load \"%s\"\n", entry->path);
- return FALSE;
- }
+ key_file = g_key_file_new ();
- categories_str = g_desktop_app_info_get_categories (entry_desktop->appinfo);
- if (categories_str)
+ if (g_key_file_load_from_file (key_file, entry->path, 0, NULL))
{
- char **categories;
- int i;
+ entry_desktop->appinfo = g_desktop_app_info_new_from_keyfile (key_file);
- categories = g_strsplit (categories_str, ";", -1);
- entry_desktop->categories = g_new0 (GQuark, g_strv_length (categories) + 1);
+ if (!entry_desktop->appinfo ||
+ !g_app_info_get_name (G_APP_INFO (entry_desktop->appinfo)) ||
+ !g_app_info_get_executable (G_APP_INFO (entry_desktop->appinfo)))
+ {
+ menu_verbose ("Failed to load appinfo for \"%s\"\n", entry->path);
+ rescode = DESKTOP_ENTRY_LOAD_FAIL_APPINFO;
+ }
+ else
+ {
+ const char *categories_str;
+ categories_str = g_desktop_app_info_get_categories (entry_desktop->appinfo);
- for (i = 0; categories[i]; i++)
- entry_desktop->categories[i] = g_quark_from_string (categories[i]);
+ if (categories_str)
+ {
+ char **categories;
+ int i;
- g_strfreev (categories);
- }
+ categories = g_strsplit (categories_str, ";", -1);
+ entry_desktop->categories = g_new0 (GQuark, g_strv_length (categories) + 1);
- key_file = g_key_file_new ();
+ for (i = 0; categories[i]; i++)
+ entry_desktop->categories[i] = g_quark_from_string (categories[i]);
- if (!g_key_file_load_from_file (key_file, entry->path, 0, NULL))
- entry_desktop->showin = TRUE;
- else
- entry_desktop->showin = key_file_get_show_in (key_file);
+ g_strfreev (categories);
+ }
- g_key_file_free (key_file);
+ entry_desktop->showin = key_file_get_show_in (key_file);
- return TRUE;
+ rescode = DESKTOP_ENTRY_LOAD_SUCCESS;
+ }
+ }
+ else
+ {
+ menu_verbose ("Failed to read contents of \"%s\"\n", entry->path);
+ rescode = DESKTOP_ENTRY_LOAD_FAIL_OTHER;
+ }
+ g_key_file_free (key_file);
}
else if (entry->type == DESKTOP_ENTRY_DIRECTORY)
{
GKeyFile *key_file = NULL;
GError *error = NULL;
- gboolean retval = FALSE;
+ rescode = DESKTOP_ENTRY_LOAD_SUCCESS;
key_file = g_key_file_new ();
if (!g_key_file_load_from_file (key_file, entry->path, 0, &error))
- goto out;
+ {
+ rescode = DESKTOP_ENTRY_LOAD_FAIL_OTHER;
+ goto out;
+ }
if (!desktop_entry_load_directory (entry, key_file, &error))
- goto out;
+ {
+ rescode = DESKTOP_ENTRY_LOAD_FAIL_OTHER;
+ goto out;
+ }
- retval = TRUE;
+ rescode = DESKTOP_ENTRY_LOAD_SUCCESS;
out:
g_key_file_free (key_file);
- if (!retval)
+ if (rescode == DESKTOP_ENTRY_LOAD_FAIL_OTHER)
{
if (error)
{
@@ -338,20 +355,27 @@
else
menu_verbose ("Failed to load \"%s\"\n", entry->path);
}
-
- return retval;
}
else
g_assert_not_reached ();
- return FALSE;
+ return rescode;
+}
+
+static gboolean
+code_failed (DesktopEntryResultCode code)
+{
+ return code == DESKTOP_ENTRY_LOAD_FAIL_OTHER ||
+ code == DESKTOP_ENTRY_LOAD_FAIL_APPINFO;
}
DesktopEntry *
-desktop_entry_new (const char *path)
+desktop_entry_new (const char *path,
+ DesktopEntryResultCode *res_code)
{
DesktopEntryType type;
DesktopEntry *retval;
+ DesktopEntryResultCode code;
menu_verbose ("Loading desktop entry \"%s\"\n", path);
@@ -369,6 +393,7 @@
{
menu_verbose ("Unknown desktop entry suffix in \"%s\"\n",
path);
+ *res_code = DESKTOP_ENTRY_LOAD_FAIL_OTHER;
return NULL;
}
@@ -377,7 +402,10 @@
retval->path = g_strdup (path);
retval->basename = unix_basename_from_path (retval->path);
- if (!desktop_entry_load (retval))
+ code = desktop_entry_load (retval);
+ *res_code = code;
+
+ if (code_failed (code))
{
desktop_entry_unref (retval);
return NULL;
@@ -419,7 +447,7 @@
else
g_assert_not_reached ();
- if (!desktop_entry_load (entry))
+ if (code_failed (desktop_entry_load (entry)))
{
desktop_entry_unref (entry);
return NULL;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinnamon-menus-3.0.0/libmenu/desktop-entries.h new/cinnamon-menus-3.0.1/libmenu/desktop-entries.h
--- old/cinnamon-menus-3.0.0/libmenu/desktop-entries.h 2016-04-23 16:57:07.000000000 +0200
+++ new/cinnamon-menus-3.0.1/libmenu/desktop-entries.h 2016-05-23 13:55:09.000000000 +0200
@@ -31,9 +31,17 @@
DESKTOP_ENTRY_DIRECTORY
} DesktopEntryType;
+typedef enum
+{
+ DESKTOP_ENTRY_LOAD_SUCCESS = 0,
+ DESKTOP_ENTRY_LOAD_FAIL_OTHER,
+ DESKTOP_ENTRY_LOAD_FAIL_APPINFO
+} DesktopEntryResultCode;
+
typedef struct DesktopEntry DesktopEntry;
-DesktopEntry *desktop_entry_new (const char *path);
+DesktopEntry *desktop_entry_new (const char *path,
+ DesktopEntryResultCode *res_code);
DesktopEntry *desktop_entry_ref (DesktopEntry *entry);
DesktopEntry *desktop_entry_copy (DesktopEntry *entry);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinnamon-menus-3.0.0/libmenu/entry-directories.c new/cinnamon-menus-3.0.1/libmenu/entry-directories.c
--- old/cinnamon-menus-3.0.0/libmenu/entry-directories.c 2016-04-23 16:57:07.000000000 +0200
+++ new/cinnamon-menus-3.0.1/libmenu/entry-directories.c 2016-05-23 13:55:09.000000000 +0200
@@ -57,6 +57,7 @@
GSList *entries;
GSList *subdirs;
+ GSList *retry_later_desktop_entries;
MenuMonitor *dir_monitor;
GSList *monitors;
@@ -161,6 +162,9 @@
g_slist_free (dir->subdirs);
dir->subdirs = NULL;
+ g_slist_free_full (dir->retry_later_desktop_entries, g_free);
+ dir->retry_later_desktop_entries = NULL;
+
g_free (dir->name);
g_free (dir);
}
@@ -314,10 +318,20 @@
const char *path)
{
DesktopEntry *entry;
+ DesktopEntryResultCode code;
- entry = desktop_entry_new (path);
+ entry = desktop_entry_new (path, &code);
if (entry == NULL)
- return FALSE;
+ {
+ if (code == DESKTOP_ENTRY_LOAD_FAIL_APPINFO)
+ {
+ menu_verbose ("Adding %s to the retry list (mimeinfo.cache maybe isn't done getting updated yet\n", path);
+
+ dir->retry_later_desktop_entries = g_slist_prepend (dir->retry_later_desktop_entries, g_strdup (path));
+ }
+
+ return FALSE;
+ }
dir->entries = g_slist_prepend (dir->entries, entry);
@@ -525,6 +539,8 @@
CachedDir *dir)
{
gboolean handled = FALSE;
+ gboolean retry_changes = FALSE;
+
char *basename;
char *dirname;
@@ -558,6 +574,58 @@
break;
}
}
+ else if (g_strcmp0 (basename, "mimeinfo.cache") == 0)
+ {
+ /* The observed file notifies when a new desktop file is added
+ * (but fails to load) go something like:
+ *
+ * NOTIFY: foo.desktop
+ * NOTIFY: mimeinfo.cache.tempfile
+ * NOTIFY: mimeinfo.cache.tempfile
+ * NOTIFY: mimeinfo.cache
+ *
+ * Additionally, the failure is not upon trying to read the file,
+ * but attempting to get its GAppInfo (g_desktop_app_info_new_from_filename()
+ * in desktop-entries.c ln 277). If you jigger desktop_entry_load() around
+ * and read the file as a keyfile *first*, it succeeds. If you then try
+ * to run g_desktop_app_info_new_from_keyfile(), *then* it fails.
+ *
+ * The theory here is there is a race condition where app info (which includes
+ * mimetype stuff) is unavailable because mimeinfo.cache is updated immediately
+ * after the app is installed.
+ *
+ * What we do here is, when a desktop fails to load, we add it to a temporary
+ * list. We wait until mimeinfo.cache changes, then retry that desktop file,
+ * which succeeds this second time.
+ *
+ * Note: An alternative fix (presented more as a proof than a suggestion) is to
+ * change line 151 in menu-monitor.c to use g_timeout_add_seconds, and delay
+ * for one second. This also avoids the issue (but it remains a race condition).
+ */
+
+ GSList *iter;
+
+ menu_verbose ("mimeinfo changed, checking for failed entries\n");
+
+ for (iter = dir->retry_later_desktop_entries; iter != NULL; iter = iter->next)
+ {
+ const gchar *retry_path = iter->data;
+
+ menu_verbose ("retrying %s\n", retry_path);
+
+ char *retry_basename = g_path_get_basename (retry_path);
+
+ if (cached_dir_update_entry (dir, retry_basename, retry_path))
+ retry_changes = TRUE;
+
+ g_free (retry_basename);
+ }
+
+ g_slist_free_full (dir->retry_later_desktop_entries, g_free);
+ dir->retry_later_desktop_entries = NULL;
+
+ handled = retry_changes;
+ }
else /* Try recursing */
{
switch (event)
@@ -584,8 +652,8 @@
if (handled)
{
- /* CHANGED events don't change the set of desktop entries */
- if (event == MENU_MONITOR_EVENT_CREATED || event == MENU_MONITOR_EVENT_DELETED)
+ /* CHANGED events don't change the set of desktop entries, unless it's the mimeinfo.cache file changing */
+ if (retry_changes || (event == MENU_MONITOR_EVENT_CREATED || event == MENU_MONITOR_EVENT_DELETED))
{
_entry_directory_list_empty_desktop_cache ();
}