Merge lp:~josharenson/unity8/fix-session-icon into lp:unity8
- fix-session-icon
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 2776 | ||||
Proposed branch: | lp:~josharenson/unity8/fix-session-icon | ||||
Merge into: | lp:unity8 | ||||
Prerequisite: | lp:~mterry/unity8/session-lightdm | ||||
Diff against target: |
266 lines (+118/-17) 7 files modified
qml/Greeter/LoginList.qml (+1/-1) qml/Greeter/WideView.qml (+22/-2) tests/mocks/liblightdm/MockController.cpp (+24/-0) tests/mocks/liblightdm/MockController.h (+15/-0) tests/mocks/liblightdm/MockUsersModel.cpp (+37/-14) tests/mocks/liblightdm/MockUsersModel.h (+2/-0) tests/qmltests/Greeter/tst_WideView.qml (+17/-0) |
||||
To merge this branch: | bzr merge lp:~josharenson/unity8/fix-session-icon | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Unity8 CI Bot | continuous-integration | Needs Fixing | |
Michael Terry | Pending | ||
Albert Astals Cid | Pending | ||
Review via email: mp+310381@code.launchpad.net |
This proposal supersedes a proposal from 2016-10-20.
Commit message
Enable the greeter to remember which session the user last logged into
This also fixes a small issue with how the default session was handled.
Description of the change
* Are there any related MPs required for this MP to build/function as expected? Please list.
No
* Did you perform an exploratory manual test run of your code change and any related functionality?
Yes
* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
N/A
* If you changed the UI, has there been a design review?
N/A
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
Albert Astals Cid (aacid) wrote : Posted in a previous version of this proposal | # |
Tested, seems to work well.
Is this something that we can autotest?
Josh Arenson (josharenson) wrote : Posted in a previous version of this proposal | # |
> Tested, seems to work well.
>
> Is this something that we can autotest?
There are some existing tests for the session icons. I think the level of effort to test this small issue would be very high, if even possible. The information for this field is delivered from AccountService via LightDM and thus, would likely require substantial updates to the mocks. Perhaps I'm overthinking this...
It may be a good candidate for an autopilot test, however. If you disagree, lets discuss in person.
Albert Astals Cid (aacid) wrote : Posted in a previous version of this proposal | # |
talked in person, agreed that Josh will evaluate how hard is to add an autotest for the Greeter in which we have two users, set the last used session of user2 to be X (non default) and then while moving to user2 we check that the selected session is the one we set.
Josh Arenson (josharenson) wrote : | # |
Kind of gross, but I added a test.
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2583
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2584
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
- 2585. By Josh Arenson
-
Fix whitespace
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2585
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2585
https:/
Executed test runs:
SUCCESS: https:/
UNSTABLE: https:/
UNSTABLE: https:/
UNSTABLE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Preview Diff
1 | === modified file 'qml/Greeter/LoginList.qml' |
2 | --- qml/Greeter/LoginList.qml 2016-11-16 02:13:48 +0000 |
3 | +++ qml/Greeter/LoginList.qml 2016-11-16 02:13:50 +0000 |
4 | @@ -165,7 +165,7 @@ |
5 | } |
6 | |
7 | delegate: Item { |
8 | - width: parent.width |
9 | + width: userList.width |
10 | height: root.cellHeight |
11 | |
12 | readonly property bool belowHighlight: (userList.currentIndex < 0 && index > 0) || (userList.currentIndex >= 0 && index > userList.currentIndex) |
13 | |
14 | === modified file 'qml/Greeter/WideView.qml' |
15 | --- qml/Greeter/WideView.qml 2016-11-16 02:13:48 +0000 |
16 | +++ qml/Greeter/WideView.qml 2016-11-16 02:13:50 +0000 |
17 | @@ -125,6 +125,8 @@ |
18 | id: loginList |
19 | objectName: "loginList" |
20 | |
21 | + property int selectedUserIndex: 0 |
22 | + |
23 | width: units.gu(40) |
24 | anchors { |
25 | left: parent.left |
26 | @@ -139,12 +141,30 @@ |
27 | Behavior on boxVerticalOffset { UbuntuNumberAnimation {} } |
28 | |
29 | model: root.userModel |
30 | - currentSession: LightDM.Greeter.defaultSession |
31 | + currentSession: LightDM.Users.data(selectedUserIndex, |
32 | + LightDM.UserRoles.SessionRole); |
33 | onResponded: root.responded(response) |
34 | - onSelected: root.selected(index) |
35 | + onSelected: { |
36 | + if (LightDM.Users.mock) { |
37 | + LightDM.Users.mock.currentUsername = currentUser; |
38 | + } |
39 | + |
40 | + loginList.selectedUserIndex = index; |
41 | + root.selected(index) |
42 | + } |
43 | onSessionChooserButtonClicked: parent.state = "SessionsList" |
44 | |
45 | Keys.forwardTo: [sessionChooserLoader.item] |
46 | + |
47 | + // This is only for testing |
48 | + Connections { |
49 | + // TODO when Qt 5.7 |
50 | + //enabled: LightDM.Users.mock |
51 | + target: LightDM.Users |
52 | + onModelReset: { |
53 | + loginList.currentSession = LightDM.Users.data(loginList.selectedUserIndex, LightDM.UserRoles.SessionRole); |
54 | + } |
55 | + } |
56 | } |
57 | |
58 | Loader { |
59 | |
60 | === modified file 'tests/mocks/liblightdm/MockController.cpp' |
61 | --- tests/mocks/liblightdm/MockController.cpp 2016-11-16 02:13:48 +0000 |
62 | +++ tests/mocks/liblightdm/MockController.cpp 2016-11-16 02:13:50 +0000 |
63 | @@ -98,6 +98,30 @@ |
64 | } |
65 | } |
66 | |
67 | +QString MockController::sessionName() const |
68 | +{ |
69 | + return QString("INVALID - Please read directly from the UserModel"); |
70 | +} |
71 | + |
72 | +void MockController::setSessionName(const QString &sessionName) |
73 | +{ |
74 | + // Let the user model deal with this |
75 | + Q_EMIT sessionNameChanged(sessionName, m_currentUsername); |
76 | +} |
77 | + |
78 | +QString MockController::currentUsername() const |
79 | +{ |
80 | + return m_currentUsername; |
81 | +} |
82 | + |
83 | +void MockController::setCurrentUsername(const QString &username) |
84 | +{ |
85 | + if (m_currentUsername != username) { |
86 | + m_currentUsername = username; |
87 | + Q_EMIT currentUsernameChanged(); |
88 | + } |
89 | +} |
90 | + |
91 | const QList<MockController::SessionItem> &MockController::fullSessionItems() const |
92 | { |
93 | return m_fullSessions; |
94 | |
95 | === modified file 'tests/mocks/liblightdm/MockController.h' |
96 | --- tests/mocks/liblightdm/MockController.h 2016-11-16 02:13:48 +0000 |
97 | +++ tests/mocks/liblightdm/MockController.h 2016-11-16 02:13:50 +0000 |
98 | @@ -35,6 +35,11 @@ |
99 | // single, none, full |
100 | Q_PROPERTY(QString sessionMode READ sessionMode WRITE setSessionMode NOTIFY sessionModeChanged) |
101 | |
102 | + // This would be best as a Q_INVOKABLE, but using a property allows for |
103 | + // keeping the mock cleaner |
104 | + Q_PROPERTY(QString sessionName READ sessionName WRITE setSessionName NOTIFY sessionNameChanged) |
105 | + Q_PROPERTY(QString currentUsername READ currentUsername WRITE setCurrentUsername NOTIFY currentUsernameChanged) |
106 | + |
107 | Q_PROPERTY(int numAvailableSessions READ numFullSessions CONSTANT) |
108 | Q_PROPERTY(int numSessions READ numSessions WRITE setNumSessions NOTIFY numSessionsChanged) |
109 | |
110 | @@ -51,6 +56,12 @@ |
111 | QString sessionMode() const; |
112 | void setSessionMode(const QString &sessionMode); |
113 | |
114 | + QString sessionName() const; |
115 | + void setSessionName(const QString &sessionName); |
116 | + |
117 | + QString currentUsername() const; |
118 | + void setCurrentUsername(const QString &userIndex); |
119 | + |
120 | class SessionItem |
121 | { |
122 | public: |
123 | @@ -64,14 +75,18 @@ |
124 | void setNumSessions(int numSessions); |
125 | |
126 | Q_SIGNALS: |
127 | + void currentUsernameChanged(); |
128 | void selectUserHintChanged(); |
129 | void userModeChanged(); |
130 | void sessionModeChanged(); |
131 | + void sessionNameChanged(const QString &sessionName, const QString &username); |
132 | void numSessionsChanged(); |
133 | |
134 | private: |
135 | explicit MockController(QObject* parent=0); |
136 | |
137 | + QString m_currentUsername; |
138 | + QString m_sessionName; |
139 | QString m_selectUserHint; |
140 | QString m_userMode; |
141 | QString m_sessionMode; |
142 | |
143 | === modified file 'tests/mocks/liblightdm/MockUsersModel.cpp' |
144 | --- tests/mocks/liblightdm/MockUsersModel.cpp 2016-11-16 02:13:48 +0000 |
145 | +++ tests/mocks/liblightdm/MockUsersModel.cpp 2016-11-16 02:13:50 +0000 |
146 | @@ -67,6 +67,8 @@ |
147 | |
148 | connect(MockController::instance(), &MockController::userModeChanged, |
149 | this, &UsersModel::resetEntries); |
150 | + connect(MockController::instance(), &MockController::sessionNameChanged, |
151 | + this, &UsersModel::setCurrentSessionName); |
152 | resetEntries(); |
153 | } |
154 | |
155 | @@ -75,6 +77,22 @@ |
156 | delete d_ptr; |
157 | } |
158 | |
159 | +void UsersModel::setCurrentSessionName(const QString &sessionName, const QString &username) |
160 | +{ |
161 | + Q_D(UsersModel); |
162 | + |
163 | + beginResetModel(); |
164 | + |
165 | + for (auto &entry : d->entries) { |
166 | + if (username == entry.username) { |
167 | + entry.session = sessionName; |
168 | + break; |
169 | + } |
170 | + } |
171 | + |
172 | + endResetModel(); |
173 | +} |
174 | + |
175 | int UsersModel::rowCount(const QModelIndex &parent) const |
176 | { |
177 | Q_D(const UsersModel); |
178 | @@ -138,28 +156,33 @@ |
179 | } else if (userMode == "single-pin") { |
180 | d->entries = {{"has-pin", "Has PIN", "", 0, false, false, "ubuntu", 0}}; |
181 | } else if (userMode == "full") { |
182 | + /* |
183 | + * Since the real model sorts these entries alphabetically, the model indices |
184 | + * don't line up correctly. The easiest way to fix this is to ensure that this |
185 | + * list of entries REMAINS IN ALPHABETICAL ORDER at all times. |
186 | + */ |
187 | d->entries = { |
188 | + { "active", "Active Account", 0, 0, true, false, "ubuntu", 0 }, |
189 | + { "auth-error", "Auth Error", 0, 0, false, false, "ubuntu", 0 }, |
190 | + { "black-background", "Black Background", "#000000", 0, false, false, "ubuntu", 0 }, |
191 | + { "color-background", "Color Background", "#E95420", 0, false, false, "ubuntu", 0 }, |
192 | + { "different-prompt", "Different Prompt", 0, 0, false, false, "ubuntu", 0 }, |
193 | + { "empty-name", "", 0, 0, false, false, "ubuntu", 0 }, |
194 | { "has-password", "Has Password", 0, 0, false, false, "ubuntu", 0 }, |
195 | { "has-pin", "Has PIN", 0, 0, false, false, "ubuntu", 0 }, |
196 | - { "different-prompt", "Different Prompt", 0, 0, false, false, "ubuntu", 0 }, |
197 | - { "no-password", "No Password", 0, 0, false, false, "ubuntu", 0 }, |
198 | - { "auth-error", "Auth Error", 0, 0, false, false, "ubuntu", 0 }, |
199 | - { "two-factor", "Two Factor", 0, 0, false, false, "ubuntu", 0 }, |
200 | + { "html-info-prompt", "HTML Info Prompt", 0, 0, false, false, "ubuntu", 0 }, |
201 | { "info-prompt", "Info Prompt", 0, 0, false, false, "ubuntu", 0 }, |
202 | - { "html-info-prompt", "HTML Info Prompt", 0, 0, false, false, "ubuntu", 0 }, |
203 | { "long-info-prompt", "Long Info Prompt", 0, 0, false, false, "ubuntu", 0 }, |
204 | - { "wide-info-prompt", "Wide Info Prompt", 0, 0, false, false, "ubuntu", 0 }, |
205 | + { "long-name", "Long name (far far too long to fit, seriously this would never fit on the screen, you will never see this part of the name)", 0, 0, false, false, "ubuntu", 0 }, |
206 | { "multi-info-prompt", "Multi Info Prompt", 0, 0, false, false, "ubuntu", 0 }, |
207 | - { "long-name", "Long name (far far too long to fit, seriously this would never fit on the screen, you will never see this part of the name)", 0, 0, false, false, "ubuntu", 0 }, |
208 | - { "color-background", "Color Background", "#E95420", 0, false, false, "ubuntu", 0 }, |
209 | + { "no-background", "No Background", "", 0, false, false, "ubuntu", 0 }, |
210 | + { "no-password", "No Password", 0, 0, false, false, "ubuntu", 0 }, |
211 | + { "no-response", "No Response", 0, 0, false, false, "ubuntu", 0 }, |
212 | + { "two-factor", "Two Factor", 0, 0, false, false, "ubuntu", 0 }, |
213 | + { "unicode", "가나다라마", 0, 0, false, false, "ubuntu", 0 }, |
214 | // white and black are a bit redundant, but useful for manually testing if UI is still readable |
215 | { "white-background", "White Background", "#ffffff", 0, false, false, "ubuntu", 0 }, |
216 | - { "black-background", "Black Background", "#000000", 0, false, false, "ubuntu", 0 }, |
217 | - { "no-background", "No Background", "", 0, false, false, "ubuntu", 0 }, |
218 | - { "unicode", "가나다라마", 0, 0, false, false, "ubuntu", 0 }, |
219 | - { "no-response", "No Response", 0, 0, false, false, "ubuntu", 0 }, |
220 | - { "empty-name", "", 0, 0, false, false, "ubuntu", 0 }, |
221 | - { "active", "Active Account", 0, 0, true, false, "ubuntu", 0 }, |
222 | + { "wide-info-prompt", "Wide Info Prompt", 0, 0, false, false, "ubuntu", 0 } |
223 | }; |
224 | } |
225 | |
226 | |
227 | === modified file 'tests/mocks/liblightdm/MockUsersModel.h' |
228 | --- tests/mocks/liblightdm/MockUsersModel.h 2016-11-16 02:13:48 +0000 |
229 | +++ tests/mocks/liblightdm/MockUsersModel.h 2016-11-16 02:13:50 +0000 |
230 | @@ -52,6 +52,8 @@ |
231 | int rowCount(const QModelIndex &parent) const override; |
232 | QVariant data(const QModelIndex &index, int role) const override; |
233 | |
234 | + void setCurrentSessionName(const QString &sessionName, const QString &username); |
235 | + |
236 | QObject *mock(); |
237 | |
238 | private Q_SLOTS: |
239 | |
240 | === modified file 'tests/qmltests/Greeter/tst_WideView.qml' |
241 | --- tests/qmltests/Greeter/tst_WideView.qml 2016-11-16 02:13:48 +0000 |
242 | +++ tests/qmltests/Greeter/tst_WideView.qml 2016-11-16 02:13:50 +0000 |
243 | @@ -409,6 +409,23 @@ |
244 | waitForRendering(view); |
245 | } |
246 | |
247 | + function test_changingSessionSticksToUser() { |
248 | + LightDM.Sessions.mock.sessionMode = "full"; |
249 | + var loginList = findChild(view, "loginList"); |
250 | + var fakeSessionName = "ASessionWillNeverBeCalledThis" |
251 | + |
252 | + compare(LightDM.Sessions.count > 1, true); |
253 | + compare(loginList.currentSession != fakeSessionName, true); |
254 | + |
255 | + LightDM.Users.mock.sessionName = fakeSessionName; |
256 | + tryCompare(loginList, "currentSession", fakeSessionName); |
257 | + |
258 | + // Force a model reset |
259 | + LightDM.Users.mock.userMode = "single"; |
260 | + LightDM.Users.mock.userMode = "full"; |
261 | + |
262 | + } |
263 | + |
264 | function test_tease_data() { |
265 | return [ |
266 | {tag: "locked", x: 0, offset: 0, count: 0, locked: true}, |
PASSED: Continuous integration, rev:2659 /unity8- jenkins. ubuntu. com/job/ lp-unity8- ci/2419/ /unity8- jenkins. ubuntu. com/job/ build/3173 /unity8- jenkins. ubuntu. com/job/ test-0- autopkgtest/ label=amd64, release= vivid+overlay, testname= qmluitests. sh/1810 /unity8- jenkins. ubuntu. com/job/ test-0- autopkgtest/ label=amd64, release= xenial+ overlay, testname= qmluitests. sh/1810 /unity8- jenkins. ubuntu. com/job/ test-0- autopkgtest/ label=amd64, release= yakkety, testname= qmluitests. sh/1810 /unity8- jenkins. ubuntu. com/job/ build-0- fetch/3201 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= vivid+overlay/ 3057 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= vivid+overlay/ 3057/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 3057 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 3057/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= yakkety/ 3057 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= yakkety/ 3057/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= vivid+overlay/ 3057 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= vivid+overlay/ 3057/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 3057 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 3057/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= yakkety/ 3057 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= yakkety/ 3057/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= vivid+overlay/ 3057 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= vivid+overlay/ 3057/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 3057 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 3057/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= yakkety/ 3057 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= yakkety/ 3057/artifact/ output/ *zip*/output. zip
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild: /unity8- jenkins. ubuntu. com/job/ lp-unity8- ci/2419/ rebuild
https:/