[Xfce4-commits] <garcon:master> Monitor directory dirs, add the GarconMenu::directory-changed signal.

Jannis Pohlmann noreply at xfce.org
Sun Sep 5 21:42:11 CEST 2010


Updating branch refs/heads/master
         to 2bfeb08bfb7f24cc075e22d15cc5405a13cf8456 (commit)
       from 9513c7716c656735e5c6c92769579c854deaa644 (commit)

commit 2bfeb08bfb7f24cc075e22d15cc5405a13cf8456
Author: Jannis Pohlmann <jannis at xfce.org>
Date:   Sun Sep 5 18:11:23 2010 +0200

    Monitor directory dirs, add the GarconMenu::directory-changed signal.
    
    Also remove garcon-config.h and update a few copyright headers.

 garcon/Makefile.am          |   51 ++++++++++++++-
 garcon/garcon-config.h      |   94 --------------------------
 garcon/garcon-config.h.in   |   26 ++++----
 garcon/garcon-marshal.list  |    1 +
 garcon/garcon-menu-merger.c |    2 +-
 garcon/garcon-menu-merger.h |    2 +-
 garcon/garcon-menu.c        |  152 +++++++++++++++++++++++++++++++++++++++++--
 7 files changed, 210 insertions(+), 118 deletions(-)

diff --git a/garcon/Makefile.am b/garcon/Makefile.am
index 84bc7e8..3ae2c35 100644
--- a/garcon/Makefile.am
+++ b/garcon/Makefile.am
@@ -1,6 +1,6 @@
 # vi:set ts=8 sw=8 noet ai nocindent syntax=automake:
 # 
-# Copyright (c) 2007-2009 Jannis Pohlmann <jannis at xfce.org>
+# Copyright (c) 2007-2010 Jannis Pohlmann <jannis at xfce.org>
 # 
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Library General Public
@@ -27,9 +27,17 @@ INCLUDES = 								\
 lib_LTLIBRARIES = 							\
 	libgarcon-1.la
 
+libgarcon_built_public_sources =					\
+	garcon-marshal.h
+
+libgarcon_built_sources =						\
+	$(libgarcon_built_public_sources)				\
+	garcon-marshal.c
+
 libgarcon_headers =							\
 	garcon.h							\
 	garcon-config.h							\
+	garcon-marshal.h						\
 	garcon-menu-element.h						\
 	garcon-menu-separator.h						\
 	garcon-menu-directory.h						\
@@ -45,6 +53,7 @@ libgarcon_headers =							\
 
 libgarcon_sources =							\
 	garcon-config.c							\
+	garcon-marshal.c						\
 	garcon-menu-element.c						\
 	garcon-menu-separator.c						\
 	garcon-menu-directory.c						\
@@ -88,10 +97,48 @@ libgarcon_1_la_LIBADD = 						\
 	$(GIO_LIBS)
 
 EXTRA_DIST =								\
-	garcon-config.h.in
+	garcon-config.h.in						\
+	garcon-marshal.list
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = garcon-1.pc
 
+DISTCLEANFILES =							\
+	stamp-garcon-marshal.h						\
+	garcon-config.h							\
+	$(libgarcon_built_sources)
+
+BUILT_SOURCES =								\
+	$(libgarcon_built_sources)
+
+garcon-marshal.h: stamp-garcon-marshal.h
+	@true
+
+stamp-garcon-marshal.h: garcon-marshal.list Makefile
+	$(AM_V_GEN) ( \
+	  cd $(top_builddir)/garcon \
+	  && echo "#ifndef __GARCON_MARSHAL_H__" > xgen-emh \
+	  && echo "#define __GARCON_MARSHAL_H__" >> xgen-emh \
+	  && ( glib-genmarshal \
+	  	--prefix=garcon_marshal \
+	  	--header $(srcdir)/garcon-marshal.list ) >> xgen-emh \
+	  && echo "#endif /* !__GARCON_MARSHAL_H__ */" >> xgen-emh \
+	  && ( cmp -s xgen-emh garcon-marshal.h \
+	  	|| cp xgen-emh garcon-marshal.h ) \
+	  && rm -f xgen-emh \
+	  && echo timestamp > $(@F) \
+	)
+
+garcon-marshal.c: garcon-marshal.list Makefile
+	$(AM_V_GEN) ( \
+	  cd $(top_builddir)/garcon \
+	  && echo "#include <garcon/garcon-marshal.h>" > xgen-emc \
+	  && ( glib-genmarshal \
+	  	--prefix=garcon_marshal \
+	  	--body $(srcdir)/garcon-marshal.list ) >> xgen-emc \
+	  && cp xgen-emc garcon-marshal.c \
+	  && rm -f xgen-emc \
+	)
+
 # Required for gtk-doc and make distcheck
 dist-hook: all
