Index: gconf-editor-application.c
===================================================================
--- gconf-editor-application.c	(révision 1435)
+++ gconf-editor-application.c	(copie de travail)
@@ -21,6 +21,7 @@
 
 #include "gconf-util.h"
 #include "gconf-editor-window.h"
+#include "gconf-policykit.h"
 #include "gconf-tree-model.h"
 #include "gconf-list-model.h"
 #include <gtk/gtk.h>
@@ -55,11 +56,11 @@ gconf_editor_application_create_editor_w
 	gconf_tree_model_set_client (GCONF_TREE_MODEL (gconfwindow->tree_model), gconfwindow->client);
 	gconf_list_model_set_client (GCONF_LIST_MODEL (gconfwindow->list_model), gconfwindow->client);
 
-	if (!gconf_util_can_edit_defaults ())
+	if (!gconf_util_can_edit_defaults () && !gconf_pk_can_set_default ())
 		gtk_action_set_sensitive (gtk_ui_manager_get_action (gconfwindow->ui_manager, "/GConfEditorMenu/FileMenu/NewDefaultsWindow"),
 					  FALSE);
 
-	if (!gconf_util_can_edit_mandatory ())
+	if (!gconf_util_can_edit_mandatory () && !gconf_pk_can_set_mandatory ())
 		gtk_action_set_sensitive (gtk_ui_manager_get_action (gconfwindow->ui_manager, "/GConfEditorMenu/FileMenu/NewMandatoryWindow"),
 					  FALSE);
 	
Index: gconf-editor-window.c
===================================================================
--- gconf-editor-window.c	(révision 1436)
+++ gconf-editor-window.c	(copie de travail)
@@ -332,6 +332,11 @@ gconf_editor_window_new_defaults_window
 {
 	GtkWidget *new_window;
 
+	if (!gconf_util_can_edit_defaults () && !gconf_pk_can_set_default ()) {
+		/* FIXME: display an error? */
+		return;
+	}
+
 	new_window = gconf_editor_application_create_editor_window (GCONF_EDITOR_WINDOW_TYPE_DEFAULTS);
 	gtk_widget_show (new_window);
 }
@@ -341,6 +346,11 @@ gconf_editor_window_new_mandatory_window
 {
 	GtkWidget *new_window;
 
+	if (!gconf_util_can_edit_mandatory () && !gconf_pk_can_set_mandatory ()) {
+		/* FIXME: display an error? */
+		return;
+	}
+
 	new_window = gconf_editor_application_create_editor_window (GCONF_EDITOR_WINDOW_TYPE_MANDATORY);
 	gtk_widget_show (new_window);
 }
@@ -405,6 +415,70 @@ gconf_editor_window_about_window (GtkAct
 }	
 
 static void
