Index: plugins/xsettings/fontconfig-monitor.c
===================================================================
--- plugins/xsettings/fontconfig-monitor.c	(revision 0)
+++ plugins/xsettings/fontconfig-monitor.c	(revision 0)
@@ -0,0 +1,189 @@
+/*
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Red Hat not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Red Hat makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author:  Behdad Esfahbod, Red Hat, Inc.
+ */
+
+#include "fontconfig-monitor.h"
+
+#include <gio/gio.h>
+#include <fontconfig/fontconfig.h>
+
+#define TIMEOUT_SECONDS 2
+
+static void
+stuff_changed (GFileMonitor *monitor,
+	       GFile *file,
+	       GFile *other_file,
+	       GFileMonitorEvent event_type,
+	       gpointer handle);
+
+static GPtrArray *
+monitor_files (GPtrArray *monitors,
+	       FcStrList *list,
+	       gpointer   data)
+{
+  const char *str;
+
+  while ((str = (const char *) FcStrListNext (list)))
+    {
+      GFile *file;
+      GFileMonitor *monitor;
+
+      file = g_file_new_for_path (str);
+
+      if (g_file_test (str, G_FILE_TEST_IS_DIR))
+	monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL);
+      else
+	monitor = g_file_monitor_file      (file, G_FILE_MONITOR_NONE, NULL, NULL);
+
+      g_signal_connect (monitor, "changed", G_CALLBACK (stuff_changed), data);
+
+      g_ptr_array_add (monitors, monitor);
+
+      g_object_unref (file);
+    }
+
+  FcStrListDone (list);
+
+  return monitors;
+}
+
+
+struct _fontconfig_monitor_handle {
+  GPtrArray *monitors;
+
+  guint timeout;
+
+  GFunc    notify_callback;
+  gpointer notify_data;
+};
+
+static GPtrArray *
+monitors_create (gpointer data)
+{
+  GPtrArray *monitors = g_ptr_array_new ();
+
+  monitor_files (monitors, FcConfigGetConfigFiles (NULL), data);
+  monitor_files (monitors, FcConfigGetFontDirs (NULL)   , data);
+
+  return monitors;
+}
+
+static void
+monitors_free (GPtrArray *monitors)
+{
+  if (!monitors)
+    return;
+
+  g_ptr_array_foreach (monitors, (GFunc) g_object_unref, NULL);
+  g_ptr_array_set_size (monitors, 0);
+
+  g_ptr_array_free (monitors, TRUE);
+}
+
+static gboolean
+update (gpointer data)
+{
+  fontconfig_monitor_handle_t *handle = data;
+  gboolean notify = FALSE;
+
+  handle->timeout = 0;
+
+  monitors_free (handle->monitors);
+  handle->monitors = NULL;
+
+  if (FcInitReinitialize () && handle->notify_callback)
+    notify = TRUE;
+
+  handle->monitors = monitors_create (data);
+
+  /* we finish modifying handle before calling the notify callback,
+   * allowing the callback to free the monitor if it decides to. */
+
+  if (notify)
+    handle->notify_callback (data, handle->notify_data);
+
+  return FALSE;
+}
+
+static void
+stuff_changed (GFileMonitor *monitor G_GNUC_UNUSED,
+	       GFile *file G_GNUC_UNUSED,
+	       GFile *other_file G_GNUC_UNUSED,
+	       GFileMonitorEvent event_type G_GNUC_UNUSED,
+	       gpointer data)
+{
+  fontconfig_monitor_handle_t *handle = data;
+
+  /* wait for quiescence */
+  if (handle->timeout)
+    g_source_remove (handle->timeout);
+  
+  handle->timeout = g_timeout_add_seconds (TIMEOUT_SECONDS, update, data);
+}
+
+
+fontconfig_monitor_handle_t *
+fontconfig_monitor_start (GFunc    notify_callback,
+			  gpointer notify_data)
+{
+  fontconfig_monitor_handle_t *handle = g_slice_new0 (fontconfig_monitor_handle_t);
+
+  handle->notify_callback = notify_callback;
+  handle->notify_data = notify_data;
+  handle->monitors = monitors_create (handle);
+
+  return handle;
+}
+
+void
+fontconfig_monitor_stop  (fontconfig_monitor_handle_t *handle)
+{
+  if (handle->timeout)
+    g_source_remove (handle->timeout);
+  handle->timeout = 0;
+
+  monitors_free (handle->monitors);
+  handle->monitors = NULL;
+}
+
+#ifdef FONTCONFIG_MONITOR_TEST
+static void
+yay (void)
+{
+  g_message ("yay");
+}
+
+int
+main (void)
+{
+  GMainLoop *loop;
+
+  g_type_init ();
+
+  fontconfig_monitor_start ((GFunc) yay, NULL);
+
+  loop = g_main_loop_new (NULL, TRUE);
+  g_main_loop_run (loop);
+
+  return 0;
+}
+#endif
Index: plugins/xsettings/fontconfig-monitor.h
===================================================================
--- plugins/xsettings/fontconfig-monitor.h	(revision 0)
+++ plugins/xsettings/fontconfig-monitor.h	(revision 0)
@@ -0,0 +1,39 @@
+/*
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Red Hat not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Red Hat makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author:  Behdad Esfahbod, Red Hat, Inc.
+ */
+#ifndef FONTCONFIG_MONITOR_H
+#define FONTCONFIG_MONITOR_H
+
+#include <glib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _fontconfig_monitor_handle fontconfig_monitor_handle_t;
+
+fontconfig_monitor_handle_t *
+fontconfig_monitor_start (GFunc    notify_callback,
+			  gpointer notify_data);
+void fontconfig_monitor_stop  (fontconfig_monitor_handle_t *handle);
+
+#endif
Index: plugins/xsettings/Makefile.am
===================================================================
--- plugins/xsettings/Makefile.am	(revision 361)
+++ plugins/xsettings/Makefile.am	(working copy)
@@ -13,6 +13,8 @@ libxsettings_la_SOURCES = 	\
 	xsettings-common.c	\
 	xsettings-manager.h	\
 	xsettings-manager.c	\
