Merge lp:~donadigo/wingpanel-indicator-session/use-native-accounts-library into lp:~wingpanel-devs/wingpanel-indicator-session/trunk
- use-native-accounts-library
- Merge into trunk
Proposed by
Adam Bieńkowski
Status: | Merged |
---|---|
Approved by: | Felipe Escoto |
Approved revision: | 96 |
Merged at revision: | 94 |
Proposed branch: | lp:~donadigo/wingpanel-indicator-session/use-native-accounts-library |
Merge into: | lp:~wingpanel-devs/wingpanel-indicator-session/trunk |
Diff against target: |
655 lines (+245/-206) 7 files modified
src/CMakeLists.txt (+0/-1) src/Indicator.vala (+6/-3) src/Services/DbusInterfaces.vala (+12/-23) src/Services/User.vala (+0/-108) src/Services/UserManager.vala (+144/-50) src/Widgets/UserBox.vala (+56/-18) src/Widgets/UserListBox.vala (+27/-3) |
To merge this branch: | bzr merge lp:~donadigo/wingpanel-indicator-session/use-native-accounts-library |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Felipe Escoto | code/ux | Approve | |
Review via email: mp+302229@code.launchpad.net |
Commit message
* Use native accounts-service library
* Close indicator on activating row (logging of, switching accounts)
* Show guest account proper state when logged in
Description of the change
This branch replaces the old DBus implementation with native accounts-service library. In result we don't need a User class, that's provided already by the library.
Other features include:
- Close indicator on activating row (logging of, switching accounts)
- Show guest account proper state when logged in
To post a comment you must log in.
- 94. By Adam Bieńkowski
-
Use enums
Revision history for this message
Felipe Escoto (philip.scott) wrote : | # |
review:
Needs Fixing
(code/ux)
- 95. By Adam Bieńkowski
-
Prevent logged in users to be able to click themselves
- 96. By Adam Bieńkowski
-
Simpler draw function
Revision history for this message
Felipe Escoto (philip.scott) : | # |
review:
Approve
(code/ux)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/CMakeLists.txt' |
2 | --- src/CMakeLists.txt 2016-02-18 19:58:35 +0000 |
3 | +++ src/CMakeLists.txt 2016-08-08 16:32:36 +0000 |
4 | @@ -17,7 +17,6 @@ |
5 | Widgets/UserBox.vala |
6 | Widgets/UserListBox.vala |
7 | Widgets/EndSessionDialog.vala |
8 | - Services/User.vala |
9 | Services/UserManager.vala |
10 | Services/DbusInterfaces.vala |
11 | ${CMAKE_CURRENT_BINARY_DIR}/config.vala |
12 | |
13 | === modified file 'src/Indicator.vala' |
14 | --- src/Indicator.vala 2016-07-12 16:33:07 +0000 |
15 | +++ src/Indicator.vala 2016-08-08 16:32:36 +0000 |
16 | @@ -67,11 +67,10 @@ |
17 | users_separator = new Wingpanel.Widgets.Separator (); |
18 | manager = new Session.Services.UserManager (users_separator); |
19 | |
20 | - main_grid.add (manager.current_user); |
21 | main_grid.add (manager.user_grid); |
22 | |
23 | if (manager.has_guest) { |
24 | - manager.user_grid.add_guest (manager.guest (false)); |
25 | + manager.add_guest (false); |
26 | } |
27 | |
28 | main_grid.add (users_separator); |
29 | @@ -118,6 +117,8 @@ |
30 | } |
31 | |
32 | public void connections () { |
33 | + manager.close.connect (() => close ()); |
34 | + |
35 | lock_screen.clicked.connect (() => { |
36 | close (); |
37 | try { |
38 | @@ -151,7 +152,9 @@ |
39 | }); |
40 | } |
41 | |
42 | - public override void opened () {} |
43 | + public override void opened () { |
44 | + manager.update_all (); |
45 | + } |
46 | |
47 | public override void closed () {} |
48 | } |
49 | |
50 | === modified file 'src/Services/DbusInterfaces.vala' |
51 | --- src/Services/DbusInterfaces.vala 2016-08-05 22:26:34 +0000 |
52 | +++ src/Services/DbusInterfaces.vala 2016-08-08 16:32:36 +0000 |
53 | @@ -17,12 +17,9 @@ |
54 | * Boston, MA 02111-1307, USA. |
55 | */ |
56 | |
57 | -/* To generate new UserBoxes for each user, and when a new one is added */ |
58 | -[DBus (name = "org.freedesktop.Accounts")] |
59 | -interface AccountsInterface : Object { |
60 | - public abstract string[] list_cached_users () throws IOError; |
61 | - public signal void user_added (ObjectPath user_path); |
62 | - public signal void user_deleted (ObjectPath user_path); |
63 | +struct UserInfo { |
64 | + uint32 uid; |
65 | + string user_name; |
66 | } |
67 | |
68 | /* Power and system control */ |
69 | @@ -42,26 +39,18 @@ |
70 | public abstract void reboot (bool interactive) throws IOError; |
71 | public abstract void power_off (bool interactive) throws IOError; |
72 | |
73 | - public abstract string? get_user (uint32 uuid) throws IOError; |
74 | + public abstract UserInfo[] list_users () throws IOError; |
75 | + public abstract ObjectPath? get_user (uint32 uuid) throws IOError; |
76 | +} |
77 | + |
78 | +[DBus (name = "org.freedesktop.login1.User")] |
79 | +interface UserInterface : Object { |
80 | + public abstract string state { owned get; } |
81 | } |
82 | |
83 | [DBus (name = "org.freedesktop.DisplayManager.Seat")] |
84 | interface SeatInterface : Object { |
85 | - //public abstract void SwitchToGreeter () throws IOError; |
86 | + public abstract bool has_guest_account { get; } |
87 | public abstract void switch_to_guest (string session_name) throws IOError; |
88 | public abstract void switch_to_user (string username, string session_name) throws IOError; |
89 | -} |
90 | - |
91 | -/* for User.vala, to get the user properties */ |
92 | -[DBus (name = "org.freedesktop.Accounts.User")] |
93 | -interface UserInterface : Object { |
94 | - public signal void changed (); |
95 | -} |
96 | - |
97 | -[DBus (name = "org.freedesktop.DBus.Properties")] |
98 | -interface PropertiesInterface : Object { |
99 | - public abstract Variant get (string interface, string propname) throws IOError; |
100 | - |
101 | - /* public abstract void Set (string interface, string propname, Variant value) throws IOError; */ |
102 | - public signal void properties_changed (); |
103 | -} |
104 | +} |
105 | \ No newline at end of file |
106 | |
107 | === removed file 'src/Services/User.vala' |
108 | --- src/Services/User.vala 2016-01-15 18:20:25 +0000 |
109 | +++ src/Services/User.vala 1970-01-01 00:00:00 +0000 |
110 | @@ -1,108 +0,0 @@ |
111 | -/* |
112 | - * Copyright (c) 2011-2015 Wingpanel Developers (http://launchpad.net/wingpanel) |
113 | - * |
114 | - * This program is free software; you can redistribute it and/or |
115 | - * modify it under the terms of the GNU General Public |
116 | - * License as published by the Free Software Foundation; either |
117 | - * version 2 of the License, or (at your option) any later version. |
118 | - * |
119 | - * This program is distributed in the hope that it will be useful, |
120 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
121 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
122 | - * General Public License for more details. |
123 | - * |
124 | - * You should have received a copy of the GNU General Public |
125 | - * License along with this program; if not, write to the |
126 | - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
127 | - * Boston, MA 02111-1307, USA. |
128 | - */ |
129 | - |
130 | -public class Session.Services.User : Object { |
131 | - private static string ACCOUNTS_INTERFACE = "org.freedesktop.Accounts"; |
132 | - private static string USER_INTERFACE = "org.freedesktop.Accounts.User"; |
133 | - private static string LOGIN_INTERFACE = "org.freedesktop.login1"; |
134 | - private static string MANAGER = "/org/freedesktop/login1"; |
135 | - |
136 | - public string user_path { get; private set; } |
137 | - public string real_name { get; private set; } |
138 | - public string user_name { get; private set; } |
139 | - public string icon_file { get; private set; } |
140 | - public uint64 Uid { get; private set; } |
141 | - public bool locked { get; private set; } |
142 | - |
143 | - private UserInterface? user_interface = null; |
144 | - private PropertiesInterface? user_properties = null; |
145 | - private PropertiesInterface? state_properties = null; |
146 | - private SystemInterface? system_interface = null; |
147 | - |
148 | - public signal void properties_updated (); |
149 | - |
150 | - public User (string user_path_) { |
151 | - this.user_path = user_path_; |
152 | - |
153 | - connect_to_bus (); |
154 | - connect_signals (); |
155 | - update_properties (); |
156 | - get_state (); |
157 | - |
158 | - } |
159 | - |
160 | - private bool connect_to_bus () { |
161 | - try { |
162 | - system_interface = Bus.get_proxy_sync (BusType.SYSTEM, LOGIN_INTERFACE, MANAGER, DBusProxyFlags.NONE); |
163 | - user_interface = Bus.get_proxy_sync (BusType.SYSTEM, ACCOUNTS_INTERFACE, user_path, DBusProxyFlags.NONE); |
164 | - user_properties = Bus.get_proxy_sync (BusType.SYSTEM, ACCOUNTS_INTERFACE, user_path, DBusProxyFlags.NONE); |
165 | - |
166 | - update_properties (); |
167 | - string? user_object_path = system_interface.get_user ((uint32)Uid); |
168 | - state_properties = Bus.get_proxy_sync (BusType.SYSTEM, LOGIN_INTERFACE, user_object_path, DBusProxyFlags.NONE); |
169 | - |
170 | - debug ("Connection to user account established. User path: %s", user_object_path); |
171 | - |
172 | - return user_interface != null & user_properties != null; |
173 | - } catch (Error e) { |
174 | - critical ("Connecting to Accounts failed: %s", e.message); |
175 | - return false; |
176 | - } |
177 | - } |
178 | - |
179 | - private void connect_signals () { |
180 | - user_interface.changed.connect (update_properties); |
181 | - user_properties.properties_changed.connect (update_properties); |
182 | - state_properties.properties_changed.connect (update_properties); |
183 | - } |
184 | - |
185 | - public bool get_state () { |
186 | - bool state = false; |
187 | - |
188 | - try { |
189 | - string status = state_properties.get (LOGIN_INTERFACE + ".User", "State").get_string (); |
190 | - |
191 | - if (status == "active" || status == "online") { |
192 | - state = true; |
193 | - } |
194 | - } catch (Error e) { |
195 | - critical ("Could not get users' state: %s", e.message); |
196 | - } |
197 | - |
198 | - return state; |
199 | - } |
200 | - |
201 | - public void update_properties () { |
202 | - try { |
203 | - real_name = user_properties.get (USER_INTERFACE, "RealName").get_string (); |
204 | - user_name = user_properties.get (USER_INTERFACE, "UserName").get_string (); |
205 | - icon_file = user_properties.get (USER_INTERFACE, "IconFile").get_string (); |
206 | - locked = user_properties.get (USER_INTERFACE, "Locked").get_boolean (); |
207 | - Uid = user_properties.get (USER_INTERFACE, "Uid").get_uint64 (); |
208 | - |
209 | - if (real_name == "") { |
210 | - real_name = user_name; |
211 | - } |
212 | - |
213 | - properties_updated (); |
214 | - } catch (Error e) { |
215 | - critical ("Updating device properties failed: %s", e.message); |
216 | - } |
217 | - } |
218 | -} |
219 | |
220 | === modified file 'src/Services/UserManager.vala' |
221 | --- src/Services/UserManager.vala 2016-05-21 15:56:59 +0000 |
222 | +++ src/Services/UserManager.vala 2016-08-08 16:32:36 +0000 |
223 | @@ -17,16 +17,93 @@ |
224 | * Boston, MA 02111-1307, USA. |
225 | */ |
226 | |
227 | +public enum UserState { |
228 | + ACTIVE, |
229 | + ONLINE, |
230 | + OFFLINE; |
231 | + |
232 | + public static UserState to_enum (string state) { |
233 | + switch (state) { |
234 | + case "active": |
235 | + return UserState.ACTIVE; |
236 | + case "online": |
237 | + return UserState.ONLINE; |
238 | + } |
239 | + |
240 | + return UserState.OFFLINE; |
241 | + } |
242 | +} |
243 | + |
244 | public class Session.Services.UserManager : Object { |
245 | + public signal void close (); |
246 | + |
247 | + private const string LOGIN_IFACE = "org.freedesktop.login1"; |
248 | + private const string LOGIN_PATH = "/org/freedesktop/login1"; |
249 | + |
250 | private signal void delete_user (ObjectPath user_path); |
251 | - private AccountsInterface accounts_interface; |
252 | - private PropertiesInterface state_properties; |
253 | + private Act.UserManager manager; |
254 | + private List<Widgets.Userbox> userbox_list; |
255 | + private SeatInterface dm_proxy; |
256 | private Wingpanel.Widgets.Separator users_separator; |
257 | |
258 | public Session.Widgets.UserListBox user_grid; |
259 | - public Session.Widgets.Userbox current_user; |
260 | |
261 | - public bool has_guest {public get; private set; default = false;} |
262 | + public bool has_guest { public get; private set; default = false; } |
263 | + |
264 | + private static SystemInterface? login_proxy; |
265 | + |
266 | + static construct { |
267 | + try { |
268 | + login_proxy = Bus.get_proxy_sync (BusType.SYSTEM, LOGIN_IFACE, LOGIN_PATH, DBusProxyFlags.NONE); |
269 | + } catch (IOError e) { |
270 | + stderr.printf ("UserManager error: %s\n", e.message); |
271 | + } |
272 | + } |
273 | + |
274 | + public static UserState get_user_state (uint32 uuid) { |
275 | + if (login_proxy == null) { |
276 | + return UserState.OFFLINE; |
277 | + } |
278 | + |
279 | + try { |
280 | + ObjectPath? path = login_proxy.get_user (uuid); |
281 | + if (path == null) { |
282 | + return UserState.OFFLINE; |
283 | + } |
284 | + |
285 | + UserInterface? user = Bus.get_proxy_sync (BusType.SYSTEM, LOGIN_IFACE, path, DBusProxyFlags.NONE); |
286 | + if (user == null) { |
287 | + return UserState.OFFLINE; |
288 | + } |
289 | + |
290 | + return UserState.to_enum (user.state); |
291 | + } catch (IOError e) { |
292 | + stderr.printf ("Error: %s\n", e.message); |
293 | + } |
294 | + |
295 | + return UserState.OFFLINE; |
296 | + } |
297 | + |
298 | + public static UserState get_guest_state () { |
299 | + if (login_proxy == null) { |
300 | + return UserState.OFFLINE; |
301 | + } |
302 | + |
303 | + try { |
304 | + UserInfo[] users = login_proxy.list_users (); |
305 | + foreach (UserInfo user in users) { |
306 | + var state = get_user_state (user.uid); |
307 | + if (user.user_name.has_prefix ("guest-") |
308 | + && state == UserState.ACTIVE) { |
309 | + return UserState.ACTIVE; |
310 | + } |
311 | + } |
312 | + } catch (IOError e) { |
313 | + stderr.printf ("Error: %s\n", e.message); |
314 | + } |
315 | + |
316 | + return UserState.OFFLINE; |
317 | + } |
318 | |
319 | public UserManager (Wingpanel.Widgets.Separator users_separator) { |
320 | this.users_separator = users_separator; |
321 | @@ -37,74 +114,91 @@ |
322 | } |
323 | |
324 | private void init () { |
325 | + userbox_list = new List<Widgets.Userbox> (); |
326 | user_grid = new Session.Widgets.UserListBox (); |
327 | + user_grid.close.connect (() => close ()); |
328 | + |
329 | + manager = Act.UserManager.get_default (); |
330 | + connect_signals (); |
331 | + init_users (); |
332 | |
333 | try { |
334 | - accounts_interface = Bus.get_proxy_sync (BusType.SYSTEM, "org.freedesktop.Accounts", "/org/freedesktop/Accounts", DBusProxyFlags.NONE); |
335 | - state_properties = Bus.get_proxy_sync (BusType.SYSTEM, "org.freedesktop.DisplayManager", Environment.get_variable ("XDG_SEAT_PATH"), DBusProxyFlags.NONE); |
336 | - has_guest = state_properties.get ("org.freedesktop.DisplayManager.Seat", "HasGuestAccount").get_boolean (); |
337 | - |
338 | - connect_signals (); |
339 | - init_users (); |
340 | + dm_proxy = Bus.get_proxy_sync (BusType.SYSTEM, "org.freedesktop.DisplayManager", Environment.get_variable ("XDG_SEAT_PATH"), DBusProxyFlags.NONE); |
341 | + has_guest = dm_proxy.has_guest_account; |
342 | } catch (IOError e) { |
343 | stderr.printf ("UserManager error: %s\n", e.message); |
344 | } |
345 | } |
346 | |
347 | private void connect_signals () { |
348 | - accounts_interface.user_added.connect ((user_path) => { |
349 | - var user = new_user (user_path); |
350 | + manager.user_added.connect (add_user); |
351 | + manager.user_removed.connect (remove_user); |
352 | + manager.user_is_logged_in_changed.connect (update_user); |
353 | |
354 | - if (user != null) { |
355 | - user_grid.add (user); |
356 | + manager.notify["is-loaded"].connect (() => { |
357 | + if (manager.is_loaded) { |
358 | + init_users (); |
359 | } |
360 | - }); |
361 | - |
362 | - accounts_interface.user_deleted.connect ((user_path) => { |
363 | - delete_user (user_path); |
364 | - }); |
365 | + }); |
366 | } |
367 | |
368 | private void init_users () { |
369 | - string current_user = GLib.Environment.get_user_name (); |
370 | - |
371 | - try { |
372 | - var users = accounts_interface.list_cached_users (); |
373 | - foreach (string user_address in users) { |
374 | - var userbox = new_user (user_address); |
375 | - |
376 | - if (userbox.user.user_name == current_user) { |
377 | - this.current_user = userbox; |
378 | - } else { |
379 | - user_grid.add (userbox); |
380 | - } |
381 | - } |
382 | - } catch (IOError e) { |
383 | - stderr.printf ("ERROR: %s\n", e.message); |
384 | + foreach (Act.User user in manager.list_users ()) { |
385 | + add_user (user); |
386 | } |
387 | } |
388 | |
389 | - private Session.Widgets.Userbox new_user (string user_address) { |
390 | - var user = new Session.Services.User (user_address); |
391 | + private void add_user (Act.User user) { |
392 | var userbox = new Session.Widgets.Userbox (user); |
393 | - |
394 | - delete_user.connect ((user_path) => { |
395 | - if (userbox.user.user_path == user_path) { |
396 | - user_grid.remove (userbox); |
397 | + userbox_list.append (userbox); |
398 | + |
399 | + user_grid.add (userbox); |
400 | + |
401 | + users_separator.visible = true; |
402 | + } |
403 | + |
404 | + private Widgets.Userbox? get_userbox_from_user (Act.User user) { |
405 | + foreach (Widgets.Userbox userbox in userbox_list) { |
406 | + if (userbox.user.get_user_name () == user.get_user_name ()) { |
407 | + return userbox; |
408 | } |
409 | - }); |
410 | - |
411 | - users_separator.visible = true; |
412 | - |
413 | - return userbox; |
414 | - } |
415 | - |
416 | - public Session.Widgets.Userbox guest (bool logged_in) { |
417 | + } |
418 | + |
419 | + return null; |
420 | + } |
421 | + |
422 | + private void remove_user (Act.User user) { |
423 | + var userbox = get_userbox_from_user (user); |
424 | + if (userbox == null) { |
425 | + return; |
426 | + } |
427 | + |
428 | + userbox_list.remove (userbox); |
429 | + user_grid.remove (userbox); |
430 | + } |
431 | + |
432 | + private void update_user (Act.User user) { |
433 | + var userbox = get_userbox_from_user (user); |
434 | + if (userbox == null) { |
435 | + return; |
436 | + } |
437 | + |
438 | + userbox.update_state (); |
439 | + } |
440 | + |
441 | + public void update_all () { |
442 | + foreach (var userbox in userbox_list) { |
443 | + userbox.update_state (); |
444 | + } |
445 | + } |
446 | + |
447 | + public void add_guest (bool logged_in) { |
448 | var userbox = new Session.Widgets.Userbox.from_data (_("Guest"), logged_in, true); |
449 | + userbox_list.append (userbox); |
450 | userbox.visible = true; |
451 | |
452 | + user_grid.add_guest (userbox); |
453 | + |
454 | users_separator.visible = true; |
455 | - |
456 | - return userbox; |
457 | } |
458 | } |
459 | |
460 | === modified file 'src/Widgets/UserBox.vala' |
461 | --- src/Widgets/UserBox.vala 2016-05-21 17:15:08 +0000 |
462 | +++ src/Widgets/UserBox.vala 2016-08-08 16:32:36 +0000 |
463 | @@ -22,28 +22,30 @@ |
464 | private const string LOGGED_OFF = _("Logged out"); |
465 | private const int ICON_SIZE = 48; |
466 | |
467 | - public Session.Services.User user { public get; private set; } |
468 | + public Act.User? user { public get; private set; } |
469 | public bool is_guest = false; |
470 | |
471 | private Granite.Widgets.Avatar avatar; |
472 | private Gtk.Label fullname_label; |
473 | private Gtk.Label status_label; |
474 | |
475 | - public Userbox (Session.Services.User user) { |
476 | + public Userbox (Act.User user) { |
477 | this.user = user; |
478 | build_ui (); |
479 | connect_signals (); |
480 | - user.update_properties (); |
481 | + update (); |
482 | + update_state (); |
483 | } |
484 | |
485 | public Userbox.from_data (string fullname, bool logged_in, bool is_guest = false) { |
486 | this.is_guest = is_guest; |
487 | - build_ui (false); |
488 | + this.user = null; |
489 | + build_ui (); |
490 | fullname_label.label = "<b>" + fullname + "</b>"; |
491 | - update_state (logged_in); |
492 | + update_state (); |
493 | } |
494 | |
495 | - private void build_ui (bool load_icon = true) { |
496 | + private void build_ui () { |
497 | get_style_context ().add_class ("menuitem"); |
498 | |
499 | var grid = new Gtk.Grid (); |
500 | @@ -56,11 +58,12 @@ |
501 | status_label = new Gtk.Label (LOGGED_OFF); |
502 | status_label.halign = Gtk.Align.START; |
503 | |
504 | - if (load_icon) { |
505 | - avatar = new Granite.Widgets.Avatar.from_file (user.icon_file, ICON_SIZE); |
506 | - } else { |
507 | + if (is_guest) { |
508 | avatar = new Granite.Widgets.Avatar.with_default_icon (ICON_SIZE); |
509 | + } else { |
510 | + avatar = new Granite.Widgets.Avatar.from_file (user.get_icon_file (), ICON_SIZE); |
511 | } |
512 | + |
513 | avatar.margin_end = 6; |
514 | |
515 | grid.attach (avatar, 0, 0, 3, 3); |
516 | @@ -69,11 +72,34 @@ |
517 | this.add (grid); |
518 | } |
519 | |
520 | - public void update (string? fullname, string icon) { |
521 | - this.fullname_label.set_label ("<b>" + fullname + "</b>"); |
522 | + // For some reason Act.User.is_logged_in () does not work |
523 | + public UserState get_user_state () { |
524 | + if (is_guest) { |
525 | + return Services.UserManager.get_guest_state (); |
526 | + } |
527 | + |
528 | + return Services.UserManager.get_user_state (user.get_uid ()); |
529 | + } |
530 | + |
531 | + public bool is_logged_in () { |
532 | + var state = get_user_state (); |
533 | + return state == UserState.ONLINE || state == UserState.ACTIVE; |
534 | + } |
535 | + |
536 | + public void set_can_activate (bool can_activate) { |
537 | + selectable = can_activate; |
538 | + activatable = can_activate; |
539 | + } |
540 | + |
541 | + private void update () { |
542 | + if (is_guest) { |
543 | + return; |
544 | + } |
545 | + |
546 | + this.fullname_label.label = "<b>" + user.get_real_name () + "</b>"; |
547 | |
548 | try { |
549 | - var pixbuf = new Gdk.Pixbuf.from_file (icon); |
550 | + var pixbuf = new Gdk.Pixbuf.from_file (user.get_icon_file ()); |
551 | pixbuf = pixbuf.scale_simple (ICON_SIZE, ICON_SIZE, Gdk.InterpType.BILINEAR); |
552 | avatar.pixbuf = pixbuf; |
553 | } catch (Error e) { |
554 | @@ -81,21 +107,33 @@ |
555 | } |
556 | } |
557 | |
558 | - public void update_state (bool logged_in) { |
559 | - if (logged_in) { |
560 | + public void update_state () { |
561 | + var state = get_user_state (); |
562 | + set_can_activate (state != UserState.ACTIVE); |
563 | + if (is_logged_in ()) { |
564 | status_label.label = LOGGED_IN; |
565 | } else { |
566 | status_label.label = LOGGED_OFF; |
567 | } |
568 | + |
569 | + changed (); |
570 | } |
571 | |
572 | private void connect_signals () { |
573 | - user.properties_updated.connect (() => { |
574 | - update (user.real_name, user.icon_file); |
575 | - update_state (user.get_state ()); |
576 | + user.changed.connect (() => { |
577 | + update (); |
578 | + update_state (); |
579 | }); |
580 | |
581 | user.bind_property ("locked", this, "visible", BindingFlags.SYNC_CREATE | BindingFlags.INVERT_BOOLEAN); |
582 | - user.bind_property ("locked", this, "no_show_all", BindingFlags.SYNC_CREATE); |
583 | + user.bind_property ("locked", this, "no-show-all", BindingFlags.SYNC_CREATE); |
584 | } |
585 | + |
586 | + public override bool draw (Cairo.Context ctx) { |
587 | + if (!get_selectable ()) { |
588 | + get_style_context ().set_state (Gtk.StateFlags.NORMAL); |
589 | + } |
590 | + |
591 | + return base.draw (ctx); |
592 | + } |
593 | } |
594 | |
595 | === modified file 'src/Widgets/UserListBox.vala' |
596 | --- src/Widgets/UserListBox.vala 2016-02-22 17:24:06 +0000 |
597 | +++ src/Widgets/UserListBox.vala 2016-08-08 16:32:36 +0000 |
598 | @@ -18,6 +18,8 @@ |
599 | */ |
600 | |
601 | public class Session.Widgets.UserListBox : Gtk.ListBox { |
602 | + public signal void close (); |
603 | + |
604 | private SeatInterface? seat = null; |
605 | private string session_path; |
606 | private bool has_guest; |
607 | @@ -32,6 +34,7 @@ |
608 | stderr.printf ("DisplayManager.Seat error: %s\n", e.message); |
609 | } |
610 | |
611 | + this.set_sort_func (sort_func); |
612 | this.set_activate_on_single_click (true); |
613 | } |
614 | |
615 | @@ -50,14 +53,35 @@ |
616 | return; |
617 | } |
618 | |
619 | + close (); |
620 | try { |
621 | if (userbox.is_guest) { |
622 | seat.switch_to_guest (""); |
623 | } else { |
624 | - seat.switch_to_user (userbox.user.user_name, session_path); |
625 | - } |
626 | + seat.switch_to_user (userbox.user.get_user_name (), session_path); |
627 | + } |
628 | } catch (IOError e) { |
629 | stderr.printf ("DisplayManager.Seat error: %s\n", e.message); |
630 | } |
631 | } |
632 | - } |
633 | \ No newline at end of file |
634 | + |
635 | + // We could use here Act.User.collate () but we want to show the logged user first |
636 | + public int sort_func (Gtk.ListBoxRow row1, Gtk.ListBoxRow row2) { |
637 | + var userbox1 = (Userbox)row1; |
638 | + var userbox2 = (Userbox)row2; |
639 | + |
640 | + if (userbox1.get_user_state () == UserState.ACTIVE) { |
641 | + return -1; |
642 | + } else if (userbox2.get_user_state () == UserState.ACTIVE) { |
643 | + return 1; |
644 | + } |
645 | + |
646 | + if (userbox1.is_guest && !userbox2.is_guest) { |
647 | + return 1; |
648 | + } else if (!userbox1.is_guest && userbox2.is_guest) { |
649 | + return -1; |
650 | + } |
651 | + |
652 | + return 0; |
653 | + } |
654 | +} |
655 | \ No newline at end of file |
Code wise the indicator now looks better than ever! The only problem I have is with the current user being clickable.