+gconf_editor_policykit_callback (GtkWindow *window, GError *error)
+{
+  if (error)
+    gconf_editor_window_popup_error_dialog (window, _("Could not set value. Error was:\n%s"), error);
+}
+
+
+static void
+gconf_editor_set_key (GConfEditorWindow  *window,
+		      const char         *path,
+		      GConfValue         *value,
+		      GError            **error)
+{
+	gboolean direct;
+	gboolean success;
+
+	direct = FALSE;
+	success = FALSE;
+
+	switch (window->type) {
+	case GCONF_EDITOR_WINDOW_TYPE_NORMAL:
+		direct = TRUE;
+		break;
+	case GCONF_EDITOR_WINDOW_TYPE_DEFAULTS:
+		direct = gconf_util_can_edit_defaults ();
+		break;
+	case GCONF_EDITOR_WINDOW_TYPE_MANDATORY:
+		direct = gconf_util_can_edit_mandatory ();
+		break;
+	default:
+		g_assert_not_reached ();
+	}
+
+	if (direct) {
+		if (gconf_client_key_is_writable (window->client, path, error)) {
+			gconf_client_set (window->client, path, value, error);
+			success = TRUE;
+		}
+	} else {
+		guint xid;
+
+		xid = GDK_WINDOW_XWINDOW (GTK_WIDGET (window)->window);
+
+		if (window->type == GCONF_EDITOR_WINDOW_TYPE_DEFAULTS) {
+			gconf_pk_set_default_value_async (path, value, xid,
+					/* FIXME: on error, refresh the thing we set */
+							  (GFunc) gconf_editor_policykit_callback,
+							  g_object_ref (window),
+							  g_object_unref);
+			success = TRUE;
+		} else if  (window->type == GCONF_EDITOR_WINDOW_TYPE_MANDATORY) {
+			gconf_pk_set_mandatory_value_async (path, value, xid,
+							    (GFunc) gconf_editor_policykit_callback,
+							    g_object_ref (window),
+							    g_object_unref);
+			success = TRUE;
+		}
+	}
+
+	if (success)
+		gconf_add_recent_key (window, path);
+}
+
+static void
 gconf_editor_popup_window_unset_key (GtkAction *action, GtkWidget *callback_data)
 {
 	GConfEditorWindow *window = GCONF_EDITOR_WINDOW (callback_data);
@@ -467,8 +541,7 @@ gconf_editor_new_key_response (GtkDialog
 		/* Create the key */
 		value = gconf_key_editor_get_value (GCONF_KEY_EDITOR (editor));
 
-		gconf_client_set (window->client, full_path, value, NULL);
-		gconf_add_recent_key (window, full_path);
+		gconf_editor_set_key (window, full_path, value, NULL);
 
 		if(value)
 		  gconf_value_free (value);
@@ -523,11 +596,7 @@ gconf_editor_edit_key_response (GtkDialo
 		path = gconf_key_editor_get_key_name (GCONF_KEY_EDITOR (editor));
 		g_assert (gconf_valid_key (path, NULL));
 
-		/* if not writable we weren't allowed to change things anyway */
-		if (gconf_client_key_is_writable (window->client, path, &error)) {
-			gconf_client_set (window->client, path, value, &error);
-			gconf_add_recent_key (window, path);
-		}
+		gconf_editor_set_key (window, path, value, &error);
 
 		gconf_value_free (value);
 
@@ -641,13 +710,6 @@ gconf_editor_window_row_expanded (GtkTre
 }
 
 static void
-gconf_editor_popup_policykit_callback (GtkWindow *window, GError *error)
-{
-  if (error)
-    gconf_editor_window_popup_error_dialog (window, _("Could not set value. Error was:\n%s"), error);
-}
-
-static void
 gconf_editor_popup_window_set_as_default (GtkAction *action, GtkWidget *callback_data)
 {
   GConfEditorWindow *gconfwindow = GCONF_EDITOR_WINDOW (callback_data);
@@ -691,7 +753,7 @@ gconf_editor_popup_window_set_as_default
     gconf_client_suggest_sync (gconfwindow->client, NULL);
     gconf_pk_set_default_async (path,
                                 GDK_WINDOW_XWINDOW (GTK_WIDGET (window)->window),
-                                (GFunc) gconf_editor_popup_policykit_callback,
+                                (GFunc) gconf_editor_policykit_callback,
                                 g_object_ref (window), g_object_unref);
   }
 }
@@ -740,7 +802,7 @@ gconf_editor_popup_window_set_as_mandato
     gconf_client_suggest_sync (gconfwindow->client, NULL);
     gconf_pk_set_mandatory_async (path,
                                   GDK_WINDOW_XWINDOW (GTK_WIDGET (window)->window),
-                                  (GFunc) gconf_editor_popup_policykit_callback,
+                                  (GFunc) gconf_editor_policykit_callback,
                                   g_object_ref (window), g_object_unref);
   }
 }
@@ -982,10 +1044,8 @@ gconf_editor_gconf_value_changed (GConfC
 
 	/* We need to check this because the changed signal could come from an old
 	 * cell in another list_model */ 
-	if (value->type == new_value->type) {
-		gconf_client_set (window->client, key, new_value, NULL);
-		gconf_add_recent_key (window, key);
-	}
+	if (value->type == new_value->type)
+		gconf_editor_set_key (window, key, new_value, NULL);
 
 	gconf_value_free (value);
 	g_free (key);
Index: gconf-policykit.c
===================================================================
--- gconf-policykit.c	(révision 1436)
+++ gconf-policykit.c	(copie de travail)
@@ -39,6 +39,12 @@
 #include <polkit/polkit.h>
 #include <polkit-dbus/polkit-dbus.h>
 
+#include <gconf/gconf.h>
+
+/* TODO: yeah, cheating! */
+GConfValue* gconf_value_decode (const gchar *encoded);
+gchar*      gconf_value_encode (GConfValue  *val);
+
 #include "gconf-policykit.h"
 
 #define CACHE_VALIDITY_SEC 10
@@ -230,6 +236,7 @@ typedef struct {
         gint            ref_count;
         const gchar    *call;
         gchar          *key;
+        gchar          *value;
         guint           transient_parent_xid;
         GFunc           callback;
         gpointer        data;
@@ -256,6 +263,7 @@ _gconf_pk_data_unref (gpointer d)
                 if (data->notify)
                         data->notify (data->data);
                 g_free (data->key);
+                g_free (data->value);
                 g_slice_free (GConfPKCallbackData, data);
         }
 }
@@ -385,6 +393,35 @@ set_key_async (GConfPKCallbackData *data
                                               G_TYPE_INVALID);
 }
 