diff --git a/garcon/garcon-config.h b/garcon/garcon-config.h
deleted file mode 100644
index 0419d29..0000000
--- a/garcon/garcon-config.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* vi:set et ai sw=2 sts=2 ts=2: */
-/*-
- * Copyright (c) 2008-2010 Jannis Pohlmann <jannis at xfce.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General 
- * Public License along with this library; if not, write to the 
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#if !defined (GARCON_INSIDE_GARCON_H) && !defined (GARCON_COMPILATION)
-#error "Only <garcon/garcon.h> can be included directly, this file may disappear or change contents."
-#endif
-
-#ifndef __GARCON_CONFIG_H__
-#define __GARCON_CONFIG_H__
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-/**
- * GARCON_MAJOR_VERSION:
- *
- * The major version number of the garcon library.
- * Like garcon_major_version, but from the headers used at
- * application compile time, rather than from the library
- * linked against at application run time.
- **/
-#define GARCON_MAJOR_VERSION 0
-
-/**
- * GARCON_MINOR_VERSION:
- *
- * The minor version number of the garcon library.
- * Like garcon_minor_version, but from the headers used at
- * application compile time, rather than from the library
- * linked against at application run time.
- **/
-#define GARCON_MINOR_VERSION 1
-
-/**
- * GARCON_MICRO_VERSION:
- *
- * The micro version number of the garcon library.
- * Like garcon_micro_version, but from the headers used at
- * application compile time, rather than from the library
- * linked against at application run time.
- **/
-#define GARCON_MICRO_VERSION 1
-
-/**
- * GARCON_CHECK_VERSION:
- * @major : the major version number.
- * @minor : the minor version number.
- * @micro : the micro version number.
- *
- * Checks the version of the garcon library.
- *
- * Returns: %TRUE if the version of the garcon header files is
- *          the same as or newer than the passed-in version.
- **/
-#define GARCON_CHECK_VERSION(major,minor,micro) \
-  (GARCON_MAJOR_VERSION > (major) \
-   || (GARCON_MAJOR_VERSION == (major) \
-       && GARCON_MINOR_VERSION > (minor)) \
-   || (GARCON_MAJOR_VERSION == (major) \
-       && GARCON_MINOR_VERSION == (minor) \
-       && GARCON_MICRO_VERSION >= (micro)))
-
-extern const guint garcon_major_version;
-extern const guint garcon_minor_version;
-extern const guint garcon_micro_version;
-
-const gchar *garcon_check_version      (guint required_major,
-                                        guint required_minor,
-                                        guint required_micro);
-
-gchar       *garcon_config_lookup      (const gchar *filename) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
-gchar      **garcon_config_build_paths (const gchar *filename) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
-
-G_END_DECLS
-
-#endif /* !__GARCON_CONFIG_H__ */
diff --git a/garcon/garcon-config.h.in b/garcon/garcon-config.h.in
index baae3b8..d8dd63b 100644
--- a/garcon/garcon-config.h.in
+++ b/garcon/garcon-config.h.in
@@ -1,7 +1,6 @@
-/* $Id$ */
-/* vi:set expandtab sw=2 sts=2: */
+/* vi:set et ai sw=2 sts=2 ts=2: */
 /*-
- * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>
+ * Copyright (c) 2008-2010 Jannis Pohlmann <jannis at xfce.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -10,13 +9,13 @@
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ * GNU Library General Public License for more details.
  *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * You should have received a copy of the GNU Library General 
+ * Public License along with this library; if not, write to the 
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
  */
 
 #if !defined (GARCON_INSIDE_GARCON_H) && !defined (GARCON_COMPILATION)
