Re: Using GSettings to set for all users

On Thu, 2010-06-03 at 10:30 -0400, Matthias Clasen wrote:
> On Thu, Jun 3, 2010 at 5:15 AM, Richard Hughes <hughsient gmail com> wrote:
> >              The only remaining bits to port is the "set default"
> > button which sets the per-user settings for all users.  ....  I'm
> > unsure on how to port this in a GSettings/dconf world.
> This was being discussed between Ryan and David just yesterday. I'm
> sure Ryan can shed some light on the current plans.

So first of all, a little bit of knowledge about how dconf and GSettings
handle access to the system defaults database:

Both systems support the concept of "context" to allow you to access
something other than the user's normal database of settings.  You can
give a context of "default" to access the system default settings, for

My current thinking for the write-to-defaults API is along these lines:

GSettings exposes via is_writable() if a key is writable at this moment.
In the case that the key may become writable in the future, given proper
policy kit authentication then this function still returns FALSE.  This
allows preferences dialogs with "unlock" buttons to work properly and
show the controls as insensitive while the dialog is "locked".

Probably I will add a new API:

gboolean g_settings_canhasprivs(GSettings *);

This will return TRUE if it's possible that the user might gain
additional privileges from authenticating against PolicyKit.


void g_settings_gimmeprivs(GSettings *);

Will actually go and try to get those privs.  This function is
non-blocking -- all it does is send a request to PolicyKit to give the
privs and return immediately.  If and when the privs are successfully
granted this will be reflected by the is_writable() property returning
TRUE (and the application will be notified by the writability-changed
signal).  The same thing would happen if the privileges were requested
by another application but affected this one.  I like this approach.

So that's the story for the "unlock this dialog" case, but I understand
that there is another case for "copy some setting to the defaults".

Given the API that I plan to add for the previously mentioned case, you
could almost do this for yourself:

  GSettings *prefs = g_settings_new ("my.prefs");

... you are doing stuff with prefs, then the user clicks <Make Default>

  GSettings *def = g_settings_new_with_context ("my.prefs", "default");
  if (!g_settings_is_writable (def, "key") &&
  g_settings_set_value (def, "key",
                        g_settings_get_value (prefs, "key"));

this could work, but the problem is that gimmeprivs() won't block until
you have the privs, so the set_value() call that you try to do too
quickly will fail.

What is needed is three new calls implementing a variant of
gimmeprivs().  These three calls are of course the traditional _sync(),
_async() and _finish() calls.  In this case, the application will be
able to detect when the authentication has succeeded (or failed) and go
ahead with the write (or bail out) accordingly.

Probably I will add these.

Finally, it might be useful to have a helper to do all of this:

gboolean g_settings_push (GSettings    *settings,
                          const gchar  *key,
                          const gchar  *context,
                          GError      **error);

that does all of the above internally.

you would use it like this:

  g_settings_push (prefs, "my-key", "default", NULL);

which would block your app, pop up a PolKit dialog and do its thing,
returning TRUE on success.

of course, there would be a _sync/_finish version too.

So, 8 new functions:
  - canhasprivs
  - gimmeprivs
  - gimmeprivs_sync
  - gimmeprivs_async
  - gimmeprivs_finish
  - push
  - push_async
  - push_finish

It's possible that i don't expose the _sync/_async/_finish versions of
gimmeprivs because with _push() there is no real use case for having

That's it.  Bye :)

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