+static void
+set_key_value_async (GConfPKCallbackData *data)
+{
+        DBusGConnection *bus;
+        DBusGProxy      *proxy;
+
+        bus = get_system_bus ();
+        if (bus == NULL)
+                return;
+
+        proxy = dbus_g_proxy_new_for_name (bus,
+                                           "org.gnome.GConf.Defaults",
+                                           "/",
+                                           "org.gnome.GConf.Defaults");
+
+        dbus_g_proxy_begin_call_with_timeout (proxy,
+                                              data->call,
+                                              set_key_notify,
+                                              _gconf_pk_data_ref (data),
+                                              _gconf_pk_data_unref,
+                                              INT_MAX,
+                                              /* parameters: */
+                                              G_TYPE_STRING, data->key,
+                                              G_TYPE_STRING, data->value,
+                                              G_TYPE_INVALID,
+                                              /* return values: */
+                                              G_TYPE_INVALID);
+}
+
 void
 gconf_pk_set_default_async (const gchar    *key,
                             guint           transient_parent_xid,
@@ -401,6 +438,7 @@ gconf_pk_set_default_async (const gchar
         data->ref_count = 1;
         data->call = "SetSystem";
         data->key = g_strdup (key);
+        data->value = NULL;
         data->transient_parent_xid = transient_parent_xid;
         data->callback = callback;
         data->data = d;
@@ -426,6 +464,7 @@ gconf_pk_set_mandatory_async (const gcha
         data->ref_count = 1;
         data->call = "SetMandatory";
         data->key = g_strdup (key);
+        data->value = NULL;
         data->transient_parent_xid = transient_parent_xid;
         data->callback = callback;
         data->data = d;
@@ -434,3 +473,57 @@ gconf_pk_set_mandatory_async (const gcha
         set_key_async (data);
         _gconf_pk_data_unref (data);
 }
+
+void
+gconf_pk_set_default_value_async (const gchar    *key,
+                                  GConfValue     *value,
+                                  guint           transient_parent_xid,
+                                  GFunc           callback,
+                                  gpointer        d,
+                                  GDestroyNotify  notify)
+{
+        GConfPKCallbackData *data;
+
+        if (key == NULL)
+                return;
+
+        data = g_slice_new0 (GConfPKCallbackData);
+        data->ref_count = 1;
+        data->call = "SetSystemValue";
+        data->key = g_strdup (key);
+        data->value = gconf_value_encode (value);
+        data->transient_parent_xid = transient_parent_xid;
+        data->callback = callback;
+        data->data = d;
+        data->notify = notify;
+
+        set_key_value_async (data);
+        _gconf_pk_data_unref (data);
+}
+
+void
+gconf_pk_set_mandatory_value_async (const gchar    *key,
+                                    GConfValue     *value,
+                                    guint           transient_parent_xid,
+                                    GFunc           callback,
+                                    gpointer        d,
+                                    GDestroyNotify  notify)
+{
+        GConfPKCallbackData *data;
+
+        if (key == NULL)
+                return;
+
+        data = g_slice_new0 (GConfPKCallbackData);
+        data->ref_count = 1;
+        data->call = "SetMandatoryValue";
+        data->key = g_strdup (key);
+        data->value = gconf_value_encode (value);
+        data->transient_parent_xid = transient_parent_xid;
+        data->callback = callback;
+        data->data = d;
+        data->notify = notify;
+
+        set_key_value_async (data);
+        _gconf_pk_data_unref (data);
+}
Index: gconf-policykit.h
===================================================================
--- gconf-policykit.h	(révision 1436)
+++ gconf-policykit.h	(copie de travail)
@@ -26,6 +26,7 @@
 #define  __GCONF_POLICYKIT_H__
 
 #include <glib.h>
+#include <gconf/gconf.h>
 
 gint     gconf_pk_can_set_default    (void);
 
@@ -37,10 +38,24 @@ void     gconf_pk_set_default_async  (co
                                       gpointer        data,
                                       GDestroyNotify  notify);
 
+void     gconf_pk_set_default_value_async  (const gchar    *key,
+                                            GConfValue     *value,
+                                            guint           transient_parent_xid,
+                                            GFunc           callback,
+                                            gpointer        data,
+                                            GDestroyNotify  notify);
+
 void     gconf_pk_set_mandatory_async (const gchar    *key,
                                        guint           transient_parent_xid,
                                        GFunc           callback,
                                        gpointer        data,
                                        GDestroyNotify  notify);
 
+void     gconf_pk_set_mandatory_value_async  (const gchar    *key,
+                                              GConfValue     *value,
+                                              guint           transient_parent_xid,
+                                              GFunc           callback,
+                                              gpointer        data,
+                                              GDestroyNotify  notify);
+
 #endif /* __GCONF_POLICYKIT_H__ */