@@ -83,11 +82,12 @@ extern const guint garcon_major_version;
 extern const guint garcon_minor_version;
 extern const guint garcon_micro_version;
 
-const gchar *garcon_check_version (guint required_major,
-                                   guint required_minor,
-                                   guint required_micro);
+const gchar *garcon_check_version      (guint        required_major,
+                                        guint        required_minor,
+                                        guint        required_micro);
 
-gchar       *garcon_config_lookup (const gchar *filename) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+gchar       *garcon_config_lookup      (const gchar *filename) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+gchar      **garcon_config_build_paths (const gchar *filename) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
 
 G_END_DECLS
 
diff --git a/garcon/garcon-marshal.list b/garcon/garcon-marshal.list
new file mode 100644
index 0000000..38076d6
--- /dev/null
+++ b/garcon/garcon-marshal.list
@@ -0,0 +1 @@
+VOID:OBJECT,OBJECT
diff --git a/garcon/garcon-menu-merger.c b/garcon/garcon-menu-merger.c
index f620d6f..e914588 100644
--- a/garcon/garcon-menu-merger.c
+++ b/garcon/garcon-menu-merger.c
@@ -1,6 +1,6 @@
 /* vi:set et ai sw=2 sts=2 ts=2: */
 /*-
- * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
+ * Copyright (c) 2009-2010 Jannis Pohlmann <jannis at xfce.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
diff --git a/garcon/garcon-menu-merger.h b/garcon/garcon-menu-merger.h
index 129fc43..c0d0e06 100644
--- a/garcon/garcon-menu-merger.h
+++ b/garcon/garcon-menu-merger.h
@@ -1,6 +1,6 @@
 /* vi:set et ai sw=2 sts=2 ts=2: */
 /*-
- * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
+ * Copyright (c) 2009-2010 Jannis Pohlmann <jannis at xfce.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
diff --git a/garcon/garcon-menu.c b/garcon/garcon-menu.c
index 3adbaed..f2e226f 100644
--- a/garcon/garcon-menu.c
+++ b/garcon/garcon-menu.c
@@ -28,7 +28,9 @@
 
 #include <glib/gi18n.h>
 
+#include <garcon/garcon-config.h>
 #include <garcon/garcon-environment.h>
+#include <garcon/garcon-marshal.h>
 #include <garcon/garcon-menu-element.h>
 #include <garcon/garcon-menu-item.h>
 #include <garcon/garcon-menu-directory.h>
@@ -38,7 +40,6 @@
 #include <garcon/garcon-menu-parser.h>
 #include <garcon/garcon-menu-merger.h>
 #include <garcon/garcon-private.h>
-#include <garcon/garcon.h>
 
 
 
@@ -101,6 +102,7 @@ enum
 enum
 {
   RELOAD_REQUIRED,
+  DIRECTORY_CHANGED,
   LAST_SIGNAL
 };
 
@@ -120,7 +122,9 @@ static void                 garcon_menu_set_property                    (GObject
 static void                 garcon_menu_set_directory                   (GarconMenu              *menu,
                                                                          GarconMenuDirectory     *directory);
 static void                 garcon_menu_resolve_menus                   (GarconMenu              *menu);
-static void                 garcon_menu_resolve_directory               (GarconMenu              *menu);
+static void                 garcon_menu_resolve_directory               (GarconMenu              *menu,
+                                                                         GCancellable            *cancellable,
+                                                                         gboolean                 recursive);
 static GarconMenuDirectory *garcon_menu_lookup_directory                (GarconMenu              *menu,
                                                                          const gchar             *filename);
 static void                 garcon_menu_collect_files                   (GarconMenu              *menu,
@@ -156,6 +160,7 @@ static void                 garcon_menu_monitor_files                   (GarconM
                                                                          GList                   *files,
                                                                          gpointer                 callback);
 static void                 garcon_menu_monitor_app_dirs                (GarconMenu              *menu);
+static void                 garcon_menu_monitor_directory_dirs          (GarconMenu              *menu);
 static void                 garcon_menu_file_changed                    (GarconMenu              *menu,
                                                                          GFile                   *file,
                                                                          GFile                   *other_file,
@@ -176,6 +181,11 @@ static void                 garcon_menu_app_dir_changed                 (GarconM
                                                                          GFile                   *other_file,
                                                                          GFileMonitorEvent        event_type,
                                                                          GFileMonitor            *monitor);
+static void                 garcon_menu_directory_file_changed          (GarconMenu              *menu,
+                                                                         GFile                   *file,
+                                                                         GFile                   *other_file,
+                                                                         GFileMonitorEvent        event_type,
+                                                                         GFileMonitor            *monitor);
 
 
 
@@ -278,6 +288,19 @@ garcon_menu_class_init (GarconMenuClass *klass)
                   G_TYPE_NONE,
                   0);
 
+  menu_signals[DIRECTORY_CHANGED] =
+    g_signal_new ("directory-changed",
+                  GARCON_TYPE_MENU,
+                  G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS,
+                  0,
+                  NULL,
+                  NULL,
+                  garcon_marshal_VOID__OBJECT_OBJECT,
+                  G_TYPE_NONE,
+                  2,
+                  GARCON_TYPE_MENU_DIRECTORY,
+                  GARCON_TYPE_MENU_DIRECTORY);
+
   garcon_menu_file_quark = g_quark_from_string ("garcon-menu-file-quark");
 }
 
@@ -715,7 +738,11 @@ garcon_menu_load (GarconMenu   *menu,
   garcon_menu_resolve_menus (menu);
 
   /* Resolve the menu directory */
