[gnome-settings-daemon] xsettings: Port GTK+ Modules loading to GSettings



commit 1f5146439074267bdca9f5723bb9dffc428874b4
Author: Bastien Nocera <hadess hadess net>
Date:   Tue Oct 26 15:11:37 2010 +0100

    xsettings: Port GTK+ Modules loading to GSettings
    
    Adds the "disabled-gtk-modules" and "enabled-gtk-modules" GSettings
    keys, for admins to lockdown loading (or not) particular GTK+ modules.
    
    The modules that need it will install a .desktop file in
    $(libdir)/gnome-settings-daemon-3.0/gtk-modules/
    
    https://bugzilla.gnome.org/show_bug.cgi?id=633191

 ...ings-daemon.plugins.xsettings.gschema.xml.in.in |   10 +
 plugins/xsettings/Makefile.am                      |   22 ++
 plugins/xsettings/gsd-xsettings-gtk.c              |  374 ++++++++++++++++++++
 plugins/xsettings/gsd-xsettings-gtk.h              |   58 +++
 plugins/xsettings/gsd-xsettings-manager.c          |  204 ++++--------
 plugins/xsettings/test-gtk-modules.c               |   33 ++
 6 files changed, 560 insertions(+), 141 deletions(-)
---
diff --git a/data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in b/data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in
index b3c7f62..2b3a434 100644
--- a/data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in
+++ b/data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in
@@ -30,5 +30,15 @@
       <_summary>RGBA order</_summary>
       <_description>The order of subpixel elements on an LCD screen; only used when antialiasing is set to "rgba". Possible values are: "rgb" for red on left (most common), "bgr" for blue on left, "vrgb" for red on top, "vbgr" for red on bottom.</_description>
     </key>
+    <key name="disabled-gtk-modules" type="as">
+      <default>[]</default>
+      <_summary>List of explicitly disabled GTK+ modules</_summary>
+      <_description>A list of strings representing the GTK+ modules that will not be loaded, even if enabled by default in their configuration.</_description>
+    </key>
+    <key name="enabled-gtk-modules" type="as">
+      <default>[]</default>
+      <_summary>List of explicitly enabled GTK+ modules</_summary>
+      <_description>A list of strings representing the GTK+ modules that will be loaded, usually in addition to conditional and forcibly disabled ones.</_description>
+    </key>
   </schema>
 </schemalist>
diff --git a/plugins/xsettings/Makefile.am b/plugins/xsettings/Makefile.am
index b677eb1..de03011 100644
--- a/plugins/xsettings/Makefile.am
+++ b/plugins/xsettings/Makefile.am
@@ -1,5 +1,26 @@
 NULL =
 
+noinst_PROGRAMS = test-gtk-modules
+
+test_gtk_modules_SOURCES =	\
+	gsd-xsettings-gtk.c	\
+	gsd-xsettings-gtk.h	\
+	test-gtk-modules.c
+
+test_gtk_modules_CFLAGS =		\
+	$(SETTINGS_PLUGIN_CFLAGS)	\
+	$(AM_CFLAGS)
+
+test_gtk_modules_LDADD =		\
+	$(SETTINGS_PLUGIN_LIBS)
+
+test_gtk_modules_CPPFLAGS =				\
+	-I$(top_srcdir)/gnome-settings-daemon		\
+	-I$(top_srcdir)/data/				\
+	-DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \
+	-DGTK_MODULES_DIRECTORY=\""$(libdir)/gnome-settings-daemon- GSD_API_VERSION@/gtk-modules/"\" \
+	$(AM_CPPFLAGS)
+
 plugin_LTLIBRARIES = \
 	libxsettings.la		\
 	$(NULL)
@@ -21,6 +42,7 @@ libxsettings_la_CPPFLAGS = \
 	-I$(top_srcdir)/gnome-settings-daemon		\
 	-I$(top_srcdir)/data/				\
 	-DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \
