[Xfce4-commits] <garcon:jannis/basic-monitoring> Add garcon_menu_item_cache_invalidate_file, simplify app dir monitoring.

Jannis Pohlmann noreply at xfce.org
Sun Sep 5 21:36:01 CEST 2010


Updating branch refs/heads/jannis/basic-monitoring
         to 2be335a2c9332d9b2c9f649245a764afb7140257 (commit)
       from 60460406ec33394222f3f624f99d0ea46c3704fa (commit)

commit 2be335a2c9332d9b2c9f649245a764afb7140257
Author: Jannis Pohlmann <jannis at xfce.org>
Date:   Sun Sep 5 21:32:37 2010 +0200

    Add garcon_menu_item_cache_invalidate_file, simplify app dir monitoring.
    
    Only listen to G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT events, otherwise
    consecutive events may not be picked up. A good example is when a
    desktop entry is edited and saved in VIM. This results in a series of
    events (move, create, change etc.). Some of these will not be picked up
    if garcon is busy reloading the menu at the time of their emission.
    
    So, the only real choice we have is to hope that CHANGES_DONE_HINT is
    always generated at the end of modifications like move, create, delete
    and attribute changes.

 garcon/garcon-menu-item-cache.c |   25 ++++++++
 garcon/garcon-menu-item-cache.h |   24 ++++---
 garcon/garcon-menu-parser.c     |    6 +-
 garcon/garcon-menu.c            |  131 +++++++++++++--------------------------
 4 files changed, 86 insertions(+), 100 deletions(-)

diff --git a/garcon/garcon-menu-item-cache.c b/garcon/garcon-menu-item-cache.c
index afccfd0..8d7e131 100644
--- a/garcon/garcon-menu-item-cache.c
+++ b/garcon/garcon-menu-item-cache.c
@@ -219,3 +219,28 @@ garcon_menu_item_cache_invalidate (GarconMenuItemCache *cache)
   /* Release item cache lock */
   g_static_mutex_unlock (&lock);
 }
+
+
+
+void
+garcon_menu_item_cache_invalidate_file (GarconMenuItemCache *cache,
+                                        GFile               *file)
+{
+  gchar *uri;
+
+  g_return_if_fail (GARCON_IS_MENU_ITEM_CACHE (cache));
+  g_return_if_fail (G_IS_FILE (file));
+
+  uri = g_file_get_uri (file);
+
+  /* Acquire a lock on the item cache */
+  g_static_mutex_lock (&lock);
+
+  /* Remove possible items with this URI from the cache */
+  g_hash_table_remove (cache->priv->items, uri);
+
+  /* Release the item cache lock */
+  g_static_mutex_unlock (&lock);
+
+  g_free (uri);
+}
diff --git a/garcon/garcon-menu-item-cache.h b/garcon/garcon-menu-item-cache.h
index 1e8bbb6..8ed6646 100644
--- a/garcon/garcon-menu-item-cache.h
+++ b/garcon/garcon-menu-item-cache.h
@@ -56,17 +56,19 @@ struct _GarconMenuItemCache
 
 
 
-GType                garcon_menu_item_cache_get_type    (void) G_GNUC_CONST;
-
-GarconMenuItemCache *garcon_menu_item_cache_get_default (void);
-
-GarconMenuItem      *garcon_menu_item_cache_lookup      (GarconMenuItemCache *cache,
-                                                         const gchar         *uri,
-                                                         const gchar         *desktop_id);
-void                 garcon_menu_item_cache_foreach     (GarconMenuItemCache *cache,
-                                                         GHFunc               func,
-                                                         gpointer             user_data);
-void                 garcon_menu_item_cache_invalidate  (GarconMenuItemCache *cache);
+GType                garcon_menu_item_cache_get_type        (void) G_GNUC_CONST;
+
+GarconMenuItemCache *garcon_menu_item_cache_get_default     (void);
+
+GarconMenuItem      *garcon_menu_item_cache_lookup          (GarconMenuItemCache *cache,
+                                                             const gchar         *uri,
+                                                             const gchar         *desktop_id);
+void                 garcon_menu_item_cache_foreach         (GarconMenuItemCache *cache,
+                                                             GHFunc               func,
+                                                             gpointer             user_data);
+void                 garcon_menu_item_cache_invalidate      (GarconMenuItemCache *cache);
+void                 garcon_menu_item_cache_invalidate_file (GarconMenuItemCache *cache,
+                                                             GFile               *file);
 
 G_END_DECLS
 