-  garcon_menu_resolve_directory (menu);
+  garcon_menu_resolve_directory (menu, cancellable, TRUE);
+
+  /* Abort if the cancellable was cancelled */
+  if (g_cancellable_set_error_if_cancelled (cancellable, error))
+    return FALSE;
 
   desktop_id_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
 
@@ -887,13 +914,23 @@ garcon_menu_get_directories (GarconMenu *menu)
 
 
 static void
-garcon_menu_resolve_directory (GarconMenu *menu)
+garcon_menu_resolve_directory (GarconMenu   *menu,
+                               GCancellable *cancellable,
+                               gboolean      recursive)
 {
   GarconMenuDirectory *directory = NULL;
   GList               *directories = NULL;
   GList               *iter;
 
   g_return_if_fail (GARCON_IS_MENU (menu));
+  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+  /* release the old directory if there is one */
+  if (menu->priv->directory != NULL) 
+    {
+      g_object_unref (menu->priv->directory);
+      menu->priv->directory = NULL;
+    }
 
   /* Determine all directories for this menu */
   directories = garcon_menu_get_directories (menu);
@@ -914,9 +951,12 @@ garcon_menu_resolve_directory (GarconMenu *menu)
   /* Free reverse list copy */
   g_list_free (directories);
 
-  /* Resolve directories of submenus recursively */
-  for (iter = menu->priv->submenus; iter != NULL; iter = g_list_next (iter))
-    garcon_menu_resolve_directory (iter->data);
+  if (recursive)
+    {
+      /* Resolve directories of submenus recursively */
+      for (iter = menu->priv->submenus; iter != NULL; iter = g_list_next (iter))
+        garcon_menu_resolve_directory (iter->data, cancellable, recursive);
+    }
 }
 
 
@@ -1729,6 +1769,8 @@ garcon_menu_start_monitoring (GarconMenu *menu)
       garcon_menu_monitor_app_dirs (menu);
     }
 
+  garcon_menu_monitor_directory_dirs (menu);
+
   /* Recurse into submenus */
   for (lp = menu->priv->submenus; lp != NULL; lp = lp->next)
     garcon_menu_start_monitoring (lp->data);
