[gnome-control-center/wip/region-panel] Implement the login page
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center/wip/region-panel] Implement the login page
- Date: Wed, 30 Jan 2013 00:11:40 +0000 (UTC)
commit 44e40e5cef119ceda54d3012b5f6290ff3d578de
Author: Matthias Clasen <mclasen redhat com>
Date: Tue Jan 29 17:30:28 2013 -0500
Implement the login page
We are now saving language and layout information to logind.
panels/region/cc-region-panel.c | 592 ++++++++++++++++++++++++++++++++++-----
panels/region/region.ui | 11 +
2 files changed, 537 insertions(+), 66 deletions(-)
---
diff --git a/panels/region/cc-region-panel.c b/panels/region/cc-region-panel.c
index 54b98fc..1fa24f1 100644
--- a/panels/region/cc-region-panel.c
+++ b/panels/region/cc-region-panel.c
@@ -21,7 +21,10 @@
#include <config.h>
#include <glib/gi18n.h>
+#include <gio/gio.h>
#include <gio/gdesktopappinfo.h>
+#include <gtk/gtk.h>
+#include <polkit/polkit.h>
#include "cc-region-panel.h"
#include "cc-region-resources.h"
@@ -30,8 +33,6 @@
#include "cc-input-chooser.h"
#include "cc-input-options.h"
-#include <gtk/gtk.h>
-
#include "cc-common-language.h"
#define GNOME_DESKTOP_USE_UNSTABLE_API
@@ -78,13 +79,26 @@ CC_PANEL_REGISTER (CcRegionPanel, cc_region_panel)
#define REGION_PANEL_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_REGION_PANEL, CcRegionPanelPrivate))
+typedef enum {
+ CHOOSE_LANGUAGE,
+ ADD_INPUT,
+ REMOVE_INPUT
+} SystemOp;
+
struct _CcRegionPanelPrivate {
GtkBuilder *builder;
- GtkWidget *login_button;
+ GtkWidget *login_button;
+ GtkWidget *login_label;
+ gboolean login;
+ GPermission *permission;
+ SystemOp op;
+ GDBusProxy *localed;
+
GtkWidget *overlay;
GtkWidget *notification;
+ GtkWidget *language_section;
GtkWidget *language_row;
GtkWidget *language_label;
GtkWidget *formats_row;
@@ -96,7 +110,10 @@ struct _CcRegionPanelPrivate {
gchar *language;
gchar *region;
+ gchar *system_language;
+ gchar *system_region;
+ GtkWidget *input_section;
GtkWidget *options_button;
GtkWidget *input_list;
GtkWidget *add_input;
@@ -121,6 +138,8 @@ cc_region_panel_finalize (GObject *object)
priv->user_manager = NULL;
priv->user = NULL;
+ g_clear_object (&priv->permission);
+ g_clear_object (&priv->localed);
g_clear_object (&priv->builder);
g_clear_object (&priv->locale_settings);
g_clear_object (&priv->input_settings);
@@ -130,6 +149,10 @@ cc_region_panel_finalize (GObject *object)
g_cancellable_cancel (priv->ibus_cancellable);
g_clear_object (&priv->ibus_cancellable);
g_clear_pointer (&priv->ibus_engines, g_hash_table_destroy);
+ g_free (priv->language);
+ g_free (priv->region);
+ g_free (priv->system_language);
+ g_free (priv->system_region);
G_OBJECT_CLASS (cc_region_panel_parent_class)->finalize (object);
}
@@ -142,14 +165,8 @@ cc_region_panel_constructed (GObject *object)
G_OBJECT_CLASS (cc_region_panel_parent_class)->constructed (object);
- priv->login_button = gtk_toggle_button_new_with_label (_("Login Screen"));
-
cc_shell_embed_widget_in_header (cc_panel_get_shell (CC_PANEL (object)),
priv->login_button);
-
- g_object_bind_property (priv->user_manager, "has-multiple-users",
- priv->login_button, "visible",
- G_BINDING_SYNC_CREATE);
}
static const char *
@@ -239,17 +256,26 @@ update_separator_func (GtkWidget **separator,
}
}
+static void set_localed_locale (CcRegionPanel *self,
+ const gchar *language);
+
static gboolean
update_language (CcRegionPanel *self,
const gchar *language)
{
CcRegionPanelPrivate *priv = self->priv;
- if (g_strcmp0 (language, priv->language) == 0)
- return FALSE;
-
- act_user_set_language (priv->user, language);
- return TRUE;
+ if (priv->login) {
+ if (g_strcmp0 (language, priv->system_language) == 0)
+ return FALSE;
+ set_localed_locale (self, language);
+ return FALSE; /* don't show notification for login */
+ } else {
+ if (g_strcmp0 (language, priv->language) == 0)
+ return FALSE;
+ act_user_set_language (priv->user, language);
+ return TRUE;
+ }
}
static void
@@ -309,35 +335,118 @@ format_response (GtkDialog *chooser,
}
static void
-activate_language_child (CcRegionPanel *self, GtkWidget *child)
+show_language_chooser (CcRegionPanel *self,
+ const gchar *language)
{
- CcRegionPanelPrivate *priv = self->priv;
+ GtkWidget *toplevel;
GtkWidget *chooser;
+
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self));
+ chooser = cc_language_chooser_new (toplevel);
+ cc_language_chooser_set_language (chooser, language);
+ g_signal_connect (chooser, "response",
+ G_CALLBACK (language_response), self);
+ gtk_window_present (GTK_WINDOW (chooser));
+}
+
+static void show_input_chooser (CcRegionPanel *self);
+static void remove_selected_input (CcRegionPanel *self);
+
+static void
+permission_acquired (GObject *source,
+ GAsyncResult *res,
+ gpointer data)
+{
+ CcRegionPanel *self = data;
+ CcRegionPanelPrivate *priv = self->priv;
+ GError *error = NULL;
+ gboolean allowed;
+
+ allowed = g_permission_acquire_finish (priv->permission, res, &error);
+ if (error) {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ g_warning ("Failed to acquire permission: %s\n", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ if (allowed) {
+ switch (priv->op) {
+ case CHOOSE_LANGUAGE:
+ show_language_chooser (self, priv->system_language);
+ break;
+ case ADD_INPUT:
+ show_input_chooser (self);
+ break;
+ case REMOVE_INPUT:
+ remove_selected_input (self);
+ break;
+ default:
+ g_warning ("Unknown privileged operation: %d\n", priv->op);
+ break;
+ }
+ }
+}
+
+static void
+show_format_chooser (CcRegionPanel *self)
+{
+ CcRegionPanelPrivate *priv = self->priv;
GtkWidget *toplevel;
+ GtkWidget *chooser;
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self));
+ chooser = cc_format_chooser_new (toplevel);
+ cc_format_chooser_set_region (chooser, priv->region);
+ g_signal_connect (chooser, "response",
+ G_CALLBACK (format_response), self);
+ gtk_window_present (GTK_WINDOW (chooser));
+}
+
+static void
+activate_language_child (CcRegionPanel *self, GtkWidget *child)
+{
+ CcRegionPanelPrivate *priv = self->priv;
+
if (child == priv->language_row) {
- chooser = cc_language_chooser_new (toplevel);
- cc_language_chooser_set_language (chooser, priv->language);
- g_signal_connect (chooser, "response",
- G_CALLBACK (language_response), self);
- gtk_window_present (GTK_WINDOW (chooser));
+ if (!priv->login) {
+ show_language_chooser (self, priv->language);
+ } else if (g_permission_get_allowed (priv->permission)) {
+ show_language_chooser (self, priv->system_language);
+ } else if (g_permission_get_can_acquire (priv->permission)) {
+ priv->op = CHOOSE_LANGUAGE;
+ g_permission_acquire_async (priv->permission,
+ NULL,
+ permission_acquired,
+ self);
+ }
} else if (child == priv->formats_row) {
- chooser = cc_format_chooser_new (toplevel);
- cc_format_chooser_set_region (chooser, priv->region);
- g_signal_connect (chooser, "response",
- G_CALLBACK (format_response), self);
- gtk_window_present (GTK_WINDOW (chooser));
+ show_format_chooser (self);
}
}
static void
-update_language_from_user (CcRegionPanel *self)
+update_language_label (CcRegionPanel *self)
{
CcRegionPanelPrivate *priv = self->priv;
const gchar *language;
gchar *name;
+ if (priv->login)
+ language = priv->system_language;
+ else
+ language = priv->language;
+ name = gnome_get_language_from_name (language, language);
+ gtk_label_set_label (GTK_LABEL (priv->language_label), name);
+ g_free (name);
+}
+
+static void
+update_language_from_user (CcRegionPanel *self)
+{
+ CcRegionPanelPrivate *priv = self->priv;
+ const gchar *language;
+
if (act_user_is_loaded (priv->user))
language = act_user_get_language (priv->user);
else
@@ -345,9 +454,7 @@ update_language_from_user (CcRegionPanel *self)
g_free (priv->language);
priv->language = g_strdup (language);
- name = gnome_get_language_from_name (language, language);
- gtk_label_set_label (GTK_LABEL (priv->language_label), name);
- g_free (name);
+ update_language_label (self);
}
static void
@@ -358,7 +465,6 @@ update_region_from_setting (CcRegionPanel *self)
g_free (priv->region);
priv->region = g_settings_get_string (priv->locale_settings, KEY_REGION);
- g_print ("set label to %s\n", priv->region);
name = gnome_get_region_from_name (priv->region, priv->region);
gtk_label_set_label (GTK_LABEL (priv->formats_label), name);
g_free (name);
@@ -370,7 +476,6 @@ setup_language_section (CcRegionPanel *self)
CcRegionPanelPrivate *priv = self->priv;
GtkWidget *widget;
- priv->user_manager = act_user_manager_get_default ();
priv->user = act_user_manager_get_user_by_id (priv->user_manager, getuid ());
g_signal_connect_swapped (priv->user, "notify::language",
G_CALLBACK (update_language_from_user), self);
@@ -381,6 +486,7 @@ setup_language_section (CcRegionPanel *self)
g_signal_connect_swapped (priv->locale_settings, "changed::" KEY_REGION,
G_CALLBACK (update_region_from_setting), self);
+ priv->language_section = WID ("language_section");
priv->language_row = WID ("language_row");
priv->language_label = WID ("language_label");
priv->formats_row = WID ("formats_row");
@@ -563,10 +669,10 @@ add_input_row (CcRegionPanel *self,
}
static void
-populate_with_active_sources (CcRegionPanel *self)
+add_input_sources (CcRegionPanel *self,
+ GVariant *sources)
{
CcRegionPanelPrivate *priv = self->priv;
- GVariant *sources;
GVariantIter iter;
const gchar *type;
const gchar *id;
@@ -574,7 +680,6 @@ populate_with_active_sources (CcRegionPanel *self)
gchar *display_name;
GDesktopAppInfo *app_info;
- sources = g_settings_get_value (priv->input_settings, "sources");
g_variant_iter_init (&iter, sources);
while (g_variant_iter_next (&iter, "(&s&s)", &type, &id)) {
display_name = NULL;
@@ -609,16 +714,26 @@ populate_with_active_sources (CcRegionPanel *self)
g_free (display_name);
g_clear_object (&app_info);
}
+}
+
+static void
+add_input_sources_from_settings (CcRegionPanel *self)
+{
+ CcRegionPanelPrivate *priv = self->priv;
+ GVariant *sources;
+ sources = g_settings_get_value (priv->input_settings, "sources");
+ add_input_sources (self, sources);
g_variant_unref (sources);
}
static void
-container_remove_all (GtkContainer *container)
+clear_input_sources (CcRegionPanel *self)
{
+ CcRegionPanelPrivate *priv = self->priv;
GList *list, *l;
- list = gtk_container_get_children (container);
+ list = gtk_container_get_children (GTK_CONTAINER (priv->input_list));
for (l = list; l; l = l->next) {
- gtk_container_remove (container, GTK_WIDGET (l->data));
+ gtk_container_remove (GTK_CONTAINER (priv->input_list), GTK_WIDGET (l->data));
}
g_list_free (list);
}
@@ -655,8 +770,8 @@ input_sources_changed (GSettings *settings,
selected = egg_list_box_get_selected_child (EGG_LIST_BOX (priv->input_list));
if (selected)
id = (const gchar *)g_object_get_data (G_OBJECT (selected), "id");
- container_remove_all (GTK_CONTAINER (priv->input_list));
- populate_with_active_sources (self);
+ clear_input_sources (self);
+ add_input_sources_from_settings (self);
if (id)
select_input (self, id);
}
@@ -688,11 +803,13 @@ update_button_sensitivity (CcRegionPanel *self)
gtk_widget_set_sensitive (priv->show_layout, TRUE);
gtk_widget_set_sensitive (priv->remove_input, multiple_sources);
}
- gtk_widget_set_visible (priv->options_button, multiple_sources);
+
+ gtk_widget_set_visible (priv->options_button,
+ multiple_sources && !priv->login);
}
static void
-update_configuration (CcRegionPanel *self)
+set_input_settings (CcRegionPanel *self)
{
CcRegionPanelPrivate *priv = self->priv;
const gchar *type;
@@ -740,6 +857,20 @@ update_configuration (CcRegionPanel *self)
g_variant_unref (old_sources);
}
+static void set_localed_input (CcRegionPanel *self);
+
+static void
+update_input (CcRegionPanel *self)
+{
+ CcRegionPanelPrivate *priv = self->priv;
+
+ if (priv->login) {
+ set_localed_input (self);
+ } else {
+ set_input_settings (self);
+ }
+}
+
static void
select_input_child (CcRegionPanel *self, GtkWidget *child)
{
@@ -747,40 +878,74 @@ select_input_child (CcRegionPanel *self, GtkWidget *child)
}
static void
-chooser_response (GtkWidget *chooser, gint response_id, gpointer data)
+apologize_for_no_ibus_login (CcRegionPanel *self)
+{
+ GtkWidget *dialog;
+ GtkWidget *toplevel;
+ GtkWidget *image;
+
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self));
+
+ dialog = gtk_message_dialog_new (GTK_WINDOW (toplevel),
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_OTHER,
+ GTK_BUTTONS_OK,
+ _("Sorry"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ "%s", _("Input methods can't be used on the login screen"));
+ image = gtk_image_new_from_icon_name ("face-sad-symbolic",
+ GTK_ICON_SIZE_DIALOG);
+ gtk_widget_show (image);
+ gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), image);
+
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+}
+
+static void
+input_response (GtkWidget *chooser, gint response_id, gpointer data)
{
CcRegionPanel *self = data;
- CcRegionPanelPrivate *priv = self->priv;
+ CcRegionPanelPrivate *priv = self->priv;
gchar *type;
gchar *id;
gchar *name;
GDesktopAppInfo *app_info = NULL;
- if (cc_input_chooser_get_selected (chooser, &type, &id, &name)) {
- if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS)) {
- g_free (type);
- type = INPUT_SOURCE_TYPE_IBUS;
+ if (response_id == GTK_RESPONSE_OK) {
+ if (cc_input_chooser_get_selected (chooser, &type, &id, &name)) {
+
+ gtk_widget_destroy (chooser);
+
+ if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS)) {
+ g_free (type);
+ type = INPUT_SOURCE_TYPE_IBUS;
#ifdef HAVE_IBUS
- app_info = setup_app_info_for_id (id);
+ app_info = setup_app_info_for_id (id);
#endif
- } else {
- g_free (type);
- type = INPUT_SOURCE_TYPE_XKB;
- }
- add_input_row (self, type, id, name, app_info);
- g_free (id);
- g_free (name);
- g_clear_object (&app_info);
+ } else {
+ g_free (type);
+ type = INPUT_SOURCE_TYPE_XKB;
+ }
- update_button_sensitivity (self);
- update_configuration (self);
+ if (priv->login && g_str_equal (type, INPUT_SOURCE_TYPE_IBUS)) {
+ apologize_for_no_ibus_login (self);
+ } else {
+ add_input_row (self, type, id, name, app_info);
+ update_button_sensitivity (self);
+ update_input (self);
+ }
+ g_free (id);
+ g_free (name);
+ g_clear_object (&app_info);
+ }
+ } else {
+ gtk_widget_destroy (chooser);
}
-
- gtk_widget_destroy (chooser);
}
static void
-add_input (CcRegionPanel *self)
+show_input_chooser (CcRegionPanel *self)
{
CcRegionPanelPrivate *priv = self->priv;
GtkWidget *chooser;
@@ -791,7 +956,25 @@ add_input (CcRegionPanel *self)
priv->xkb_info,
priv->ibus_engines);
g_signal_connect (chooser, "response",
- G_CALLBACK (chooser_response), self);
+ G_CALLBACK (input_response), self);
+}
+
+static void
+add_input (CcRegionPanel *self)
+{
+ CcRegionPanelPrivate *priv = self->priv;
+
+ if (!priv->login) {
+ show_input_chooser (self);
+ } else if (g_permission_get_allowed (priv->permission)) {
+ show_input_chooser (self);
+ } else if (g_permission_get_can_acquire (priv->permission)) {
+ priv->op = ADD_INPUT;
+ g_permission_acquire_async (priv->permission,
+ NULL,
+ permission_acquired,
+ self);
+ }
}
static GtkWidget *
@@ -825,7 +1008,7 @@ out:
}
static void
-remove_selected_input (CcRegionPanel *self)
+do_remove_selected_input (CcRegionPanel *self)
{
CcRegionPanelPrivate *priv = self->priv;
GtkWidget *selected;
@@ -840,7 +1023,25 @@ remove_selected_input (CcRegionPanel *self)
egg_list_box_select_child (EGG_LIST_BOX (priv->input_list), sibling);
update_button_sensitivity (self);
- update_configuration (self);
+ update_input (self);
+}
+
+static void
+remove_selected_input (CcRegionPanel *self)
+{
+ CcRegionPanelPrivate *priv = self->priv;
+
+ if (!priv->login) {
+ do_remove_selected_input (self);
+ } else if (g_permission_get_allowed (priv->permission)) {
+ do_remove_selected_input (self);
+ } else if (g_permission_get_can_acquire (priv->permission)) {
+ priv->op = REMOVE_INPUT;
+ g_permission_acquire_async (priv->permission,
+ NULL,
+ permission_acquired,
+ self);
+ }
}
static void
@@ -979,6 +1180,7 @@ setup_input_section (CcRegionPanel *self)
maybe_start_ibus ();
#endif
+ priv->input_section = WID ("input_section");
priv->options_button = WID ("input_options");
priv->input_list = WID ("input_list");
priv->add_input = WID ("input_source_add");
@@ -1008,9 +1210,264 @@ setup_input_section (CcRegionPanel *self)
g_signal_connect (priv->input_settings, "changed::" KEY_INPUT_SOURCES,
G_CALLBACK (input_sources_changed), self);
- populate_with_active_sources (self);
+ add_input_sources_from_settings (self);
+ update_button_sensitivity (self);
+}
+
+static void
+on_localed_properties_changed (GDBusProxy *proxy,
+ GVariant *changed_properties,
+ const gchar **invalidated_properties,
+ CcRegionPanel *self)
+{
+ CcRegionPanelPrivate *priv = self->priv;
+ GVariant *v;
+
+ v = g_dbus_proxy_get_cached_property (proxy, "Locale");
+ if (v) {
+ const gchar **strv;
+ gsize len;
+ gint i;
+ const gchar *lang, *messages, *time;
+
+ strv = g_variant_get_strv (v, &len);
+
+ lang = messages = time = NULL;
+ for (i = 0; strv[i]; i++) {
+ if (g_str_has_prefix (strv[i], "LANG=")) {
+ lang = strv[i] + strlen ("LANG=");
+ } else if (g_str_has_prefix (strv[i], "LC_MESSAGES=")) {
+ messages = strv[i] + strlen ("LC_MESSAGES=");
+ } else if (g_str_has_prefix (strv[i], "LC_TIME=")) {
+ time = strv[i] + strlen ("LC_TIME=");
+ }
+ }
+ if (!lang) {
+ lang = "";
+ }
+ if (!messages) {
+ messages = lang;
+ }
+ if (!time) {
+ time = lang;
+ }
+ g_free (priv->system_language);
+ priv->system_language = g_strdup (messages);
+ g_free (priv->system_region);
+ priv->system_region = g_strdup (time);
+ g_variant_unref (v);
+
+ update_language_label (self);
+ }
+}
+
+static void
+add_input_sources_from_localed (CcRegionPanel *self)
+{
+ CcRegionPanelPrivate *priv = self->priv;
+ GVariant *v;
+ const gchar *s;
+ gchar **layouts = NULL;
+ gchar **variants = NULL;
+ gint i, n;
+
+ v = g_dbus_proxy_get_cached_property (priv->localed, "X11Layout");
+ if (v) {
+ s = g_variant_get_string (v, NULL);
+ layouts = g_strsplit (s, ",", -1);
+ g_variant_unref (v);
+ }
+
+ v = g_dbus_proxy_get_cached_property (priv->localed, "X11Variant");
+ if (v) {
+ s = g_variant_get_string (v, NULL);
+ if (s && *s)
+ variants = g_strsplit (s, ",", -1);
+ g_variant_unref (v);
+ }
+
+ if (variants && variants[0])
+ n = MIN (g_strv_length (layouts), g_strv_length (variants));
+ else
+ n = g_strv_length (layouts);
+
+ for (i = 0; i < n && layouts[i][0]; i++) {
+ const gchar *name;
+ gchar *id;
+
+ if (variants && variants[i] && variants[i][0])
+ id = g_strdup_printf ("%s+%s", layouts[i], variants[i]);
+ else
+ id = g_strdup (layouts[i]);
+
+ gnome_xkb_info_get_layout_info (priv->xkb_info, id, &name, NULL, NULL, NULL);
+
+ add_input_row (self, "xkb", id, name ? name : id, NULL);
+
+ g_free (id);
+ }
+
+ g_strfreev (variants);
+ g_strfreev (layouts);
+}
+
+static void
+set_localed_locale (CcRegionPanel *self,
+ const gchar *language)
+{
+ CcRegionPanelPrivate *priv = self->priv;
+ GVariantBuilder *b;
+ gchar *s;
+
+ b = g_variant_builder_new (G_VARIANT_TYPE ("as"));
+ s = g_strconcat ("LANG=", language, NULL);
+ g_variant_builder_add (b, "s", s);
+ g_free (s);
+
+ if (g_strcmp0 (priv->system_language, priv->system_region) != 0) {
+ s = g_strconcat ("LC_TIME=", priv->system_region, NULL);
+ g_variant_builder_add (b, "s", s);
+ g_free (s);
+ s = g_strconcat ("LC_NUMERIC=", priv->system_region, NULL);
+ g_variant_builder_add (b, "s", s);
+ g_free (s);
+ s = g_strconcat ("LC_MONETARY=", priv->system_region, NULL);
+ g_variant_builder_add (b, "s", s);
+ g_free (s);
+ s = g_strconcat ("LC_MEASUREMENT=", priv->system_region, NULL);
+ g_variant_builder_add (b, "s", s);
+ g_free (s);
+ s = g_strconcat ("LC_PAPER=", priv->system_region, NULL);
+ g_variant_builder_add (b, "s", s);
+ g_free (s);
+ }
+ g_dbus_proxy_call (priv->localed,
+ "SetLocale",
+ g_variant_new ("(asb)", b, TRUE),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, NULL, NULL, NULL);
+ g_variant_builder_unref (b);
+}
+static void
+set_localed_input (CcRegionPanel *self)
+{
+ CcRegionPanelPrivate *priv = self->priv;
+ GString *layouts;
+ GString *variants;
+ const gchar *type, *id;
+ GList *list, *li;
+ const gchar *l, *v;
+
+ layouts = g_string_new ("");
+ variants = g_string_new ("");
+
+ list = gtk_container_get_children (GTK_CONTAINER (priv->input_list));
+ for (li = list; li; li = li->next) {
+ type = (const gchar *)g_object_get_data (G_OBJECT (li->data), "type");
+ id = (const gchar *)g_object_get_data (G_OBJECT (li->data), "id");
+ if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS))
+ continue;
+
+ if (gnome_xkb_info_get_layout_info (priv->xkb_info, id, NULL, NULL, &l, &v)) {
+ if (layouts->str[0]) {
+ g_string_append_c (layouts, ',');
+ g_string_append_c (variants, ',');
+ }
+ g_string_append (layouts, l);
+ g_string_append (variants, v);
+ }
+ }
+ g_list_free (list);
+
+ g_dbus_proxy_call (priv->localed,
+ "SetX11Keyboard",
+ g_variant_new ("(ssssbb)", layouts->str, "", variants->str, "", TRUE, TRUE),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, NULL, NULL, NULL);
+
+ g_string_free (layouts, TRUE);
+ g_string_free (variants, TRUE);
+}
+
+static void
+localed_proxy_ready (GObject *source,
+ GAsyncResult *res,
+ gpointer data)
+{
+ CcRegionPanel *self = data;
+ CcRegionPanelPrivate *priv = self->priv;
+ GError *error = NULL;
+
+ priv->localed = g_dbus_proxy_new_finish (res, &error);
+
+ if (!priv->localed) {
+ g_warning ("Failed to contact localed: %s\n", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ g_signal_connect (priv->localed, "g-properties-changed",
+ G_CALLBACK (on_localed_properties_changed), self);
+ on_localed_properties_changed (priv->localed, NULL, NULL, self);
+}
+
+static void
+login_changed (CcRegionPanel *self)
+{
+ CcRegionPanelPrivate *priv = self->priv;
+ gboolean insensitive;
+
+ priv->login = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->login_button));
+ gtk_widget_set_visible (priv->formats_row, !priv->login);
+ gtk_widget_set_visible (priv->login_label, priv->login);
update_button_sensitivity (self);
+
+ /* FIXME: insensitive doesn't look quite right for this */
+ insensitive = priv->login &&
+ !g_permission_get_allowed (priv->permission) &&
+ !g_permission_get_can_acquire (priv->permission);
+ gtk_widget_set_sensitive (priv->language_section, !insensitive);
+ gtk_widget_set_sensitive (priv->input_section, !insensitive);
+
+ clear_input_sources (self);
+ if (priv->login)
+ add_input_sources_from_localed (self);
+ else
+ add_input_sources_from_settings (self);
+
+ update_language_label (self);
+ update_button_sensitivity (self);
+}
+
+static void
+setup_login_button (CcRegionPanel *self)
+{
+ CcRegionPanelPrivate *priv = self->priv;
+ GDBusConnection *bus;
+
+ priv->permission = polkit_permission_new_sync ("org.freedesktop.locale1.set-locale", NULL, NULL, NULL);
+ bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL);
+ g_dbus_proxy_new (bus,
+ G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES,
+ NULL,
+ "org.freedesktop.locale1",
+ "/org/freedesktop/locale1",
+ "org.freedesktop.locale1",
+ NULL,
+ (GAsyncReadyCallback) localed_proxy_ready,
+ self);
+ g_object_unref (bus);
+
+ priv->login_label = WID ("login-label");
+ priv->login_button = gtk_toggle_button_new_with_label (_("Login Screen"));
+
+ g_object_bind_property (priv->user_manager, "has-multiple-users",
+ priv->login_button, "visible",
+ G_BINDING_SYNC_CREATE);
+
+ g_signal_connect_swapped (priv->login_button, "notify::active",
+ G_CALLBACK (login_changed), self);
}
static void
@@ -1033,6 +1490,9 @@ cc_region_panel_init (CcRegionPanel *self)
return;
}
+ priv->user_manager = act_user_manager_get_default ();
+
+ setup_login_button (self);
setup_language_section (self);
setup_input_section (self);
diff --git a/panels/region/region.ui b/panels/region/region.ui
index 89b0955..f594ab0 100644
--- a/panels/region/region.ui
+++ b/panels/region/region.ui
@@ -346,6 +346,17 @@
<property name="position">1</property>
</packing>
</child>
+ <child>
+ <object class="GtkLabel" id="login-label">
+ <property name="valign">end</property>
+ <property name="vexpand">True</property>
+ <property name="label" translatable="yes">Login settings are used by all users when logging into the system</property>
+ <property name="margin_bottom">12</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ </child>
</object>
</child>
</object>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]