+	-DGTK_MODULES_DIRECTORY=\""$(libdir)/gnome-settings-daemon- GSD_API_VERSION@/gtk-modules/"\" \
 	$(AM_CPPFLAGS)
 
 libxsettings_la_CFLAGS = \
diff --git a/plugins/xsettings/gsd-xsettings-gtk.c b/plugins/xsettings/gsd-xsettings-gtk.c
new file mode 100644
index 0000000..4a9513e
--- /dev/null
+++ b/plugins/xsettings/gsd-xsettings-gtk.c
@@ -0,0 +1,374 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 William Jon McCann <mccann jhu edu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <glib/gi18n-lib.h>
+#include <gio/gio.h>
+
+#include "gsd-xsettings-gtk.h"
+
+#define XSETTINGS_PLUGIN_SCHEMA "org.gnome.settings-daemon.plugins.xsettings"
+
+#define GTK_MODULES_DISABLED_KEY "disabled-gtk-modules"
+#define GTK_MODULES_ENABLED_KEY  "enabled-gtk-modules"
+
+enum {
+        PROP_0,
+        PROP_GTK_MODULES
+};
+
+struct GsdXSettingsGtkPrivate {
+        char              *modules;
+        GHashTable        *dir_modules;
+
+        GSettings         *settings;
+
+        guint64            dir_mtime;
+        GFileMonitor      *monitor;
+        GList             *cond_settings;
+};
+
+#define GSD_XSETTINGS_GTK_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSD_TYPE_XSETTINGS_GTK, GsdXSettingsGtkPrivate))
+
+G_DEFINE_TYPE(GsdXSettingsGtk, gsd_xsettings_gtk, G_TYPE_OBJECT)
+
+static void update_gtk_modules (GsdXSettingsGtk *gtk);
+
+static void
+empty_cond_settings_list (GsdXSettingsGtk *gtk)
+{
+        if (gtk->priv->cond_settings == NULL)
+                return;
+
+        /* Empty the list of settings */
+        g_list_foreach (gtk->priv->cond_settings, (GFunc) g_object_unref, NULL);
+        g_list_free (gtk->priv->cond_settings);
+        gtk->priv->cond_settings = NULL;
+}
+
+static void
+cond_setting_changed (GSettings       *settings,
+                      const char      *key,
+                      GsdXSettingsGtk *gtk)
+{
+        gboolean enabled;
+        const char *module_name;
+
+        module_name = g_object_get_data (G_OBJECT (settings), "module-name");
+
+        enabled = g_settings_get_boolean (settings, key);
+        if (enabled != FALSE) {
+                g_hash_table_insert (gtk->priv->dir_modules, g_strdup (module_name), NULL);
+        } else {
+                g_hash_table_remove (gtk->priv->dir_modules, module_name);
+        }
+
+        update_gtk_modules (gtk);
+}
+
+static char *
+process_desktop_file (const char      *path,
+                      GsdXSettingsGtk *gtk)
+{
+        GKeyFile *keyfile;
+        char *retval;
+        const char *module_name;
+
+        retval = NULL;
+
+        if (g_str_has_suffix (path, ".desktop") == FALSE)
+                return retval;
+
+        keyfile = g_key_file_new ();
+        if (g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, NULL) == FALSE)
+                goto bail;
+
+        if (g_key_file_has_group (keyfile, "GTK Module") == FALSE)
+                goto bail;
+
+        module_name = g_key_file_get_string (keyfile, "GTK Module", "X-GTK-Module-Name", NULL);
+        if (module_name == NULL)
+                goto bail;
+
+        if (g_key_file_has_key (keyfile, "GTK Module", "X-GTK-Module-Enabled-Schema", NULL) != FALSE) {
+                const char *schema;
+                const char *key;
+                gboolean enabled;
+                GSettings *settings;
+                char *signal;
+
+                schema = g_key_file_get_string (keyfile, "GTK Module", "X-GTK-Module-Enabled-Schema", NULL);
+                key = g_key_file_get_string (keyfile, "GTK Module", "X-GTK-Module-Enabled-Key", NULL);
+
+                settings = g_settings_new (schema);
+                enabled = g_settings_get_boolean (settings, key);
+
+                gtk->priv->cond_settings = g_list_prepend (gtk->priv->cond_settings, settings);
+
+                g_object_set_data_full (G_OBJECT (settings), "module-name", g_strdup (module_name), (GDestroyNotify) g_free);
+
+                signal = g_strdup_printf ("changed::%s", key);
+                g_signal_connect (G_OBJECT (settings), signal,
+                                  G_CALLBACK (cond_setting_changed), gtk);
+                g_free (signal);
+
+                if (enabled != FALSE)
+                        retval = g_strdup (module_name);
+        } else {
+                retval = g_strdup (module_name);
+        }
+
+bail:
+        g_key_file_free (keyfile);
+        return retval;
+}
+
+static void
+get_gtk_modules_from_dir (GsdXSettingsGtk *gtk)
+{
+        GFile *file;
+        GFileInfo *info;
+        GHashTable *ht;
+
+        file = g_file_new_for_path (GTK_MODULES_DIRECTORY);
+        info = g_file_query_info (file,
+                                  G_FILE_ATTRIBUTE_TIME_MODIFIED,
+                                  G_FILE_QUERY_INFO_NONE,
+                                  NULL,
+                                  NULL);
+        if (info != NULL) {
+                guint64 dir_mtime;
+
+                dir_mtime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
+                if (gtk->priv->dir_mtime == 0 ||
+                    dir_mtime > gtk->priv->dir_mtime) {
+                        GDir *dir;
+                        const char *name;
+
+                        empty_cond_settings_list (gtk);
+
+                        gtk->priv->dir_mtime = dir_mtime;
+
+                        if (gtk->priv->dir_modules != NULL) {
+                                g_hash_table_destroy (gtk->priv->dir_modules);
+                                gtk->priv->dir_modules = NULL;
+                        }
+
+                        dir = g_dir_open (GTK_MODULES_DIRECTORY, 0, NULL);
+                        if (dir == NULL)
+                                goto bail;
+
+                        ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+                        while ((name = g_dir_read_name (dir)) != NULL) {
+                                char *path;
+                                char *module;
+
+                                path = g_build_filename (GTK_MODULES_DIRECTORY, name, NULL);
+                                module = process_desktop_file (path, gtk);
+                                if (module != NULL)
+                                        g_hash_table_insert (ht, module, NULL);
+                                g_free (path);
+                        }
+                        g_dir_close (dir);
+
+                        gtk->priv->dir_modules = ht;
+                }
+                g_object_unref (info);
+        } else {
+                empty_cond_settings_list (gtk);
+        }
+
+bail:
+        g_object_unref (file);
+}
+
+static void
+stringify_gtk_modules (gpointer key,
+                       gpointer value,
+                       GString *str)
+{
+        if (str->len != 0)
+                g_string_append_c (str, ':');
+        g_string_append (str, key);
+}
+
+static void
+update_gtk_modules (GsdXSettingsGtk *gtk)
+{
+        char **enabled, **disabled;
+        GHashTable *ht;
+        guint i;
+        GString *str;
+        char *modules;
+
+        enabled = g_settings_get_strv (gtk->priv->settings, GTK_MODULES_ENABLED_KEY);
+        disabled = g_settings_get_strv (gtk->priv->settings, GTK_MODULES_DISABLED_KEY);
+
+        ht = g_hash_table_new (g_str_hash, g_str_equal);
+
+        if (gtk->priv->dir_modules != NULL) {
+                GList *list, *l;
+
+                list = g_hash_table_get_keys (gtk->priv->dir_modules);
+                for (l = list; l != NULL; l = l->next) {
+                        g_hash_table_insert (ht, l->data, NULL);
+                }
+                g_list_free (list);
+        }
+
+        for (i = 0; enabled[i] != NULL; i++)
+                g_hash_table_insert (ht, enabled[i], NULL);
+
+        for (i = 0; disabled[i] != NULL; i++)
+                g_hash_table_remove (ht, disabled[i]);
+
+        str = g_string_new (NULL);
+        g_hash_table_foreach (ht, (GHFunc) stringify_gtk_modules, str);
+        g_hash_table_destroy (ht);
+
+        modules = g_string_free (str, FALSE);
+
+        if (modules == NULL ||
+            gtk->priv->modules == NULL ||
+            g_str_equal (modules, gtk->priv->modules) == FALSE) {
+                g_free (gtk->priv->modules);
+                gtk->priv->modules = modules;
+                g_object_notify (G_OBJECT (gtk), "gtk-modules");
+        } else {
+                g_free (modules);
+        }
+}
+
+static void
+gtk_modules_dir_changed_cb (GFileMonitor     *monitor,
+                            GFile            *file,
+                            GFile            *other_file,
+                            GFileMonitorEvent event_type,
+                            GsdXSettingsGtk  *gtk)
+{
+        get_gtk_modules_from_dir (gtk);
+        update_gtk_modules (gtk);
+}
+
+static void
+gsd_xsettings_gtk_init (GsdXSettingsGtk *gtk)
+{
+        GFile *file;
+
+        gtk->priv = GSD_XSETTINGS_GTK_GET_PRIVATE (gtk);
+
+        g_debug ("GsdXSettingsGtk initializing");
+
+        gtk->priv->settings = g_settings_new (XSETTINGS_PLUGIN_SCHEMA);
+
+        get_gtk_modules_from_dir (gtk);
+
+        file = g_file_new_for_path (GTK_MODULES_DIRECTORY);
+        gtk->priv->monitor = g_file_monitor (file,
+                                             G_FILE_MONITOR_NONE,
+                                             NULL,
+                                             NULL);
+        g_signal_connect (G_OBJECT (gtk->priv->monitor), "changed",
+                          G_CALLBACK (gtk_modules_dir_changed_cb), gtk);
+        g_object_unref (file);
+
+        update_gtk_modules (gtk);
+}
+
+static void
+gsd_xsettings_gtk_finalize (GObject *object)
+{
+        GsdXSettingsGtk *gtk;
+
+        g_return_if_fail (object != NULL);
+        g_return_if_fail (GSD_IS_XSETTINGS_GTK (object));
+
+        g_debug ("GsdXSettingsGtk finalizing");
+
+        gtk = GSD_XSETTINGS_GTK (object);
+
+        g_return_if_fail (gtk->priv != NULL);
+
+        g_free (gtk->priv->modules);
+        gtk->priv->modules = NULL;
+
+        if (gtk->priv->dir_modules != NULL) {
+                g_hash_table_destroy (gtk->priv->dir_modules);
+                gtk->priv->dir_modules = NULL;
+        }
+
+        g_object_unref (gtk->priv->settings);
+
+        if (gtk->priv->monitor != NULL)
+                g_object_unref (gtk->priv->monitor);
+
+        empty_cond_settings_list (gtk);
+
+        G_OBJECT_CLASS (gsd_xsettings_gtk_parent_class)->finalize (object);
+}
+
+static void
+gsd_xsettings_gtk_get_property (GObject        *object,
+                                guint           prop_id,
+                                GValue         *value,
+                                GParamSpec     *pspec)
+{
+        GsdXSettingsGtk *self;
+
+        self = GSD_XSETTINGS_GTK (object);
+
+        switch (prop_id) {
+        case PROP_GTK_MODULES:
+                g_value_set_string (value, self->priv->modules);
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+gsd_xsettings_gtk_class_init (GsdXSettingsGtkClass *klass)
+{
+        GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+        object_class->get_property = gsd_xsettings_gtk_get_property;
+        object_class->finalize = gsd_xsettings_gtk_finalize;
+
+        g_object_class_install_property (object_class, PROP_GTK_MODULES,
+                                         g_param_spec_string ("gtk-modules", NULL, NULL,
+                                                              NULL, G_PARAM_READABLE));
+
+        g_type_class_add_private (klass, sizeof (GsdXSettingsGtkPrivate));
+}
+
+GsdXSettingsGtk *
+gsd_xsettings_gtk_new (void)
+{
+        return GSD_XSETTINGS_GTK (g_object_new (GSD_TYPE_XSETTINGS_GTK, NULL));
+}
+
+const char *
+gsd_xsettings_get_modules (GsdXSettingsGtk *gtk)
+{
+        return gtk->priv->modules;
+}
diff --git a/plugins/xsettings/gsd-xsettings-gtk.h b/plugins/xsettings/gsd-xsettings-gtk.h
new file mode 100644
index 0000000..7d4d2c4
--- /dev/null
+++ b/plugins/xsettings/gsd-xsettings-gtk.h
@@ -0,0 +1,58 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2010 Bastien Nocera <hadess hadess net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __GSD_XSETTINGS_GTK_H__
+#define __GSD_XSETTINGS_GTK_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gmodule.h>
+
+G_BEGIN_DECLS
+
+#define GSD_TYPE_XSETTINGS_GTK                (gsd_xsettings_gtk_get_type ())
+#define GSD_XSETTINGS_GTK(o)                  (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_XSETTINGS_GTK, GsdXSettingsGtk))
+#define GSD_XSETTINGS_GTK_CLASS(k)            (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_XSETTINGS_GTK, GsdXSettingsGtkClass))
+#define GSD_IS_XSETTINGS_GTK(o)               (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_XSETTINGS_GTK))
+#define GSD_IS_XSETTINGS_GTK_CLASS(k)         (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_XSETTINGS_GTK))
+#define GSD_XSETTINGS_GTK_GET_CLASS(o)        (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_XSETTINGS_GTK, GsdXSettingsGtkClass))
+
+typedef struct GsdXSettingsGtkPrivate GsdXSettingsGtkPrivate;
+
+typedef struct
+{
+        GObject                   parent;
+        GsdXSettingsGtkPrivate *priv;
+} GsdXSettingsGtk;
+
+typedef struct
+{
+        GObjectClass parent_class;
+} GsdXSettingsGtkClass;
+
+GType   gsd_xsettings_gtk_get_type            (void) G_GNUC_CONST;
+
+GsdXSettingsGtk *gsd_xsettings_gtk_new        (void);
+
+const char * gsd_xsettings_get_modules (GsdXSettingsGtk *gtk);
+
+G_END_DECLS
+
+#endif /* __GSD_XSETTINGS_GTK_H__ */
diff --git a/plugins/xsettings/gsd-xsettings-manager.c b/plugins/xsettings/gsd-xsettings-manager.c
index df33d49..18e130a 100644
--- a/plugins/xsettings/gsd-xsettings-manager.c
+++ b/plugins/xsettings/gsd-xsettings-manager.c
@@ -43,6 +43,7 @@
 #include "gnome-settings-profile.h"
 #include "gsd-enums.h"
 #include "gsd-xsettings-manager.h"
+#include "gsd-xsettings-gtk.h"
 #include "xsettings-manager.h"
 #include "fontconfig-monitor.h"
 
@@ -52,9 +53,11 @@
 #define INTERFACE_SETTINGS_SCHEMA "org.gnome.desktop.interface"
 #define SOUND_SETTINGS_SCHEMA     "org.gnome.desktop.sound"
 
-#define GTK_MODULES_DIR        "/apps/gnome_settings_daemon/gtk-modules"
+#define XSETTINGS_PLUGIN_SCHEMA "org.gnome.settings-daemon.plugins.xsettings"
+
+#define GTK_MODULES_DISABLED_KEY "disabled-gtk-modules"
+#define GTK_MODULES_ENABLED_KEY  "enabled-gtk-modules"
 
-#define FONT_RENDER_DIR "org.gnome.settings-daemon.plugins.xsettings"
 #define FONT_ANTIALIASING_KEY "antialiasing"
 #define FONT_HINTING_KEY      "hinting"
 #define FONT_RGBA_ORDER_KEY   "rgba-order"
@@ -91,10 +94,11 @@ struct GnomeXSettingsManagerPrivate
 {
         XSettingsManager **managers;
         GHashTable        *settings;
-        guint              gtk_modules_notify;
 
-        GSettings         *font_settings;
+        GSettings         *plugin_settings;
         fontconfig_monitor_handle_t *fontconfig_handle;
+
+        GsdXSettingsGtk   *gtk;
 };
 
 #define GSD_XSETTINGS_ERROR gsd_xsettings_error_quark ()
@@ -261,7 +265,7 @@ get_dpi_from_gsettings_or_x_server (GnomeXSettingsManager *manager)
 {
         double      dpi;
 
-        dpi = g_settings_get_double (manager->priv->font_settings, FONT_DPI_KEY);
+        dpi = g_settings_get_double (manager->priv->plugin_settings, FONT_DPI_KEY);
         if (dpi == 0.0)
                 dpi = get_dpi_from_x_server ();
 
@@ -289,9 +293,9 @@ xft_settings_get (GnomeXSettingsManager *manager,
         gboolean use_rgba = FALSE;
 
 
-        antialiasing = g_settings_get_enum (manager->priv->font_settings, FONT_ANTIALIASING_KEY);
-        hinting = g_settings_get_enum (manager->priv->font_settings, FONT_HINTING_KEY);
-        rgba_order = g_settings_get_enum (manager->priv->font_settings, FONT_RGBA_ORDER_KEY);
+        antialiasing = g_settings_get_enum (manager->priv->plugin_settings, FONT_ANTIALIASING_KEY);
+        hinting = g_settings_get_enum (manager->priv->plugin_settings, FONT_HINTING_KEY);
+        rgba_order = g_settings_get_enum (manager->priv->plugin_settings, FONT_RGBA_ORDER_KEY);
         dpi = get_dpi_from_gsettings_or_x_server (manager);
 
         settings->antialias = (antialiasing != GSD_FONT_ANTIALIASING_MODE_NONE);
@@ -454,6 +458,45 @@ xft_callback (GSettings             *settings,
 }
 
 static void
+plugin_callback (GSettings             *settings,
+                 const char            *key,
+                 GnomeXSettingsManager *manager)
+{
+        if (g_str_equal (key, GTK_MODULES_DISABLED_KEY) ||
+            g_str_equal (key, GTK_MODULES_ENABLED_KEY)) {
+                /* Do nothing, as GsdXsettingsGtk will handle it */
+        } else {
+                xft_callback (settings, key, manager);
+        }
+}
+
+static void
+gtk_modules_callback (GsdXSettingsGtk       *gtk,
+                      GParamSpec            *spec,
+                      GnomeXSettingsManager *manager)
+{
+        const char *modules = gsd_xsettings_get_modules (manager->priv->gtk);
+        int i;
+
+        if (modules == NULL) {
+                for (i = 0; manager->priv->managers [i]; ++i) {
+                        xsettings_manager_delete_setting (manager->priv->managers [i], "Gtk/Modules");
+                }
+        } else {
+                g_debug ("Setting GTK modules '%s'", modules);
+                for (i = 0; manager->priv->managers [i]; ++i) {
+                        xsettings_manager_set_string (manager->priv->managers [i],
+                                                      "Gtk/Modules",
+                                                      modules);
+                }
+        }
+
+        for (i = 0; manager->priv->managers [i]; ++i) {
+                xsettings_manager_notify (manager->priv->managers [i]);
+        }
+}
+
+static void
 fontconfig_callback (fontconfig_monitor_handle_t *handle,
                      GnomeXSettingsManager       *manager)
 {
@@ -502,32 +545,6 @@ stop_fontconfig_monitor (GnomeXSettingsManager  *manager)
         }
 }
 
-static const char *
-type_to_string (GConfValueType type)
-{
-        switch (type) {
-        case GCONF_VALUE_INT:
-                return "int";
-        case GCONF_VALUE_STRING:
-                return "string";
-        case GCONF_VALUE_FLOAT:
-                return "float";
-        case GCONF_VALUE_BOOL:
-                return "bool";
-        case GCONF_VALUE_SCHEMA:
-                return "schema";
-        case GCONF_VALUE_LIST:
-                return "list";
-        case GCONF_VALUE_PAIR:
-                return "pair";
-        case GCONF_VALUE_INVALID:
-                return "*invalid*";
-        default:
-                g_assert_not_reached();
-                return NULL; /* for warnings */
-        }
-}
-
 static void
 process_value (GnomeXSettingsManager *manager,
                TranslationEntry      *trans,
@@ -588,92 +605,6 @@ xsettings_callback (GSettings             *settings,
         }
 }
 
-static gchar *
-get_gtk_modules (GConfClient *client)
-{
-        GSList *entries, *l;
-        GString *mods = g_string_new (NULL);
-
-        entries = gconf_client_all_entries (client, GTK_MODULES_DIR, NULL);
-
-        for (l = entries; l != NULL; l = g_slist_next (l)) {
-                GConfEntry *e = l->data;
-                GConfValue *v = gconf_entry_get_value (e);
-
-                if (v != NULL) {
-                        gboolean enabled = FALSE;
-                        const gchar *key;
-
-                        switch (v->type) {
-                        case GCONF_VALUE_BOOL:
-                                /* simple enabled/disabled */
-                                enabled = gconf_value_get_bool (v);
-                                break;
-
-                        /* due to limitations in GConf (or the client libraries,
-                         * anyway), it is currently impossible to monitor
-                         * arbitrary keys for changes, so these won't update at
-                         * runtime */
-                        case GCONF_VALUE_STRING:
-                                /* linked to another GConf key of type bool */
-                                key = gconf_value_get_string (v);
-                                if (key != NULL && gconf_valid_key (key, NULL)) {
-                                        enabled = gconf_client_get_bool (client, key, NULL);
-                                }
-                                break;
-
-                        default:
-                                g_warning ("GConf entry %s has invalid type %s",
-                                           gconf_entry_get_key (e), type_to_string (v->type));
-                        }
-
-                        if (enabled) {
-                                const gchar *name;
-                                name = strrchr (gconf_entry_get_key (e), '/') + 1;
-
-                                if (mods->len > 0) {
-                                        g_string_append_c (mods, ':');
-                                }
-                                g_string_append (mods, name);
-                        }
-                }
-
-                gconf_entry_free (e);
-        }
-
-        g_slist_free (entries);
-
-        return g_string_free (mods, mods->len == 0);
-}
-
-static void
-gtk_modules_callback (GConfClient           *client,
-                      guint                  cnxn_id,
-                      GConfEntry            *entry,
-                      GnomeXSettingsManager *manager)
-{
-        gchar *modules = get_gtk_modules (client);
-        int i;
-
-        if (modules == NULL) {
-                for (i = 0; manager->priv->managers [i]; ++i) {
-                        xsettings_manager_delete_setting (manager->priv->managers [i], "Gtk/Modules");
-                }
-        } else {
-                g_debug ("Setting GTK modules '%s'", modules);
-                for (i = 0; manager->priv->managers [i]; ++i) {
-                        xsettings_manager_set_string (manager->priv->managers [i],
-                                                      "Gtk/Modules",
-                                                      modules);
-                }
-                g_free (modules);
-        }
-
-        for (i = 0; manager->priv->managers [i]; ++i) {
-                xsettings_manager_notify (manager->priv->managers [i]);
-        }
-}
-
 static void
 terminate_cb (void *data)
 {
@@ -732,7 +663,6 @@ gboolean
 gnome_xsettings_manager_start (GnomeXSettingsManager *manager,
                                GError               **error)
 {
-        GConfClient *client;
         guint        i;
         GList       *list, *l;
 
@@ -779,20 +709,16 @@ gnome_xsettings_manager_start (GnomeXSettingsManager *manager,
         }
         g_list_free (list);
 
-        /* Set up the GTK modules */
-        client = gconf_client_get_default ();
-        gconf_client_add_dir (client, GTK_MODULES_DIR, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
-        manager->priv->gtk_modules_notify = gconf_client_notify_add (client, GTK_MODULES_DIR,
-                                                                     (GConfClientNotifyFunc) gtk_modules_callback,
-                                                                     manager, NULL, NULL);
-
-        gtk_modules_callback (client, 0, NULL, manager);
+        /* Plugin settings (GTK modules and Xft) */
+        manager->priv->plugin_settings = g_settings_new (XSETTINGS_PLUGIN_SCHEMA);
+        g_signal_connect (manager->priv->plugin_settings, "changed",
+                          G_CALLBACK (plugin_callback), manager);
 
-        g_object_unref (client);
+        manager->priv->gtk = gsd_xsettings_gtk_new ();
+        g_signal_connect (G_OBJECT (manager->priv->gtk), "notify::gtk-modules",
+                          G_CALLBACK (gtk_modules_callback), manager);
 
-        manager->priv->font_settings = g_settings_new (FONT_RENDER_DIR);
-        g_signal_connect (manager->priv->font_settings, "changed",
-                          G_CALLBACK (xft_callback), manager);
+        /* Xft settings */
         update_xft_settings (manager);
 
         start_fontconfig_monitor (manager);
@@ -816,7 +742,6 @@ void
 gnome_xsettings_manager_stop (GnomeXSettingsManager *manager)
 {
         GnomeXSettingsManagerPrivate *p = manager->priv;
-        GConfClient *client;
         int i;
 
         g_debug ("Stopping xsettings manager");
@@ -829,17 +754,14 @@ gnome_xsettings_manager_stop (GnomeXSettingsManager *manager)
                 p->managers = NULL;
         }
 
-        g_object_unref (manager->priv->font_settings);
+        g_object_unref (manager->priv->plugin_settings);
         stop_fontconfig_monitor (manager);
 
-        /* Stopping GTK+ modules */
-        client = gconf_client_get_default ();
-        gconf_client_remove_dir (client, GTK_MODULES_DIR, NULL);
-        gconf_client_notify_remove (client, p->gtk_modules_notify);
-        p->gtk_modules_notify = 0;
-
         g_hash_table_destroy (p->settings);
         p->settings = NULL;
+
+        g_object_unref (p->gtk);
+        p->gtk = NULL;
 }
 
 static void
diff --git a/plugins/xsettings/test-gtk-modules.c b/plugins/xsettings/test-gtk-modules.c
new file mode 100644
index 0000000..dd117f1
--- /dev/null
+++ b/plugins/xsettings/test-gtk-modules.c
@@ -0,0 +1,33 @@
+
+
+#include "gsd-xsettings-gtk.h"
+
+static void
+gtk_modules_callback (GsdXSettingsGtk       *gtk,
+		      GParamSpec            *spec,
+		      gpointer               user_data)
+{
+	const char *modules;
+
+	modules = gsd_xsettings_get_modules (gtk);
+	g_message ("GTK+ modules list changed to: %s", modules ? modules : "(empty)");
+}
+
+int main (int argc, char **argv)
+{
+	GMainLoop *loop;
+	GsdXSettingsGtk *gtk;
+
+	g_type_init ();
+
+	gtk = gsd_xsettings_gtk_new ();
+        g_signal_connect (G_OBJECT (gtk), "notify::gtk-modules",
+			  G_CALLBACK (gtk_modules_callback), NULL);
+
+	gtk_modules_callback (gtk, NULL, NULL);
+
+	loop = g_main_loop_new (NULL, TRUE);
+	g_main_loop_run (loop);
+
+	return 0;
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]