@@ -1906,6 +1948,67 @@ garcon_menu_monitor_app_dirs (GarconMenu *menu)
 
 
 static void
+garcon_menu_monitor_directory_dirs (GarconMenu *menu)
+{
+  GFileMonitor *monitor;
+  GFile        *file;
+  GFile        *dir;
+  GList        *directory_files;
+  GList        *directory_dirs;
+  GList        *dp;
+  GList        *lp;
+
+  g_return_if_fail (GARCON_IS_MENU (menu));
+
+  /* Determine all .directory files we are interested in for this menu */
+  directory_files = garcon_menu_get_directories (menu);
+
+  /* Determine all .directory lookup dirs for this menu */
+  directory_dirs = garcon_menu_get_directory_dirs (menu);
+
+  /* Monitor potential .directory files */
+  for (lp = directory_files; lp != NULL; lp = lp->next)
+    {
+      for (dp = directory_dirs; dp != NULL; dp = dp->next)
+        {
+          dir = _garcon_file_new_relative_to_file (dp->data, menu->priv->file);
+          file = _garcon_file_new_relative_to_file (lp->data, dir);
+
+          /* Only try to monitor the .directory file if we don't do that already */
+          if (g_list_find_custom (menu->priv->monitors, file, 
+                                  (GCompareFunc) find_file_monitor) == NULL)
+            {
+              /* Try to monitor the file */
+              monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, NULL);
+              if (monitor != NULL)
+                {
+                  /* Associate the monitor with the monitored file */
+                  g_object_set_qdata_full (G_OBJECT (monitor), garcon_menu_file_quark,
+                                           g_object_ref (file), g_object_unref);
+
+                  /* Add the monitor to the list of monitors belonging to the menu */
+                  menu->priv->monitors = g_list_prepend (menu->priv->monitors, monitor);
+
+                  /* Make sure we are notified when the file changes */
+                  g_signal_connect_swapped (monitor, "changed",
+                                            G_CALLBACK (garcon_menu_directory_file_changed),
+                                            menu);
+                }
+            }
+
+          g_object_unref (file);
+          g_object_unref (dir);
+        }
+    }
+
+  /* Free lists */
+  g_list_free (directory_dirs);
+  g_list_free (directory_files);
+}
+
+
+
+static void
 garcon_menu_file_changed (GarconMenu       *menu,
                           GFile            *file,
                           GFile            *other_file,
@@ -2005,5 +2108,40 @@ garcon_menu_app_dir_changed (GarconMenu       *menu,
   g_return_if_fail (GARCON_IS_MENU (menu));
   g_return_if_fail (menu->priv->parent == NULL);
 
+  /* TODO */
+}
+
+
 
+static void
+garcon_menu_directory_file_changed (GarconMenu       *menu,
+                                    GFile            *file,
+                                    GFile            *other_file,
+                                    GFileMonitorEvent event_type,
+                                    GFileMonitor     *monitor)
+{
+  GarconMenuDirectory *old_directory;
+
+  g_return_if_fail (GARCON_IS_MENU (menu));
+
+  if (event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT
+      || event_type == G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED
+      || event_type == G_FILE_MONITOR_EVENT_DELETED 
+      || event_type == G_FILE_MONITOR_EVENT_CREATED)
+    {
+      /* take a reference on the current menu directory */
+      if (menu->priv->directory != NULL)
+        old_directory = g_object_ref (menu->priv->directory);
+                  
+      /* reset the menu directory of the menu and load a new one */
+      garcon_menu_resolve_directory (menu, NULL, FALSE);
+
+      /* notify listeners about the old and new menu directories */
+      g_signal_emit (menu, menu_signals[DIRECTORY_CHANGED], 0, 
+                     old_directory, menu->priv->directory);
+
+      /* release the old menu directory we no longer need */
+      if (old_directory != NULL)
+        g_object_unref (old_directory);
+    }
 }



More information about the Xfce4-commits mailing list