Merge lp:~donadigo/wingpanel-indicator-session/use-native-accounts-library into lp:~wingpanel-devs/wingpanel-indicator-session/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
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 :

Code wise the indicator now looks better than ever! The only problem I have is with the current user being clickable.

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
=== modified file 'src/CMakeLists.txt'
--- src/CMakeLists.txt 2016-02-18 19:58:35 +0000
+++ src/CMakeLists.txt 2016-08-08 16:32:36 +0000
@@ -17,7 +17,6 @@
17 Widgets/UserBox.vala17 Widgets/UserBox.vala
18 Widgets/UserListBox.vala18 Widgets/UserListBox.vala
19 Widgets/EndSessionDialog.vala19 Widgets/EndSessionDialog.vala
20 Services/User.vala
21 Services/UserManager.vala20 Services/UserManager.vala
22 Services/DbusInterfaces.vala21 Services/DbusInterfaces.vala
23 ${CMAKE_CURRENT_BINARY_DIR}/config.vala22 ${CMAKE_CURRENT_BINARY_DIR}/config.vala
2423
=== modified file 'src/Indicator.vala'
--- src/Indicator.vala 2016-07-12 16:33:07 +0000
+++ src/Indicator.vala 2016-08-08 16:32:36 +0000
@@ -67,11 +67,10 @@
67 users_separator = new Wingpanel.Widgets.Separator ();67 users_separator = new Wingpanel.Widgets.Separator ();
68 manager = new Session.Services.UserManager (users_separator);68 manager = new Session.Services.UserManager (users_separator);
6969
70 main_grid.add (manager.current_user);
71 main_grid.add (manager.user_grid);70 main_grid.add (manager.user_grid);
7271
73 if (manager.has_guest) {72 if (manager.has_guest) {
74 manager.user_grid.add_guest (manager.guest (false));73 manager.add_guest (false);
75 }74 }
7675
77 main_grid.add (users_separator);76 main_grid.add (users_separator);
@@ -118,6 +117,8 @@
118 }117 }
119118
120 public void connections () {119 public void connections () {
120 manager.close.connect (() => close ());
121
121 lock_screen.clicked.connect (() => {122 lock_screen.clicked.connect (() => {
122 close ();123 close ();
123 try {124 try {
@@ -151,7 +152,9 @@
151 });152 });
152 }153 }
153154
154 public override void opened () {}155 public override void opened () {
156 manager.update_all ();
157 }
155158
156 public override void closed () {}159 public override void closed () {}
157}160}
158161
=== modified file 'src/Services/DbusInterfaces.vala'
--- src/Services/DbusInterfaces.vala 2016-08-05 22:26:34 +0000
+++ src/Services/DbusInterfaces.vala 2016-08-08 16:32:36 +0000
@@ -17,12 +17,9 @@
17 * Boston, MA 02111-1307, USA.17 * Boston, MA 02111-1307, USA.
18 */18 */
1919
20/* To generate new UserBoxes for each user, and when a new one is added */20struct UserInfo {
21[DBus (name = "org.freedesktop.Accounts")]21 uint32 uid;
22interface AccountsInterface : Object {22 string user_name;
23 public abstract string[] list_cached_users () throws IOError;
24 public signal void user_added (ObjectPath user_path);
25 public signal void user_deleted (ObjectPath user_path);
26}23}
2724
28/* Power and system control */25/* Power and system control */
@@ -42,26 +39,18 @@
42 public abstract void reboot (bool interactive) throws IOError;39 public abstract void reboot (bool interactive) throws IOError;
43 public abstract void power_off (bool interactive) throws IOError;40 public abstract void power_off (bool interactive) throws IOError;
4441
45 public abstract string? get_user (uint32 uuid) throws IOError;42 public abstract UserInfo[] list_users () throws IOError;
43 public abstract ObjectPath? get_user (uint32 uuid) throws IOError;
44}
45
46[DBus (name = "org.freedesktop.login1.User")]
47interface UserInterface : Object {
48 public abstract string state { owned get; }
46}49}
4750
48[DBus (name = "org.freedesktop.DisplayManager.Seat")]51[DBus (name = "org.freedesktop.DisplayManager.Seat")]
49interface SeatInterface : Object {52interface SeatInterface : Object {
50 //public abstract void SwitchToGreeter () throws IOError;53 public abstract bool has_guest_account { get; }
51 public abstract void switch_to_guest (string session_name) throws IOError;54 public abstract void switch_to_guest (string session_name) throws IOError;
52 public abstract void switch_to_user (string username, string session_name) throws IOError;55 public abstract void switch_to_user (string username, string session_name) throws IOError;
53}56}
54
55/* for User.vala, to get the user properties */
56[DBus (name = "org.freedesktop.Accounts.User")]
57interface UserInterface : Object {
58 public signal void changed ();
59}
60
61[DBus (name = "org.freedesktop.DBus.Properties")]
62interface PropertiesInterface : Object {
63 public abstract Variant get (string interface, string propname) throws IOError;
64
65 /* public abstract void Set (string interface, string propname, Variant value) throws IOError; */
66 public signal void properties_changed ();
67}
68\ No newline at end of file57\ No newline at end of file
6958
=== removed file 'src/Services/User.vala'
--- src/Services/User.vala 2016-01-15 18:20:25 +0000
+++ src/Services/User.vala 1970-01-01 00:00:00 +0000
@@ -1,108 +0,0 @@
1/*
2 * Copyright (c) 2011-2015 Wingpanel Developers (http://launchpad.net/wingpanel)
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20public class Session.Services.User : Object {
21 private static string ACCOUNTS_INTERFACE = "org.freedesktop.Accounts";
22 private static string USER_INTERFACE = "org.freedesktop.Accounts.User";
23 private static string LOGIN_INTERFACE = "org.freedesktop.login1";
24 private static string MANAGER = "/org/freedesktop/login1";
25
26 public string user_path { get; private set; }
27 public string real_name { get; private set; }
28 public string user_name { get; private set; }
29 public string icon_file { get; private set; }
30 public uint64 Uid { get; private set; }
31 public bool locked { get; private set; }
32
33 private UserInterface? user_interface = null;
34 private PropertiesInterface? user_properties = null;
35 private PropertiesInterface? state_properties = null;
36 private SystemInterface? system_interface = null;
37
38 public signal void properties_updated ();
39
40 public User (string user_path_) {
41 this.user_path = user_path_;
42
43 connect_to_bus ();
44 connect_signals ();
45 update_properties ();
46 get_state ();
47
48 }
49
50 private bool connect_to_bus () {
51 try {
52 system_interface = Bus.get_proxy_sync (BusType.SYSTEM, LOGIN_INTERFACE, MANAGER, DBusProxyFlags.NONE);
53 user_interface = Bus.get_proxy_sync (BusType.SYSTEM, ACCOUNTS_INTERFACE, user_path, DBusProxyFlags.NONE);
54 user_properties = Bus.get_proxy_sync (BusType.SYSTEM, ACCOUNTS_INTERFACE, user_path, DBusProxyFlags.NONE);
55
56 update_properties ();
57 string? user_object_path = system_interface.get_user ((uint32)Uid);
58 state_properties = Bus.get_proxy_sync (BusType.SYSTEM, LOGIN_INTERFACE, user_object_path, DBusProxyFlags.NONE);
59
60 debug ("Connection to user account established. User path: %s", user_object_path);
61
62 return user_interface != null & user_properties != null;
63 } catch (Error e) {
64 critical ("Connecting to Accounts failed: %s", e.message);
65 return false;
66 }
67 }
68
69 private void connect_signals () {
70 user_interface.changed.connect (update_properties);
71 user_properties.properties_changed.connect (update_properties);
72 state_properties.properties_changed.connect (update_properties);
73 }
74
75 public bool get_state () {
76 bool state = false;
77
78 try {
79 string status = state_properties.get (LOGIN_INTERFACE + ".User", "State").get_string ();
80
81 if (status == "active" || status == "online") {
82 state = true;
83 }
84 } catch (Error e) {
85 critical ("Could not get users' state: %s", e.message);
86 }
87
88 return state;
89 }
90
91 public void update_properties () {
92 try {
93 real_name = user_properties.get (USER_INTERFACE, "RealName").get_string ();
94 user_name = user_properties.get (USER_INTERFACE, "UserName").get_string ();
95 icon_file = user_properties.get (USER_INTERFACE, "IconFile").get_string ();
96 locked = user_properties.get (USER_INTERFACE, "Locked").get_boolean ();
97 Uid = user_properties.get (USER_INTERFACE, "Uid").get_uint64 ();
98
99 if (real_name == "") {
100 real_name = user_name;
101 }
102
103 properties_updated ();
104 } catch (Error e) {
105 critical ("Updating device properties failed: %s", e.message);
106 }
107 }
108}
1090
=== modified file 'src/Services/UserManager.vala'
--- src/Services/UserManager.vala 2016-05-21 15:56:59 +0000
+++ src/Services/UserManager.vala 2016-08-08 16:32:36 +0000
@@ -17,16 +17,93 @@
17 * Boston, MA 02111-1307, USA.17 * Boston, MA 02111-1307, USA.
18 */18 */
1919
20public enum UserState {
21 ACTIVE,
22 ONLINE,
23 OFFLINE;
24
25 public static UserState to_enum (string state) {
26 switch (state) {
27 case "active":
28 return UserState.ACTIVE;
29 case "online":
30 return UserState.ONLINE;
31 }
32
33 return UserState.OFFLINE;
34 }
35}
36
20public class Session.Services.UserManager : Object {37public class Session.Services.UserManager : Object {
38 public signal void close ();
39
40 private const string LOGIN_IFACE = "org.freedesktop.login1";
41 private const string LOGIN_PATH = "/org/freedesktop/login1";
42
21 private signal void delete_user (ObjectPath user_path);43 private signal void delete_user (ObjectPath user_path);
22 private AccountsInterface accounts_interface;44 private Act.UserManager manager;
23 private PropertiesInterface state_properties;45 private List<Widgets.Userbox> userbox_list;
46 private SeatInterface dm_proxy;
24 private Wingpanel.Widgets.Separator users_separator;47 private Wingpanel.Widgets.Separator users_separator;
2548
26 public Session.Widgets.UserListBox user_grid;49 public Session.Widgets.UserListBox user_grid;
27 public Session.Widgets.Userbox current_user;
28 50
29 public bool has_guest {public get; private set; default = false;}51 public bool has_guest { public get; private set; default = false; }
52
53 private static SystemInterface? login_proxy;
54
55 static construct {
56 try {
57 login_proxy = Bus.get_proxy_sync (BusType.SYSTEM, LOGIN_IFACE, LOGIN_PATH, DBusProxyFlags.NONE);
58 } catch (IOError e) {
59 stderr.printf ("UserManager error: %s\n", e.message);
60 }
61 }
62
63 public static UserState get_user_state (uint32 uuid) {
64 if (login_proxy == null) {
65 return UserState.OFFLINE;
66 }
67
68 try {
69 ObjectPath? path = login_proxy.get_user (uuid);
70 if (path == null) {
71 return UserState.OFFLINE;
72 }
73
74 UserInterface? user = Bus.get_proxy_sync (BusType.SYSTEM, LOGIN_IFACE, path, DBusProxyFlags.NONE);
75 if (user == null) {
76 return UserState.OFFLINE;
77 }
78
79 return UserState.to_enum (user.state);
80 } catch (IOError e) {
81 stderr.printf ("Error: %s\n", e.message);
82 }
83
84 return UserState.OFFLINE;
85 }
86
87 public static UserState get_guest_state () {
88 if (login_proxy == null) {
89 return UserState.OFFLINE;
90 }
91
92 try {
93 UserInfo[] users = login_proxy.list_users ();
94 foreach (UserInfo user in users) {
95 var state = get_user_state (user.uid);
96 if (user.user_name.has_prefix ("guest-")
97 && state == UserState.ACTIVE) {
98 return UserState.ACTIVE;
99 }
100 }
101 } catch (IOError e) {
102 stderr.printf ("Error: %s\n", e.message);
103 }
104
105 return UserState.OFFLINE;
106 }
30107
31 public UserManager (Wingpanel.Widgets.Separator users_separator) {108 public UserManager (Wingpanel.Widgets.Separator users_separator) {
32 this.users_separator = users_separator;109 this.users_separator = users_separator;
@@ -37,74 +114,91 @@
37 }114 }
38115
39 private void init () {116 private void init () {
117 userbox_list = new List<Widgets.Userbox> ();
40 user_grid = new Session.Widgets.UserListBox ();118 user_grid = new Session.Widgets.UserListBox ();
119 user_grid.close.connect (() => close ());
120
121 manager = Act.UserManager.get_default ();
122 connect_signals ();
123 init_users ();
41124
42 try {125 try {
43 accounts_interface = Bus.get_proxy_sync (BusType.SYSTEM, "org.freedesktop.Accounts", "/org/freedesktop/Accounts", DBusProxyFlags.NONE);126 dm_proxy = Bus.get_proxy_sync (BusType.SYSTEM, "org.freedesktop.DisplayManager", Environment.get_variable ("XDG_SEAT_PATH"), DBusProxyFlags.NONE);
44 state_properties = Bus.get_proxy_sync (BusType.SYSTEM, "org.freedesktop.DisplayManager", Environment.get_variable ("XDG_SEAT_PATH"), DBusProxyFlags.NONE);127 has_guest = dm_proxy.has_guest_account;
45 has_guest = state_properties.get ("org.freedesktop.DisplayManager.Seat", "HasGuestAccount").get_boolean ();
46
47 connect_signals ();
48 init_users ();
49 } catch (IOError e) {128 } catch (IOError e) {
50 stderr.printf ("UserManager error: %s\n", e.message);129 stderr.printf ("UserManager error: %s\n", e.message);
51 }130 }
52 }131 }
53132
54 private void connect_signals () {133 private void connect_signals () {
55 accounts_interface.user_added.connect ((user_path) => {134 manager.user_added.connect (add_user);
56 var user = new_user (user_path);135 manager.user_removed.connect (remove_user);
136 manager.user_is_logged_in_changed.connect (update_user);
57137
58 if (user != null) {138 manager.notify["is-loaded"].connect (() => {
59 user_grid.add (user);139 if (manager.is_loaded) {
140 init_users ();
60 }141 }
61 });142 });
62
63 accounts_interface.user_deleted.connect ((user_path) => {
64 delete_user (user_path);
65 });
66 }143 }
67144
68 private void init_users () {145 private void init_users () {
69 string current_user = GLib.Environment.get_user_name ();146 foreach (Act.User user in manager.list_users ()) {
70147 add_user (user);
71 try {
72 var users = accounts_interface.list_cached_users ();
73 foreach (string user_address in users) {
74 var userbox = new_user (user_address);
75
76 if (userbox.user.user_name == current_user) {
77 this.current_user = userbox;
78 } else {
79 user_grid.add (userbox);
80 }
81 }
82 } catch (IOError e) {
83 stderr.printf ("ERROR: %s\n", e.message);
84 }148 }
85 }149 }
86150
87 private Session.Widgets.Userbox new_user (string user_address) {151 private void add_user (Act.User user) {
88 var user = new Session.Services.User (user_address);
89 var userbox = new Session.Widgets.Userbox (user);152 var userbox = new Session.Widgets.Userbox (user);
90153 userbox_list.append (userbox);
91 delete_user.connect ((user_path) => {154
92 if (userbox.user.user_path == user_path) {155 user_grid.add (userbox);
93 user_grid.remove (userbox);156
157 users_separator.visible = true;
158 }
159
160 private Widgets.Userbox? get_userbox_from_user (Act.User user) {
161 foreach (Widgets.Userbox userbox in userbox_list) {
162 if (userbox.user.get_user_name () == user.get_user_name ()) {
163 return userbox;
94 }164 }
95 });165 }
96166
97 users_separator.visible = true;167 return null;
98168 }
99 return userbox;169
100 }170 private void remove_user (Act.User user) {
101171 var userbox = get_userbox_from_user (user);
102 public Session.Widgets.Userbox guest (bool logged_in) {172 if (userbox == null) {
173 return;
174 }
175
176 userbox_list.remove (userbox);
177 user_grid.remove (userbox);
178 }
179
180 private void update_user (Act.User user) {
181 var userbox = get_userbox_from_user (user);
182 if (userbox == null) {
183 return;
184 }
185
186 userbox.update_state ();
187 }
188
189 public void update_all () {
190 foreach (var userbox in userbox_list) {
191 userbox.update_state ();
192 }
193 }
194
195 public void add_guest (bool logged_in) {
103 var userbox = new Session.Widgets.Userbox.from_data (_("Guest"), logged_in, true);196 var userbox = new Session.Widgets.Userbox.from_data (_("Guest"), logged_in, true);
197 userbox_list.append (userbox);
104 userbox.visible = true;198 userbox.visible = true;
105199
200 user_grid.add_guest (userbox);
201
106 users_separator.visible = true;202 users_separator.visible = true;
107
108 return userbox;
109 }203 }
110}204}
111205
=== modified file 'src/Widgets/UserBox.vala'
--- src/Widgets/UserBox.vala 2016-05-21 17:15:08 +0000
+++ src/Widgets/UserBox.vala 2016-08-08 16:32:36 +0000
@@ -22,28 +22,30 @@
22 private const string LOGGED_OFF = _("Logged out");22 private const string LOGGED_OFF = _("Logged out");
23 private const int ICON_SIZE = 48;23 private const int ICON_SIZE = 48;
2424
25 public Session.Services.User user { public get; private set; }25 public Act.User? user { public get; private set; }
26 public bool is_guest = false;26 public bool is_guest = false;
2727
28 private Granite.Widgets.Avatar avatar;28 private Granite.Widgets.Avatar avatar;
29 private Gtk.Label fullname_label;29 private Gtk.Label fullname_label;
30 private Gtk.Label status_label;30 private Gtk.Label status_label;
3131
32 public Userbox (Session.Services.User user) {32 public Userbox (Act.User user) {
33 this.user = user;33 this.user = user;
34 build_ui ();34 build_ui ();
35 connect_signals ();35 connect_signals ();
36 user.update_properties ();36 update ();
37 update_state ();
37 }38 }
3839
39 public Userbox.from_data (string fullname, bool logged_in, bool is_guest = false) {40 public Userbox.from_data (string fullname, bool logged_in, bool is_guest = false) {
40 this.is_guest = is_guest;41 this.is_guest = is_guest;
41 build_ui (false);42 this.user = null;
43 build_ui ();
42 fullname_label.label = "<b>" + fullname + "</b>";44 fullname_label.label = "<b>" + fullname + "</b>";
43 update_state (logged_in);45 update_state ();
44 }46 }
4547
46 private void build_ui (bool load_icon = true) {48 private void build_ui () {
47 get_style_context ().add_class ("menuitem");49 get_style_context ().add_class ("menuitem");
4850
49 var grid = new Gtk.Grid ();51 var grid = new Gtk.Grid ();
@@ -56,11 +58,12 @@
56 status_label = new Gtk.Label (LOGGED_OFF);58 status_label = new Gtk.Label (LOGGED_OFF);
57 status_label.halign = Gtk.Align.START;59 status_label.halign = Gtk.Align.START;
5860
59 if (load_icon) {61 if (is_guest) {
60 avatar = new Granite.Widgets.Avatar.from_file (user.icon_file, ICON_SIZE);
61 } else {
62 avatar = new Granite.Widgets.Avatar.with_default_icon (ICON_SIZE);62 avatar = new Granite.Widgets.Avatar.with_default_icon (ICON_SIZE);
63 } else {
64 avatar = new Granite.Widgets.Avatar.from_file (user.get_icon_file (), ICON_SIZE);
63 }65 }
66
64 avatar.margin_end = 6;67 avatar.margin_end = 6;
6568
66 grid.attach (avatar, 0, 0, 3, 3);69 grid.attach (avatar, 0, 0, 3, 3);
@@ -69,11 +72,34 @@
69 this.add (grid);72 this.add (grid);
70 }73 }
7174
72 public void update (string? fullname, string icon) {75 // For some reason Act.User.is_logged_in () does not work
73 this.fullname_label.set_label ("<b>" + fullname + "</b>");76 public UserState get_user_state () {
77 if (is_guest) {
78 return Services.UserManager.get_guest_state ();
79 }
80
81 return Services.UserManager.get_user_state (user.get_uid ());
82 }
83
84 public bool is_logged_in () {
85 var state = get_user_state ();
86 return state == UserState.ONLINE || state == UserState.ACTIVE;
87 }
88
89 public void set_can_activate (bool can_activate) {
90 selectable = can_activate;
91 activatable = can_activate;
92 }
93
94 private void update () {
95 if (is_guest) {
96 return;
97 }
98
99 this.fullname_label.label = "<b>" + user.get_real_name () + "</b>";
74100
75 try {101 try {
76 var pixbuf = new Gdk.Pixbuf.from_file (icon);102 var pixbuf = new Gdk.Pixbuf.from_file (user.get_icon_file ());
77 pixbuf = pixbuf.scale_simple (ICON_SIZE, ICON_SIZE, Gdk.InterpType.BILINEAR);103 pixbuf = pixbuf.scale_simple (ICON_SIZE, ICON_SIZE, Gdk.InterpType.BILINEAR);
78 avatar.pixbuf = pixbuf;104 avatar.pixbuf = pixbuf;
79 } catch (Error e) {105 } catch (Error e) {
@@ -81,21 +107,33 @@
81 }107 }
82 }108 }
83109
84 public void update_state (bool logged_in) {110 public void update_state () {
85 if (logged_in) {111 var state = get_user_state ();
112 set_can_activate (state != UserState.ACTIVE);
113 if (is_logged_in ()) {
86 status_label.label = LOGGED_IN;114 status_label.label = LOGGED_IN;
87 } else {115 } else {
88 status_label.label = LOGGED_OFF;116 status_label.label = LOGGED_OFF;
89 }117 }
118
119 changed ();
90 }120 }
91121
92 private void connect_signals () {122 private void connect_signals () {
93 user.properties_updated.connect (() => {123 user.changed.connect (() => {
94 update (user.real_name, user.icon_file);124 update ();
95 update_state (user.get_state ());125 update_state ();
96 });126 });
97127
98 user.bind_property ("locked", this, "visible", BindingFlags.SYNC_CREATE | BindingFlags.INVERT_BOOLEAN);128 user.bind_property ("locked", this, "visible", BindingFlags.SYNC_CREATE | BindingFlags.INVERT_BOOLEAN);
99 user.bind_property ("locked", this, "no_show_all", BindingFlags.SYNC_CREATE);129 user.bind_property ("locked", this, "no-show-all", BindingFlags.SYNC_CREATE);
100 }130 }
131
132 public override bool draw (Cairo.Context ctx) {
133 if (!get_selectable ()) {
134 get_style_context ().set_state (Gtk.StateFlags.NORMAL);
135 }
136
137 return base.draw (ctx);
138 }
101}139}
102140
=== modified file 'src/Widgets/UserListBox.vala'
--- src/Widgets/UserListBox.vala 2016-02-22 17:24:06 +0000
+++ src/Widgets/UserListBox.vala 2016-08-08 16:32:36 +0000
@@ -18,6 +18,8 @@
18 */18 */
1919
20 public class Session.Widgets.UserListBox : Gtk.ListBox {20 public class Session.Widgets.UserListBox : Gtk.ListBox {
21 public signal void close ();
22
21 private SeatInterface? seat = null;23 private SeatInterface? seat = null;
22 private string session_path;24 private string session_path;
23 private bool has_guest;25 private bool has_guest;
@@ -32,6 +34,7 @@
32 stderr.printf ("DisplayManager.Seat error: %s\n", e.message);34 stderr.printf ("DisplayManager.Seat error: %s\n", e.message);
33 }35 }
3436
37 this.set_sort_func (sort_func);
35 this.set_activate_on_single_click (true);38 this.set_activate_on_single_click (true);
36 }39 }
3740
@@ -50,14 +53,35 @@
50 return;53 return;
51 }54 }
5255
56 close ();
53 try {57 try {
54 if (userbox.is_guest) {58 if (userbox.is_guest) {
55 seat.switch_to_guest ("");59 seat.switch_to_guest ("");
56 } else {60 } else {
57 seat.switch_to_user (userbox.user.user_name, session_path);61 seat.switch_to_user (userbox.user.get_user_name (), session_path);
58 } 62 }
59 } catch (IOError e) {63 } catch (IOError e) {
60 stderr.printf ("DisplayManager.Seat error: %s\n", e.message);64 stderr.printf ("DisplayManager.Seat error: %s\n", e.message);
61 }65 }
62 }66 }
63 }
64\ No newline at end of file67\ No newline at end of file
68
69 // We could use here Act.User.collate () but we want to show the logged user first
70 public int sort_func (Gtk.ListBoxRow row1, Gtk.ListBoxRow row2) {
71 var userbox1 = (Userbox)row1;
72 var userbox2 = (Userbox)row2;
73
74 if (userbox1.get_user_state () == UserState.ACTIVE) {
75 return -1;
76 } else if (userbox2.get_user_state () == UserState.ACTIVE) {
77 return 1;
78 }
79
80 if (userbox1.is_guest && !userbox2.is_guest) {
81 return 1;
82 } else if (!userbox1.is_guest && userbox2.is_guest) {
83 return -1;
84 }
85
86 return 0;
87 }
88}
65\ No newline at end of file89\ No newline at end of file

Subscribers

People subscribed via source and target branches