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 - [email protected]
+
+- 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 <[email protected]>  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 ();
         }


Reply via email to