diff --git a/garcon/garcon-menu-parser.c b/garcon/garcon-menu-parser.c
index bc939dd..2d8f088 100644
--- a/garcon/garcon-menu-parser.c
+++ b/garcon/garcon-menu-parser.c
@@ -275,12 +275,14 @@ garcon_menu_parser_run (GarconMenuParser *parser,
 
       if (error != NULL)
         {
-          g_warning (_("Could not load menu file data from %s: %s"),
+          g_message (_("Could not load menu file data from %s: %s"),
                      uri, (*error)->message);
           g_error_free (*error);
         }
       else
-        g_warning (_("Could not load menu file data from %s"), uri);
+        {
+          g_message (_("Could not load menu file data from %s"), uri);
+        }
 
       g_free (uri);
       return FALSE;
diff --git a/garcon/garcon-menu.c b/garcon/garcon-menu.c
index bc731da..4f40c2e 100644
--- a/garcon/garcon-menu.c
+++ b/garcon/garcon-menu.c
@@ -2115,119 +2115,76 @@ garcon_menu_app_dir_changed (GarconMenu       *menu,
   g_return_if_fail (GARCON_IS_MENU (menu));
   g_return_if_fail (menu->priv->parent == NULL);
 
-  if (event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT
-      || event_type == G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED)
+  if (event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT)
     {
       /* query the type of the changed file */
       file_type = g_file_query_file_type (file, G_FILE_QUERY_INFO_NONE, NULL);
 
       if (file_type == G_FILE_TYPE_DIRECTORY)
         {
-          /* in this situation, an app dir could have become unreadable for the
-           * current user. like most other situations, this is not very easy
-           * to deal with, so we simply enforce a menu reload */
+          /* in this situation, an app dir could have 
+           * - become unreadable for the current user
+           * - been deleted
+           * - created (possibly inside an existing one)
+           * this is not trivial to handle, so we simply enforce a
+           * menu reload to deal with the changes */
           g_signal_emit (menu, menu_signals[RELOAD_REQUIRED], 0);
         }
       else
         {
-          /* a regular file changed, try to find the corresponding menu item */
-          item = garcon_menu_find_file_item (menu, file);
-          if (item != NULL)
+          path = g_file_get_path (file);
+          if (path != NULL && g_str_has_suffix (path, ".desktop"))
             {
-              /* try to reload the item */
-              if (garcon_menu_item_reload (item, &affects_the_outside, NULL))
+              /* a regular file changed, try to find the corresponding menu item */
+              item = garcon_menu_find_file_item (menu, file);
+              if (item != NULL)
                 {
-                  if (affects_the_outside)
+                  /* try to reload the item */
+                  if (garcon_menu_item_reload (item, &affects_the_outside, NULL))
                     {
-                      /* if the categories changed, the item might have to be
-                       * moved around between different menus. this is slightly
-                       * more complicated than one would first think, so just
-                       * enforce a complete menu reload for now */
-                      g_signal_emit (menu, menu_signals[RELOAD_REQUIRED], 0);
+                      if (affects_the_outside)
+                        {
+                          /* if the categories changed, the item might have to be
+                           * moved around between different menus. this is slightly
+                           * more complicated than one would first think, so just
+                           * enforce a complete menu reload for now */
+                          g_signal_emit (menu, menu_signals[RELOAD_REQUIRED], 0);
+                        }
+                      else
+                        {
+                          /* remove the item from the desktop item cache so we are forced
+                           * to reload it from disk the next time */
+                          garcon_menu_item_cache_invalidate_file (menu->priv->cache, file);
+
+                          /* nothing else to do here. the item should emit a 'changed'
+                           * signal to which users of this library can react */
+                        }
                     }
                   else
                     {
-                      /* nothing to do here. the item should emit a 'changed'
-                       * signal to which users of this library can react */
+                      /* remove the item from the desktop item cache so we are forced
+                       * to reload it from disk the next time */
+                      garcon_menu_item_cache_invalidate_file (menu->priv->cache, file);
+
+                      /* failed to reload the menu item. this can have many reasons,
+                       * one of them being that the file permissions might have changed
+                       * or that the file was deleted. handling most situations can be very
+                       * tricky, so, again, we just enfore a menu reload until we have 
+                       * something better */
+                      g_signal_emit (menu, menu_signals[RELOAD_REQUIRED], 0);
                     }
                 }
               else
                 {
-                  /* failed to reload the menu item. this can have many reasons,
-                   * one of them being that the file permissions might have changed.
-                   * handling this situation can be tricky, so, again, we just
-                   * enfore a menu reload until we have something better */
+                  /* there could be a lot of stuff happening here. seriously, this
+                   * stuff is complicated. for now, simply enforce a complete reload 
+                   * of the menu structure */
                   g_signal_emit (menu, menu_signals[RELOAD_REQUIRED], 0);
                 }
             }
-          else
-            {
-              /* there could be a lot of stuff happening here. seriously, this
-               * stuff is complicated. for now, simply enforce a complete reload 
-               * of the menu structure */
-              g_signal_emit (menu, menu_signals[RELOAD_REQUIRED], 0);
-            }
-        }
-    }
-  else if (event_type == G_FILE_MONITOR_EVENT_CREATED)
-    {
-      /* query the type of the changed file */
-      file_type = g_file_query_file_type (file, G_FILE_QUERY_INFO_NONE, NULL);
-
-      if (file_type == G_FILE_TYPE_DIRECTORY)
-        {
-          /* either a previously non-existent app dir or a new subdirectory 
-           * has been created. we need to load all the .desktop files that
-           * are now available in addition to the old ones. so enforce a
-           * menu reload and they will be picked up */
-          g_signal_emit (menu, menu_signals[RELOAD_REQUIRED], 0);
-        }
-      else
-        {
-          path = g_file_get_path (file);
-          if (path != NULL && g_str_has_suffix (path, ".desktop"))
-            {
-              /* a new .desktop file has been created. does it override another
-               * .desktop file that is currently in use? is it overriden itself
-               * and thus, can be ignored? it's not trivial to determine all this,
-               * so what we do is... force a menu reload */
-              g_signal_emit (menu, menu_signals[RELOAD_REQUIRED], 0);
-            }
           g_free (path);
         }
     }
-  else if (event_type == G_FILE_MONITOR_EVENT_DELETED)
-    {
-      /* query the type of the changed file */
-      file_type = g_file_query_file_type (file, G_FILE_QUERY_INFO_NONE, NULL);
-
-      if (file_type == G_FILE_TYPE_DIRECTORY)
-        {
-          /* an existing app dir (or a subdirectory) has been deleted. we
-           * could remove all the items that are in use and reside inside
-           * this root directory. but for now... enforce a menu reload! */
-          g_signal_emit (menu, menu_signals[RELOAD_REQUIRED], 0);
-        }
-      else 
-        {
-          /* a regular file was deleted, try to find the corresponding menu item */
-          item = garcon_menu_find_file_item (menu, file);
-          if (item != NULL)
-            {
-              /* ok, so a .desktop file was removed. of course we don't know
-               * yet whether there is a replacement in another app dir
-               * with lower priority. we could try to find out but for now
-               * it's easier to simply enforce a menu reload */
-              g_signal_emit (menu, menu_signals[RELOAD_REQUIRED], 0);
-            }
-          else
-            {
-              /* the deleted file hasn't been in use anyway, so removing it
-               * doesn't change anything. so we have nothing to do for a
-               * change, no f****ing menu reload! */
-            }
-        }
-    }
 }
 
 



More information about the Xfce4-commits mailing list