+	fontconfig-monitor.h	\
+	fontconfig-monitor.c	\
 	$(NULL)
 
 libxsettings_la_CPPFLAGS = \
Index: plugins/xsettings/gsd-xsettings-manager.c
===================================================================
--- plugins/xsettings/gsd-xsettings-manager.c	(revision 361)
+++ plugins/xsettings/gsd-xsettings-manager.c	(working copy)
@@ -28,6 +28,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <errno.h>
+#include <time.h>
 
 #include <glib.h>
 #include <glib/gi18n.h>
@@ -40,6 +41,7 @@
 #include "gnome-settings-profile.h"
 #include "gsd-xsettings-manager.h"
 #include "xsettings-manager.h"
+#include "fontconfig-monitor.h"
 
 #define GNOME_XSETTINGS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNOME_TYPE_XSETTINGS_MANAGER, GnomeXSettingsManagerPrivate))
 
@@ -87,6 +89,7 @@ struct GnomeXSettingsManagerPrivate
 {
         XSettingsManager **managers;
         guint              notify[4];
+	fontconfig_monitor_handle_t *fontconfig_handle;
 };
 
 #define GSD_XSETTINGS_ERROR gsd_xsettings_error_quark ()
@@ -538,6 +541,22 @@ xft_callback (GConfClient           *cli
 
 #endif /* HAVE_XFT2 */
 
+static void
+fontconfig_callback (fontconfig_monitor_handle_t *handle,
+		     GnomeXSettingsManager       *manager)
+{
+        int i;
+
+        gnome_settings_profile_start (NULL);
+
+        for (i = 0; manager->priv->managers [i]; i++) {
+                xsettings_manager_set_int (manager->priv->managers [i], "Fontconfig/Timestamp", time(NULL));
+                xsettings_manager_notify (manager->priv->managers [i]);
+        }
+        gnome_settings_profile_end (NULL);
+}
+
+
 static const char *
 type_to_string (GConfValueType type)
 {
@@ -754,6 +773,8 @@ gnome_xsettings_manager_start (GnomeXSet
         update_xft_settings (manager, client);
 #endif /* HAVE_XFT */
 
+	manager->priv->fontconfig_handle = fontconfig_monitor_start ((GFunc) fontconfig_callback, manager);
+
         g_object_unref (client);
 
         for (i = 0; manager->priv->managers [i]; i++)
@@ -804,6 +825,9 @@ gnome_xsettings_manager_stop (GnomeXSett
                 }
         }
 
+	fontconfig_monitor_stop (manager->priv->fontconfig_handle);
+	manager->priv->fontconfig_handle = NULL;
+
         g_object_unref (client);
 }
 
