Merge lp:~mterry/lightdm/get_layouts into lp:lightdm

Proposed by Michael Terry
Status: Merged
Approved by: Robert Ancell
Approved revision: 1402
Merged at revision: 1402
Proposed branch: lp:~mterry/lightdm/get_layouts
Merge into: lp:lightdm
Diff against target: 332 lines (+124/-25)
6 files modified
liblightdm-gobject/liblightdm-gobject-1.vapi (+2/-0)
liblightdm-gobject/lightdm/user.h (+2/-0)
liblightdm-gobject/user.c (+84/-10)
tests/scripts/keyboard-layout.conf (+3/-0)
tests/src/test-gobject-greeter.c (+17/-0)
tests/src/test-runner.c (+16/-15)
To merge this branch: bzr merge lp:~mterry/lightdm/get_layouts
Reviewer Review Type Date Requested Status
Robert Ancell Approve
Review via email: mp+92346@code.launchpad.net

Description of the change

I realized that we can avoid the enormous, unhelpful keyboard indicator dropdown by allowing unity-greeter to query the configured list of layouts per-user. So I added lightdm_user_get_layouts, changed the call to accountsservice, and augmented the layout test.

To post a comment you must log in.
lp:~mterry/lightdm/get_layouts updated
1402. By Michael Terry

add layouts property, expose it in vapi

