[accounts-dialog] Implement login options saving
- From: Matthias Clasen <matthiasc src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [accounts-dialog] Implement login options saving
- Date: Wed, 20 Jan 2010 19:19:40 +0000 (UTC)
commit a9caf59c8f6c1ecc8be9af2a57187e3b8f5f8cdf
Author: Matthias Clasen <mclasen redhat com>
Date: Wed Jan 20 13:40:12 2010 -0500
Implement login options saving
Autologin is saved via the SetAutomaticLogin method in the accounts-service,
all the others are saved via the GConf defaults mechanism to the mandatory
GConf database. One icky aspect of this is that we have to run
gconftool-2 directly to get updates of the current state, since gconfd
does not notice changes in the defaults and mandatory databases.
At the same time, try using a PolkitLockButton for controlling access
to the login options page.
configure.ac | 3 +-
src/Makefile.am | 2 +
src/um-login-options.c | 253 +++++++++++++++++++++++++++++++++++++++++-------
3 files changed, 221 insertions(+), 37 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 98d7feb..fa72053 100644
--- a/configure.ac
+++ b/configure.ac
@@ -36,8 +36,9 @@ PKG_CHECK_MODULES(GTK, gtk+-2.0)
PKG_CHECK_MODULES(GNOME_DESKTOP, gnome-desktop-2.0)
PKG_CHECK_MODULES(DBUS_GLIB, dbus-glib-1)
PKG_CHECK_MODULES(UNIQUE, unique-1.0)
-PKG_CHECK_MODULES(POLKIT, polkit-gobject-1)
+PKG_CHECK_MODULES(POLKIT, polkit-gtk-1)
PKG_CHECK_MODULES(DBUS_GLIB, dbus-glib-1)
+PKG_CHECK_MODULES(GCONF, gconf-2.0)
PKG_CHECK_MODULES(CHEESE, cheese-gtk, have_cheese=yes, have_cheese=no)
if test x$have_cheese = xyes ; then
diff --git a/src/Makefile.am b/src/Makefile.am
index d05d2ad..5a40447 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,6 +13,7 @@ INCLUDES = \
$(POLKIT_CFLAGS) \
$(CHEESE_CFLAGS) \
$(DBUS_GLIB_CFLAGS) \
+ $(GCONF_CFLAGS) \
$(WARN_CFLAGS)
accounts_dialog_SOURCES = \
@@ -60,6 +61,7 @@ accounts_dialog_LDADD = \
$(POLKIT_LIBS) \
$(CHEESE_LIBS) \
$(DBUS_GLIB_LIBS) \
+ $(GCONF_LIBS) \
-lcrypt
MARSHALFILES = marshal.c marshal.h
diff --git a/src/um-login-options.c b/src/um-login-options.c
index 42a19fc..5cab924 100644
--- a/src/um-login-options.c
+++ b/src/um-login-options.c
@@ -25,23 +25,31 @@
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
+#include <sys/wait.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
+#include <gconf/gconf-client.h>
+#include <gconf/gconf-value.h>
+#include <polkitgtk/polkitgtk.h>
#include "um-login-options.h"
#include "um-user-manager.h"
#include "um-user.h"
struct _UmLoginOptions {
- GtkWidget *autologin_combo;
- GtkWidget *userlist_check;
- GtkWidget *power_check;
- GtkWidget *hints_check;
- GtkWidget *guest_check;
+ GtkWidget *autologin_combo;
+ GtkWidget *userlist_check;
+ GtkWidget *power_check;
+ GtkWidget *hints_check;
+ GtkWidget *guest_check;
+ GtkWidget *lock_button;
- UmUserManager *manager;
+ UmUserManager *manager;
+
+ DBusGProxy *proxy;
+ DBusGConnection *connection;
};
enum {
@@ -85,31 +93,37 @@ sort_login_users (GtkTreeModel *model,
static void
user_added (UmUserManager *um, UmUser *user, UmLoginOptions *d)
{
- GtkComboBox *combo;
- GtkListStore *store;
- GtkTreeIter iter;
+ GtkComboBox *combo;
+ GtkListStore *store;
+ GtkTreeIter iter;
- combo = GTK_COMBO_BOX (d->autologin_combo);
+ g_debug ("adding user '%s', %d", um_user_get_user_name (user), um_user_get_automatic_login (user));
+ combo = GTK_COMBO_BOX (d->autologin_combo);
store = (GtkListStore*)gtk_combo_box_get_model (combo);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
AUTOLOGIN_NAME_COL, um_user_get_real_name (user),
AUTOLOGIN_USER_COL, user,
-1);
+
+ if (um_user_get_automatic_login (user)) {
+ gtk_combo_box_set_active_iter (combo, &iter);
+ }
}
static void
user_removed (UmUserManager *um, UmUser *user, UmLoginOptions *d)
{
- GtkComboBox *combo;
- GtkTreeModel *model;
- GtkListStore *store;
- GtkTreeIter iter;
- UmUser *u;
+ GtkComboBox *combo;
+ GtkTreeModel *model;
+ GtkListStore *store;
+ GtkTreeIter iter;
+ UmUser *u;
- combo = GTK_COMBO_BOX (d->autologin_combo);
+ combo = GTK_COMBO_BOX (d->autologin_combo);
model = gtk_combo_box_get_model (combo);
store = (GtkListStore*)model;
+
gtk_combo_box_get_active_iter (combo, &iter);
gtk_tree_model_get (model, &iter, AUTOLOGIN_USER_COL, &u, -1);
if (u != NULL) {
@@ -143,15 +157,15 @@ user_changed (UmUserManager *manager,
UmUser *user,
UmLoginOptions *d)
{
- /* FIXME */
+ /* FIXME */
}
static void
users_loaded (UmUserManager *manager,
UmLoginOptions *d)
{
- GSList *list, *l;
- UmUser *user;
+ GSList *list, *l;
+ UmUser *user;
list = um_user_manager_list_users (manager);
for (l = list; l; l = l->next) {
@@ -165,32 +179,167 @@ users_loaded (UmUserManager *manager,
g_signal_connect (manager, "user-changed", G_CALLBACK (user_changed), d);
}
+static void update_login_options (GtkWidget *widget, UmLoginOptions *d);
+
+static void
+update_boolean_from_gconf (GtkWidget *widget,
+ UmLoginOptions *d)
+{
+ gchar *cmdline;
+ gboolean value;
+ gchar *std_out;
+ gchar *std_err;
+ gint status;
+ GError *error;
+ const gchar *key;
+
+ key = g_object_get_data (G_OBJECT (widget), "gconf-key");
+
+ cmdline = g_strdup_printf ("gconftool-2 --direct --config-source=\"xml:readonly:/ect/gconf/gconf.xml.defaults;xml:readonly:/etc/gconf/gconf.xml.mandatory\" --get %s", key);
+
+ error = NULL;
+ std_out = NULL;
+ std_err = NULL;
+ if (!g_spawn_command_line_sync (cmdline, &std_out, &std_err, &status, &error)) {
+ g_warning ("Failed to run '%s': %s", cmdline, error->message);
+ g_error_free (error);
+ g_free (cmdline);
+ g_free (std_out);
+ g_free (std_err);
+ return;
+ }
+ if (WEXITSTATUS (status) != 0) {
+ g_warning ("Failed to run '%s': %s", cmdline, std_err);
+ g_free (cmdline);
+ g_free (std_out);
+ g_free (std_err);
+ return;
+ }
+
+ if (std_out[strlen (std_out) - 1] == '\n') {
+ std_out[strlen (std_out) - 1] = 0;
+ }
+
+ if (g_strcmp0 (std_out, "true") == 0) {
+ value = TRUE;
+ }
+ else {
+ value = FALSE;
+ }
+ g_signal_handlers_block_by_func (widget, update_login_options, d);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), !value);
+ g_signal_handlers_unblock_by_func (widget, update_login_options, d);
+
+ g_free (cmdline);
+ g_free (std_out);
+ g_free (std_err);
+}
+
static void
update_login_options (GtkWidget *widget,
UmLoginOptions *d)
{
+ GError *error;
+ gboolean active;
+ GConfValue *value;
+ const gchar *key = NULL;
+ gchar *value_string;
+
+ if (widget == d->userlist_check ||
+ widget == d->power_check) {
+ active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+ key = g_object_get_data (G_OBJECT (widget), "gconf-key");
+ }
+ else {
+ g_warning ("unhandled option in update_login_options");
+ return;
+ }
+
+ error = NULL;
+ value = gconf_value_new (GCONF_VALUE_BOOL);
+ gconf_value_set_bool (value, !active);
+ value_string = gconf_value_encode (value);
+ if (!dbus_g_proxy_call (d->proxy, "SetMandatoryValue",
+ &error,
+ G_TYPE_STRING, key,
+ G_TYPE_STRING, value_string,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID)) {
+ g_warning ("error calling SetMandatoryValue: %s\n", error->message);
+ g_error_free (error);
+ }
+ g_free (value_string);
+ gconf_value_free (value);
+ update_boolean_from_gconf (widget, d);
+}
+
+static void
+update_autologin (GtkWidget *widget,
+ UmLoginOptions *d)
+{
+ GtkComboBox *combo = GTK_COMBO_BOX (widget);
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ UmUserManager *manager;
+ UmUser *user;
+ gboolean enabled;
+
+ if (!gtk_widget_is_sensitive (widget))
+ return;
+
+ model = gtk_combo_box_get_model (combo);
+ gtk_combo_box_get_active_iter (combo, &iter);
+ gtk_tree_model_get (model, &iter, AUTOLOGIN_USER_COL, &user, -1);
+ if (user) {
+ enabled = TRUE;
+ }
+ else {
+ enabled = FALSE;
+
+ manager = um_user_manager_ref_default ();
+ user = um_user_manager_get_user_by_id (manager, getuid ());
+ g_object_unref (manager);
+ }
+
+ um_user_set_automatic_login (user, enabled);
+}
+
+static void
+lockbutton_changed (PolkitLockButton *button,
+ gpointer data)
+{
+ UmLoginOptions *d = data;
+ gboolean authorized;
+
+ authorized = polkit_lock_button_get_is_authorized (button);
+
+ gtk_widget_set_sensitive (d->autologin_combo, authorized);
+ gtk_widget_set_sensitive (d->userlist_check, authorized);
+ gtk_widget_set_sensitive (d->power_check, authorized);
+ gtk_widget_set_sensitive (d->hints_check, authorized);
+ gtk_widget_set_sensitive (d->guest_check, authorized);
}
UmLoginOptions *
um_login_options_new (GtkBuilder *builder)
{
GtkWidget *widget;
+ GtkWidget *box;
GtkListStore *store;
GtkTreeIter iter;
- gchar *filename;
- GError *error;
- UmLoginOptions *um;
+ GError *error;
+ UmLoginOptions *um;
/* TODO: get actual login screen options */
- um = g_new0 (UmLoginOptions, 1);
+ um = g_new0 (UmLoginOptions, 1);
- um->manager = um_user_manager_ref_default ();
- g_signal_connect (um->manager, "users-loaded",
+ um->manager = um_user_manager_ref_default ();
+ g_signal_connect (um->manager, "users-loaded",
G_CALLBACK (users_loaded), um);
- widget = (GtkWidget *) gtk_builder_get_object (builder, "dm-automatic-login-combobox");
- um->autologin_combo = widget;
+ widget = (GtkWidget *) gtk_builder_get_object (builder, "dm-automatic-login-combobox");
+ um->autologin_combo = widget;
store = gtk_list_store_new (2, G_TYPE_STRING, UM_TYPE_USER);
gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (store));
@@ -203,26 +352,58 @@ um_login_options_new (GtkBuilder *builder)
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
g_signal_connect (widget, "changed",
- G_CALLBACK (update_login_options), um);
+ G_CALLBACK (update_autologin), um);
- widget = (GtkWidget *) gtk_builder_get_object (builder, "dm-show-user-list-checkbutton");
- um->userlist_check = widget;
+ widget = (GtkWidget *) gtk_builder_get_object (builder, "dm-show-user-list-checkbutton");
+ um->userlist_check = widget;
g_signal_connect (widget, "toggled",
G_CALLBACK (update_login_options), um);
+ g_object_set_data (G_OBJECT (widget), "gconf-key",
+ "/apps/gdm/simple-greeter/disable_user_list");
+ update_boolean_from_gconf (widget, um);
- widget = (GtkWidget *) gtk_builder_get_object (builder, "dm-show-power-buttons-checkbutton");
- um->power_check = widget;
+ widget = (GtkWidget *) gtk_builder_get_object (builder, "dm-show-power-buttons-checkbutton");
+ um->power_check = widget;
g_signal_connect(widget, "toggled",
G_CALLBACK (update_login_options), um);
+ g_object_set_data (G_OBJECT (widget), "gconf-key",
+ "/apps/gdm/simple-greeter/disable_restart_buttons");
+ update_boolean_from_gconf (widget, um);
- widget = (GtkWidget *) gtk_builder_get_object (builder, "dm-show-password-hints-checkbutton");
- um->hints_check = widget;
+ widget = (GtkWidget *) gtk_builder_get_object (builder, "dm-show-password-hints-checkbutton");
+ um->hints_check = widget;
g_signal_connect (widget, "toggled",
G_CALLBACK (update_login_options), um);
- widget = (GtkWidget *) gtk_builder_get_object (builder, "dm-allow-guest-login-checkbutton");
- um->guest_check = widget;
+ widget = (GtkWidget *) gtk_builder_get_object (builder, "dm-allow-guest-login-checkbutton");
+ um->guest_check = widget;
g_signal_connect (widget, "toggled",
G_CALLBACK (update_login_options), um);
+
+ widget = polkit_lock_button_new ("org.freedesktop.accounts.set-login-option");
+ gtk_widget_show (widget);
+ box = (GtkWidget *)gtk_builder_get_object (builder, "main-login-window-vbox");
+ gtk_box_pack_end (GTK_BOX (box), widget, FALSE, FALSE, 0);
+ g_signal_connect (widget, "changed",
+ G_CALLBACK (lockbutton_changed), um);
+ lockbutton_changed (POLKIT_LOCK_BUTTON (widget), um);
+
+ error = NULL;
+ um->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (error != NULL) {
+ g_warning ("Failed to get system bus connection: %s", error->message);
+ g_error_free (error);
+ }
+
+ um->proxy = dbus_g_proxy_new_for_name (um->connection,
+ "org.gnome.GConf.Defaults",
+ "/",
+ "org.gnome.GConf.Defaults");
+
+ if (um->proxy == NULL) {
+ g_warning ("Cannot connect to GConf defaults mechanism");
+ }
+
+ return um;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]