Revision history for this message
Robert Ancell (robert-ancell) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'liblightdm-gobject/liblightdm-gobject-1.vapi'
2--- liblightdm-gobject/liblightdm-gobject-1.vapi 2012-02-09 05:33:51 +0000
3+++ liblightdm-gobject/liblightdm-gobject-1.vapi 2012-02-09 19:45:22 +0000
4@@ -87,6 +87,8 @@
5 public unowned string image { get; }
6 public unowned string language { get; }
7 public unowned string layout { get; }
8+ [CCode (array_length = false, array_null_terminated = true)]
9+ public unowned string[] layouts { get; }
10 public bool logged_in { get; }
11 public unowned string name { get; }
12 public unowned string real_name { get; }
13
14=== modified file 'liblightdm-gobject/lightdm/user.h'
15--- liblightdm-gobject/lightdm/user.h 2011-12-07 16:50:54 +0000
16+++ liblightdm-gobject/lightdm/user.h 2012-02-09 19:45:22 +0000
17@@ -99,6 +99,8 @@
18
19 const gchar *lightdm_user_get_layout (LightDMUser *user);
20
21+const gchar * const *lightdm_user_get_layouts (LightDMUser *user);
22+
23 const gchar *lightdm_user_get_session (LightDMUser *user);
24
25 gboolean lightdm_user_get_logged_in (LightDMUser *user);
26
27=== modified file 'liblightdm-gobject/user.c'
28--- liblightdm-gobject/user.c 2012-02-01 20:18:36 +0000
29+++ liblightdm-gobject/user.c 2012-02-09 19:45:22 +0000
30@@ -38,6 +38,7 @@
31 USER_PROP_BACKGROUND,
32 USER_PROP_LANGUAGE,
33 USER_PROP_LAYOUT,
34+ USER_PROP_LAYOUTS,
35 USER_PROP_SESSION,
36 USER_PROP_LOGGED_IN
37 };
38@@ -98,7 +99,7 @@
39
40 GKeyFile *dmrc_file;
41 gchar *language;
42- gchar *layout;
43+ gchar **layouts;
44 gchar *session;
45 } LightDMUserPrivate;
46
47@@ -1144,9 +1145,17 @@
48 *codeset = '\0';
49 }
50
51- if (priv->layout)
52- g_free (priv->layout);
53- priv->layout = g_key_file_get_string (priv->dmrc_file, "Desktop", "Layout", NULL);
54+ if (priv->layouts)
55+ {
56+ g_strfreev (priv->layouts);
57+ priv->layouts = NULL;
58+ }
59+ if (g_key_file_has_key (priv->dmrc_file, "Desktop", "Layout", NULL))
60+ {
61+ priv->layouts = g_malloc (sizeof (gchar *) * 2);
62+ priv->layouts[0] = g_key_file_get_string (priv->dmrc_file, "Desktop", "Layout", NULL);
63+ priv->layouts[1] = NULL;
64+ }
65
66 if (priv->session)
67 g_free (priv->session);
68@@ -1190,6 +1199,37 @@
69 return rv;
70 }
71
72+static gchar **
73+get_string_array_property (GDBusProxy *proxy, const gchar *property)
74+{
75+ GVariant *answer;
76+ gchar **rv;
77+
78+ if (!proxy)
79+ return NULL;
80+
81+ answer = g_dbus_proxy_get_cached_property (proxy, property);
82+
83+ if (!answer)
84+ {
85+ g_warning ("Could not get accounts property %s", property);
86+ return NULL;
87+ }
88+
89+ if (!g_variant_is_of_type (answer, G_VARIANT_TYPE ("as")))
90+ {
91+ g_warning ("Unexpected accounts property type for %s: %s",
92+ property, g_variant_get_type_string (answer));
93+ g_variant_unref (answer);
94+ return NULL;
95+ }
96+
97+ rv = g_variant_dup_strv (answer, NULL);
98+
99+ g_variant_unref (answer);
100+ return rv;
101+}
102+
103 static gboolean
104 load_accounts_service (LightDMUser *user)
105 {
106@@ -1197,7 +1237,7 @@
107 LightDMUserListPrivate *list_priv = GET_LIST_PRIVATE (priv->user_list);
108 UserAccountObject *account = NULL;
109 GList *iter;
110- gchar *value;
111+ gchar **value;
112
113 /* First, find AccountObject proxy */
114 for (iter = list_priv->user_account_objects; iter; iter = iter->next)
115@@ -1220,11 +1260,11 @@
116 g_free (priv->session);
117 priv->session = get_string_property (account->proxy, "XSession");
118
119- value = get_string_property (account->proxy, "XKeyboardLayout");
120+ value = get_string_array_property (account->proxy, "XKeyboardLayouts");
121 if (value)
122 {
123- g_free (priv->layout);
124- priv->layout = value;
125+ g_strfreev (priv->layouts);
126+ priv->layouts = value;
127 }
128
129 return TRUE;
130@@ -1236,6 +1276,13 @@
131 {
132 load_dmrc (user);
133 load_accounts_service (user); // overrides dmrc values
134+
135+ /* Ensure a few guarantees */
136+ if (GET_USER_PRIVATE (user)->layouts == NULL)
137+ {
138+ GET_USER_PRIVATE (user)->layouts = g_malloc (sizeof (gchar));
139+ GET_USER_PRIVATE (user)->layouts[0] = NULL;
140+ }
141 }
142
143 /**
144@@ -1260,14 +1307,30 @@
145 *
146 * Get the keyboard layout for a user.
147 *
148- * Return value: The keyboard layoyt for the given user or #NULL if using system defaults.
149+ * Return value: The keyboard layout for the given user or #NULL if using system defaults. Copy the value if you want to use it long term.
150 **/
151 const gchar *
152 lightdm_user_get_layout (LightDMUser *user)
153 {
154 g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
155 load_user_values (user);
156- return GET_USER_PRIVATE (user)->layout;
157+ return GET_USER_PRIVATE (user)->layouts[0];
158+}
159+
160+/**
161+ * lightdm_user_get_layouts
162+ * @user: A #LightDMUser
163+ *
164+ * Get the configured keyboard layouts for a user.
165+ *
166+ * Return value: (transfer none): A NULL-terminated array of keyboard layouts for the given user. Copy the values if you want to use them long term.
167+ **/
168+const gchar * const *
169+lightdm_user_get_layouts (LightDMUser *user)
170+{
171+ g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
172+ load_user_values (user);
173+ return (const gchar * const *) GET_USER_PRIVATE (user)->layouts;
174 }
175
176 /**
177@@ -1363,6 +1426,9 @@
178 case USER_PROP_LAYOUT:
179 g_value_set_string (value, lightdm_user_get_layout (self));
180 break;
181+ case USER_PROP_LAYOUTS:
182+ g_value_set_boxed (value, g_strdupv ((gchar **) lightdm_user_get_layouts (self)));
183+ break;
184 case USER_PROP_SESSION:
185 g_value_set_string (value, lightdm_user_get_session (self));
186 break;
187@@ -1386,6 +1452,7 @@
188 g_free (priv->home_directory);
189 g_free (priv->image);
190 g_free (priv->background);
191+ g_strfreev (priv->layouts);
192 if (priv->dmrc_file)
193 g_key_file_free (priv->dmrc_file);
194 }
195@@ -1458,6 +1525,13 @@
196 NULL,
197 G_PARAM_READABLE));
198 g_object_class_install_property (object_class,
199+ USER_PROP_LAYOUTS,
200+ g_param_spec_boxed ("layouts",
201+ "layouts",
202+ "Keyboard layouts used by this user",
203+ G_TYPE_STRV,
204+ G_PARAM_READABLE));
205+ g_object_class_install_property (object_class,
206 USER_PROP_SESSION,
207 g_param_spec_string ("session",
208 "session",
209
210=== modified file 'tests/scripts/keyboard-layout.conf'
211--- tests/scripts/keyboard-layout.conf 2012-02-08 14:43:20 +0000
212+++ tests/scripts/keyboard-layout.conf 2012-02-09 19:45:22 +0000
213@@ -26,6 +26,9 @@
214 #?GREETER :50 LOG-LAYOUT USERNAME=bob LAYOUT='us'
215 #?*GREETER :50 LOG-LAYOUT USERNAME=carol
216 #?GREETER :50 LOG-LAYOUT USERNAME=carol LAYOUT='fr oss'
217+#?*GREETER :50 LOG-LAYOUTS USERNAME=carol
218+#?GREETER :50 LOG-LAYOUTS USERNAME=carol LAYOUT='fr oss'
219+#?GREETER :50 LOG-LAYOUTS USERNAME=carol LAYOUT='ru'
220
221 # Cleanup
222 #?*STOP-DAEMON
223
224=== modified file 'tests/src/test-gobject-greeter.c'
225--- tests/src/test-gobject-greeter.c 2012-02-09 06:02:50 +0000
226+++ tests/src/test-gobject-greeter.c 2012-02-09 19:45:22 +0000
227@@ -113,6 +113,23 @@
228 }
229 g_free (r);
230
231+ r = g_strdup_printf ("GREETER %s LOG-LAYOUTS USERNAME=", getenv ("DISPLAY"));
232+ if (g_str_has_prefix (request, r))
233+ {
234+ LightDMUser *user;
235+ const gchar *username;
236+ const gchar * const *layouts;
237+ int i;
238+
239+ username = request + strlen (r);
240+ user = lightdm_user_list_get_user_by_name (lightdm_user_list_get_instance (), username);
241+ layouts = lightdm_user_get_layouts (user);
242+
243+ for (i = 0; layouts[i]; i++)
244+ status_notify ("GREETER %s LOG-LAYOUTS USERNAME=%s LAYOUT='%s'", getenv ("DISPLAY"), username, layouts[i]);
245+ }
246+ g_free (r);
247+
248 r = g_strdup_printf ("GREETER %s LOG-VARIANTS LAYOUT=", getenv ("DISPLAY"));
249 if (g_str_has_prefix (request, r))
250 {
251
252=== modified file 'tests/src/test-runner.c'
253--- tests/src/test-runner.c 2012-02-09 05:34:49 +0000
254+++ tests/src/test-runner.c 2012-02-09 19:45:22 +0000
255@@ -49,7 +49,7 @@
256 guint id;
257 gchar *language;
258 gchar *xsession;
259- gchar *layout;
260+ gchar **layouts;
261 } AccountsUser;
262 static GList *accounts_users = NULL;
263 static void handle_user_call (GDBusConnection *connection,
264@@ -788,7 +788,7 @@
265 *c = '\0';
266 }
267 user->xsession = g_key_file_get_string (dmrc_file, "Desktop", "Session", NULL);
268- user->layout = g_key_file_get_string (dmrc_file, "X-Accounts", "Layout", NULL);
269+ user->layouts = g_key_file_get_string_list (dmrc_file, "X-Accounts", "Layouts", NULL, NULL);
270 user->path = g_strdup_printf ("/org/freedesktop/Accounts/User%d", uid);
271 user->id = g_dbus_connection_register_object (accounts_connection,
272 user->path,
273@@ -913,8 +913,9 @@
274 return g_variant_new_string (user->language ? user->language : "");
275 else if (strcmp (property_name, "XSession") == 0)
276 return g_variant_new_string (user->xsession ? user->xsession : "");
277- else if (strcmp (property_name, "XKeyboardLayout") == 0)
278- return g_variant_new_string (user->layout ? user->layout : "");
279+ else if (strcmp (property_name, "XKeyboardLayouts") == 0 &&
280+ user->layouts != NULL && user->layouts[0] != NULL)
281+ return g_variant_new_strv ((const gchar * const *) user->layouts, -1);
282
283 return NULL;
284 }
285@@ -952,7 +953,7 @@
286 " <property name='BackgroundFile' type='s' access='read'/>"
287 " <property name='Language' type='s' access='read'/>"
288 " <property name='XSession' type='s' access='read'/>"
289- " <property name='XKeyboardLayout' type='s' access='read'/>"
290+ " <property name='XKeyboardLayouts' type='as' access='read'/>"
291 " </interface>"
292 "</node>";
293 GError *error = NULL;
294@@ -1205,18 +1206,18 @@
295 gchar *real_name;
296 gchar *xsession;
297 gchar *dmrc_layout;
298- gchar *dbus_layout;
299+ gchar *dbus_layouts;
300 gchar *language;
301 gint uid;
302 } users[] =
303 {
304- {"root", "", TRUE, "root", NULL, NULL, NULL, NULL, 0},
305- {"lightdm", "", TRUE, "", NULL, NULL, NULL, NULL, 100},
306- {"alice", "password", TRUE, "Alice User", NULL, NULL, NULL, NULL, 1000},
307- {"bob", "", TRUE, "Bob User", NULL, "us", NULL, "en_AU.utf8", 1001},
308- {"carol", "", TRUE, "Carol User", "alternative", "ru", "fr\toss", "fr_FR.UTF-8", 1002},
309- {"dave", "", FALSE, "Dave User", NULL, NULL, NULL, NULL, 1003},
310- {NULL, NULL, FALSE, NULL, NULL, NULL, NULL, NULL, 0}
311+ {"root", "", TRUE, "root", NULL, NULL, NULL, NULL, 0},
312+ {"lightdm", "", TRUE, "", NULL, NULL, NULL, NULL, 100},
313+ {"alice", "password", TRUE, "Alice User", NULL, NULL, NULL, NULL, 1000},
314+ {"bob", "", TRUE, "Bob User", NULL, "us", NULL, "en_AU.utf8", 1001},
315+ {"carol", "", TRUE, "Carol User", "alternative", "ru", "fr\toss;ru;", "fr_FR.UTF-8", 1002},
316+ {"dave", "", FALSE, "Dave User", NULL, NULL, NULL, NULL, 1003},
317+ {NULL, NULL, FALSE, NULL, NULL, NULL, NULL, NULL, 0}
318 };
319 passwd_data = g_string_new ("");
320 int i;
321@@ -1245,9 +1246,9 @@
322 g_key_file_set_string (dmrc_file, "Desktop", "Layout", users[i].dmrc_layout);
323 save_dmrc = TRUE;
324 }
325- if (users[i].dbus_layout)
326+ if (users[i].dbus_layouts)
327 {
328- g_key_file_set_string (dmrc_file, "X-Accounts", "Layout", users[i].dbus_layout);
329+ g_key_file_set_string (dmrc_file, "X-Accounts", "Layouts", users[i].dbus_layouts);
330 save_dmrc = TRUE;
331 }
332 if (users[i].language)

Subscribers

People subscribed via source and target branches