on xenial help sign in
Fix translations
30ee98bJosh Arenson
debian/control+1
@@ -189,6 +189,7 @@ Pre-Depends: ${misc:Pre-Depends},
189Depends: ${misc:Depends},
189Depends: ${misc:Depends},
190 ${shlibs:Depends},
190 ${shlibs:Depends},
191Provides: unity-application-impl,
191Provides: unity-application-impl,
192+ unity-application-impl-12,
192 unity-application-impl-13,
193 unity-application-impl-13,
193Replaces: unity8-autopilot (<< 8.02+15.04.20150422-0ubuntu1)
194Replaces: unity8-autopilot (<< 8.02+15.04.20150422-0ubuntu1)
194Description: Fake environment for running Unity 8 shell
195Description: Fake environment for running Unity 8 shell
plugins/LightDM/Greeter.cpp+6
@@ -77,6 +77,12 @@ QString Greeter::defaultSessionHint() const
77 return d->m_greeter->defaultSessionHint();
77 return d->m_greeter->defaultSessionHint();
78}
78}
79
79
80+bool Greeter::lockHint() const
81+{
82+ Q_D(const Greeter);
83+ return d->m_greeter->lockHint();
84+}
85+
80bool Greeter::promptless() const
86bool Greeter::promptless() const
81{
87{
82 Q_D(const Greeter);
88 Q_D(const Greeter);
plugins/LightDM/Greeter.h+2
@@ -37,6 +37,7 @@ class Greeter : public QObject
37 Q_PROPERTY(bool authenticated READ isAuthenticated NOTIFY isAuthenticatedChanged)
37 Q_PROPERTY(bool authenticated READ isAuthenticated NOTIFY isAuthenticatedChanged)
38 Q_PROPERTY(QString authenticationUser READ authenticationUser NOTIFY authenticationUserChanged)
38 Q_PROPERTY(QString authenticationUser READ authenticationUser NOTIFY authenticationUserChanged)
39 Q_PROPERTY(QString defaultSession READ defaultSessionHint CONSTANT)
39 Q_PROPERTY(QString defaultSession READ defaultSessionHint CONSTANT)
40+ Q_PROPERTY(bool lockHint READ lockHint)
40 Q_PROPERTY(bool promptless READ promptless NOTIFY promptlessChanged)
41 Q_PROPERTY(bool promptless READ promptless NOTIFY promptlessChanged)
41
42
42public:
43public:
@@ -46,6 +47,7 @@ public:
46 bool isAuthenticated() const;
47 bool isAuthenticated() const;
47 QString authenticationUser() const;
48 QString authenticationUser() const;
48 QString defaultSessionHint() const;
49 QString defaultSessionHint() const;
50+ bool lockHint() const;
49 bool promptless() const;
51 bool promptless() const;
50
52
51public Q_SLOTS:
53public Q_SLOTS:
qml/Greeter/FullLightDMImpl.qml+2
@@ -22,6 +22,8 @@ Item{
22
22
23 property var greeter: LightDM.Greeter
23 property var greeter: LightDM.Greeter
24 property var infographic: LightDM.Infographic
24 property var infographic: LightDM.Infographic
25+ property var sessions: LightDM.Sessions
26+ property var sessionRoles: LightDM.SessionRoles
25 property var users: LightDM.Users
27 property var users: LightDM.Users
26 property var userRoles: LightDM.UserRoles
28 property var userRoles: LightDM.UserRoles
27
29
qml/Greeter/Greeter.qml+11−1
@@ -55,6 +55,16 @@ Showable {
55
55
56 readonly property bool animating: loader.item ? loader.item.animating : false
56 readonly property bool animating: loader.item ? loader.item.animating : false
57
57
58+ property string sessionToStart: {
59+ if (loader.active && loader.item.sessionToStart !== undefined) {
60+ return loader.item.sessionToStart
61+ } else if (LightDMService.greeter.defaultSession) {
62+ return LightDMService.greeter.defaultSession
63+ } else {
64+ return "ubuntu"
65+ }
66+ }
67+
58 signal tease()
68 signal tease()
59 signal sessionStarted()
69 signal sessionStarted()
60 signal emergencyCall()
70 signal emergencyCall()
@@ -142,7 +152,7 @@ Showable {
142
152
143 function login() {
153 function login() {
144 enabled = false;
154 enabled = false;
145− if (LightDMService.greeter.startSessionSync()) {
155+ if (LightDMService.greeter.startSessionSync(root.sessionToStart.toLowerCase())) {
146 sessionStarted();
156 sessionStarted();
147 if (loader.item) {
157 if (loader.item) {
148 loader.item.notifyAuthenticationSucceeded();
158 loader.item.notifyAuthenticationSucceeded();
qml/Greeter/IntegratedLightDMImpl.qml+2−1
@@ -22,7 +22,8 @@ Item{
22
22
23 property var greeter: LightDM.Greeter
23 property var greeter: LightDM.Greeter
24 property var infographic: LightDM.Infographic
24 property var infographic: LightDM.Infographic
25+ property var sessions: LightDM.Sessions
26+ property var sessionRoles: LightDM.SessionRoles
25 property var users: LightDM.Users
27 property var users: LightDM.Users
26 property var userRoles: LightDM.UserRoles
28 property var userRoles: LightDM.UserRoles
27−
28}
29}
qml/Greeter/LightDMService.qml+2
@@ -27,6 +27,8 @@ Loader {
27
27
28 property var greeter: d.valid ? loader.item.greeter : null
28 property var greeter: d.valid ? loader.item.greeter : null
29 property var infographic: d.valid ? loader.item.infographic : null
29 property var infographic: d.valid ? loader.item.infographic : null
30+ property var sessions: d.valid ? loader.item.sessions : null
31+ property var sessionRoles: d.valid ? loader.item.sessionRoles : null
30 property var users: d.valid ? loader.item.users : null
32 property var users: d.valid ? loader.item.users : null
31 property var userRoles: d.valid ? loader.item.userRoles : null
33 property var userRoles: d.valid ? loader.item.userRoles : null
32
34
qml/Greeter/LoginAreaContainer.qmlnew file+27
@@ -0,0 +1,27 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import "." 0.1
19+
20+Rectangle {
21+ height: units.gu(10)
22+ color: Qt.rgba(0.1, 0.1, 0.1, 0.4)
23+ border.color: Qt.rgba(0.4, 0.4, 0.4, 0.4)
24+ border.width: units.dp(1)
25+ radius: units.gu(1.5)
26+ antialiasing: true
27+}
qml/Greeter/LoginList.qml+54−9
@@ -17,6 +17,7 @@
17import QtQuick 2.4
17import QtQuick 2.4
18import Ubuntu.Components 1.3
18import Ubuntu.Components 1.3
19import "../Components"
19import "../Components"
20+import "." 0.1
20
21
21Item {
22Item {
22 id: root
23 id: root
@@ -30,13 +31,19 @@ Item {
30 readonly property int cellHeight: units.gu(5)
31 readonly property int cellHeight: units.gu(5)
31 readonly property int highlightedHeight: units.gu(10)
32 readonly property int highlightedHeight: units.gu(10)
32 readonly property int moveDuration: 200
33 readonly property int moveDuration: 200
34+ property string selectedSession
35+ property string currentSession: selectedSession ?
36+ selectedSession : userList.currentItem.userSession
33 readonly property string currentUser: userList.currentItem.username
37 readonly property string currentUser: userList.currentItem.username
34 property bool wasPrompted: false
38 property bool wasPrompted: false
35
39
36− signal selected(int index)
40+ signal loginListSessionChanged(string session)
37− signal responded(string response)
38 signal promptlessLogin()
41 signal promptlessLogin()
42+ signal responded(string response)
43+ signal selected(int index)
44+ signal sessionChooserButtonClicked()
39
45
46+ onCurrentSessionChanged: loginListSessionChanged(currentSession)
40 function tryToUnlock() {
47 function tryToUnlock() {
41 if (wasPrompted) {
48 if (wasPrompted) {
42 passwordInput.forceActiveFocus();
49 passwordInput.forceActiveFocus();
@@ -88,19 +95,56 @@ Item {
88 userList.currentIndex = currentIndex;
95 userList.currentIndex = currentIndex;
89 }
96 }
90
97
91− Rectangle {
98+ LoginAreaContainer {
92 id: highlightItem
99 id: highlightItem
93 anchors {
100 anchors {
94 left: parent.left
101 left: parent.left
95 right: parent.right
102 right: parent.right
96 verticalCenter: parent.verticalCenter
103 verticalCenter: parent.verticalCenter
97 }
104 }
98− height: root.highlightedHeight
105+
99− color: Qt.rgba(0.1, 0.1, 0.1, 0.4)
106+ z: sessionChooser.visible ? userList.z + 1 : z
100− border.color: Qt.rgba(0.4, 0.4, 0.4, 0.4)
107+
108+ // Use an AbstractButton due to icon limitations with Button
109+ AbstractButton {
110+ id: sessionChooser
111+ objectName: "sessionChooserButton"
112+
113+ readonly property alias icon: badge.source
114+
115+ visible: LightDMService.sessions.count > 1 &&
116+ !LightDMService.greeter.lockHint
117+
118+ height: units.gu(2.5)
101− border.width: units.dp(1)
119+ width: units.gu(2.5)
120+
121+ anchors {
122+ right: parent.right
123+ rightMargin: units.gu(1)
124+
125+ top: parent.top
102− radius: units.gu(1.5)
126+ topMargin: units.gu(1)
103− antialiasing: true
127+ }
128+
129+ Image {
130+ id: badge
131+ anchors.fill: parent
132+ source: LightDMService.sessions.iconUrl(root.currentSession)
133+ }
134+
135+ onClicked: {
136+ sessionChooserButtonClicked();
137+ }
138+
139+ // Refresh the icon path if looking at different places at runtime
140+ // this is mainly for testing
141+ Connections {
142+ target: LightDMService.sessions
143+ onIconSearchDirectoriesChanged: {
144+ badge.source = LightDMService.sessions.iconUrl(root.currentSession)
145+ }
146+ }
147+ }
104 }
148 }
105
149
106 ListView {
150 ListView {
@@ -133,6 +177,7 @@ Item {
133
177
134 readonly property bool belowHighlight: (userList.currentIndex < 0 && index > 0) || (userList.currentIndex >= 0 && index > userList.currentIndex)
178 readonly property bool belowHighlight: (userList.currentIndex < 0 && index > 0) || (userList.currentIndex >= 0 && index > userList.currentIndex)
135 readonly property int belowOffset: root.highlightedHeight - root.cellHeight
179 readonly property int belowOffset: root.highlightedHeight - root.cellHeight
180+ readonly property string userSession: session
136 readonly property string username: name
181 readonly property string username: name
137
182
138 opacity: {
183 opacity: {
qml/Greeter/NarrowView.qml+1
@@ -31,6 +31,7 @@ FocusScope {
31 property bool alphanumeric
31 property bool alphanumeric
32 property var userModel // unused
32 property var userModel // unused
33 property alias infographicModel: coverPage.infographicModel
33 property alias infographicModel: coverPage.infographicModel
34+ property string sessionToStart
34 readonly property bool fullyShown: coverPage.showProgress === 1 || lockscreen.shown
35 readonly property bool fullyShown: coverPage.showProgress === 1 || lockscreen.shown
35 readonly property bool required: coverPage.required || lockscreen.required
36 readonly property bool required: coverPage.required || lockscreen.required
36 readonly property bool animating: coverPage.showAnimation.running || coverPage.hideAnimation.running
37 readonly property bool animating: coverPage.showAnimation.running || coverPage.hideAnimation.running
qml/Greeter/SessionsList.qmlnew file+72
@@ -0,0 +1,72 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Ubuntu.Components.ListItems 1.3
20+import "." 0.1
21+
22+Item {
23+ id: root
24+ objectName: "sessionsList"
25+
26+ property string initiallySelectedSession
27+ property alias selectedIndex: sessionsList.selectedIndex
28+ signal sessionSelected(string sessionName)
29+
30+ LoginAreaContainer {
31+ height: sessionsList.itemHeight * sessionsList.model.count
32+
33+ anchors {
34+ left: parent.left
35+ right: parent.right
36+ verticalCenter: parent.verticalCenter
37+ }
38+
39+ ItemSelector {
40+ id: sessionsList
41+ objectName: "sessionsListSelector"
42+
43+ property color originalBackground
44+ anchors.centerIn: parent
45+ width: parent.width - units.gu(1)
46+ expanded:true
47+ style: Item{}
48+
49+ model: LightDMService.sessions
50+ delegate: OptionSelectorDelegate {
51+ objectName: "sessionDelegate" + index
52+ iconSource: icon_url
53+ text: display
54+ selected: display.toLowerCase() === initiallySelectedSession.toLowerCase()
55+ }
56+
57+ Component.onCompleted: {
58+ // Disbale the highlighting since it leaks outside of rounded corners
59+ originalBackground = theme.palette.selected.background
60+ theme.palette.selected.background = "transparent"
61+ }
62+ Component.onDestruction: {
63+ theme.palette.selected.background = originalBackground
64+ }
65+
66+ onDelegateClicked: {
67+ sessionSelected(sessionsList.model.data(index,
68+ LightDMService.sessionRoles.DisplayRole));
69+ }
70+ }
71+ }
72+}
qml/Greeter/WideView.qml+128−37
@@ -16,23 +16,27 @@
16
16
17import QtQuick 2.4
17import QtQuick 2.4
18import Ubuntu.Components 1.3
18import Ubuntu.Components 1.3
19+import "." 0.1
19
20
20FocusScope {
21FocusScope {
21 id: root
22 id: root
22
23
24+ property alias background: coverPage.background
25+ property alias backgroundTopMargin: coverPage.backgroundTopMargin
23 property alias dragHandleLeftMargin: coverPage.dragHandleLeftMargin
26 property alias dragHandleLeftMargin: coverPage.dragHandleLeftMargin
27+ property alias infographicModel: coverPage.infographicModel
24 property alias launcherOffset: coverPage.launcherOffset
28 property alias launcherOffset: coverPage.launcherOffset
25− property alias currentIndex: loginList.currentIndex
29+ property alias loginListShown: loginAreaLoader.loginListShown
30+ property int currentIndex // Set from outside
26 property int delayMinutes // TODO
31 property int delayMinutes // TODO
27− property alias backgroundTopMargin: coverPage.backgroundTopMargin
32+ property bool alphanumeric // unused
28− property alias background: coverPage.background
29 property bool locked
33 property bool locked
30− property alias alphanumeric: loginList.alphanumeric
34+ property alias sessionToStart: loginAreaLoader.currentSession
31− property alias userModel: loginList.model
35+ property var userModel // Set from outside
32− property alias infographicModel: coverPage.infographicModel
36+
37+ readonly property bool animating: coverPage.showAnimation.running || coverPage.hideAnimation.running
33 readonly property bool fullyShown: coverPage.showProgress === 1
38 readonly property bool fullyShown: coverPage.showProgress === 1
34 readonly property bool required: coverPage.required
39 readonly property bool required: coverPage.required
35− readonly property bool animating: coverPage.showAnimation.running || coverPage.hideAnimation.running
36
40
37 // so that it can be replaced in tests with a mock object
41 // so that it can be replaced in tests with a mock object
38 property var inputMethod: Qt.inputMethod
42 property var inputMethod: Qt.inputMethod
@@ -43,38 +47,39 @@ FocusScope {
43 signal tease()
47 signal tease()
44 signal emergencyCall() // unused
48 signal emergencyCall() // unused
45
49
46− function showMessage(html) {
50+ /***** Functions that depend on LoginList being loaded *****/
47− loginList.showMessage(html);
51+ // A decorator to only call LoginList functions when its shown
48− }
52+ function ifLoginlistShownThen(f) {
49−
53+ return function() {
50− function showPrompt(text, isSecret, isDefaultPrompt) {
54+ if (loginListShown) f.apply(this, arguments);
51− loginList.showPrompt(text, isSecret, isDefaultPrompt);
55+ }
52− }
53−
54− function showLastChance() {
55− // TODO
56 }
56 }
57
57
58− function hide() {
58+ readonly property var notifyAuthenticationFailed: ifLoginlistShownThen(doNotifyAuthenticationFailed);
59− coverPage.hide();
59+ function doNotifyAuthenticationFailed() {
60+ loginAreaLoader.item.showError();
60 }
61 }
61
62
62− function notifyAuthenticationSucceeded() {
63+ readonly property var reset: ifLoginlistShownThen(doReset);
63− // Nothing needed
64+ function doReset() {
65+ loginAreaLoader.item.reset();
64 }
66 }
65
67
66− function notifyAuthenticationFailed() {
68+ readonly property var showMessage: ifLoginlistShownThen(doShowMessage);
67− loginList.showError();
69+ function doShowMessage(html) {
70+ loginAreaLoader.item.showMessage(html);
68 }
71 }
69
72
70− function reset() {
73+ readonly property var showPrompt: ifLoginlistShownThen(doShowPrompt);
71− loginList.reset();
74+ function doShowPrompt(text, isSecret, isDefaultPrompt) {
75+ loginAreaLoader.item.showPrompt(text, isSecret, isDefaultPrompt);
72 }
76 }
73
77
78+ readonly property var tryToUnlock: ifLoginlistShownThen(doTryToUnlock);
74− function tryToUnlock(toTheRight) {
79+ function doTryToUnlock(toTheRight) {
75 if (root.locked) {
80 if (root.locked) {
76 coverPage.show();
81 coverPage.show();
77− loginList.tryToUnlock();
82+ loginAreaLoader.item.tryToUnlock();
78 return false;
83 return false;
79 } else {
84 } else {
80 var coverChanged = coverPage.shown;
85 var coverChanged = coverPage.shown;
@@ -87,6 +92,19 @@ FocusScope {
87 }
92 }
88 }
93 }
89
94
95+ /***** Functions that are agnostic of what object is loaded *****/
96+ function hide() {
97+ coverPage.hide();
98+ }
99+
100+ function notifyAuthenticationSucceeded() {
101+ // Nothing needed
102+ }
103+
104+ function showLastChance() {
105+ // TODO
106+ }
107+
90 Rectangle {
108 Rectangle {
91 anchors.fill: parent
109 anchors.fill: parent
92 color: "black"
110 color: "black"
@@ -102,7 +120,7 @@ FocusScope {
102
120
103 infographics {
121 infographics {
104 height: 0.75 * parent.height
122 height: 0.75 * parent.height
105− anchors.leftMargin: loginList.x + loginList.width
123+ anchors.leftMargin: loginAreaLoader.x + loginAreaLoader.width
106 }
124 }
107
125
108 onTease: root.tease()
126 onTease: root.tease()
@@ -113,25 +131,98 @@ FocusScope {
113 }
131 }
114 }
132 }
115
133
116− LoginList {
134+ Loader {
117− id: loginList
135+ id: loginAreaLoader
118− objectName: "loginList"
136+ objectName: "loginAreaLoader"
137+
138+ // True when LoginList is shown, false when SessionList is shown
139+ property bool loginListShown: true
140+ property bool sessionUpdated: false
141+ property string currentSession: LightDMService.sessions.defaultSession // Set as soon as LoginList is loaded
142+
143+ source: loginListShown ? "LoginList.qml" : "SessionsList.qml"
144+ onSourceChanged: loadingAnimation.running = true
119
145
120 anchors {
146 anchors {
121 left: parent.left
147 left: parent.left
122 leftMargin: Math.min(parent.width * 0.16, units.gu(20))
148 leftMargin: Math.min(parent.width * 0.16, units.gu(20))
123 top: parent.top
149 top: parent.top
124 }
150 }
151+
125 width: units.gu(29)
152 width: units.gu(29)
153+ height: inputMethod && inputMethod.visible ?
126− height: inputMethod && inputMethod.visible ? parent.height - inputMethod.keyboardRectangle.height
154+ parent.height - inputMethod.keyboardRectangle.height : parent.height
127− : parent.height
155+
128 Behavior on height { UbuntuNumberAnimation {} }
156 Behavior on height { UbuntuNumberAnimation {} }
129
157
130− locked: root.locked
158+ UbuntuNumberAnimation {
159+ id: loadingAnimation
160+ target: loginAreaLoader.item
161+ property: "x"
162+ from: loader.item ? loader.item.width : 0
163+ to: 0
164+ running: false
165+ }
131
166
132− onPromptlessLogin: root.promptlessLogin()
167+ Binding {
168+ target: loginAreaLoader.item
169+ property: "currentIndex"
170+ value: loginListShown ? root.currentIndex : null
171+ }
172+
173+ Binding {
174+ target: loginAreaLoader.item
175+ property: "locked"
176+ value: root.locked
177+ }
178+
179+ Binding {
180+ target: loginAreaLoader.item
181+ property: "model"
182+ value: loginListShown ? root.userModel : null
183+ }
184+
185+ // Only inform LoginList if the session isn't the user's default session
186+ // because LoginList gets the default session on its own
187+ Binding {
188+ target: loginAreaLoader.item
189+ property: "selectedSession"
190+ value: loginListShown && loginAreaLoader.sessionUpdated ?
191+ loginAreaLoader.currentSession : null
192+ }
193+
194+ Binding {
195+ target: loginAreaLoader.item
196+ property: "initiallySelectedSession"
197+ value: !loginListShown ? loginAreaLoader.currentSession : null
198+ }
199+
200+ Connections {
201+ target: loginListShown ? loginAreaLoader.item : null
133− onSelected: root.selected(index)
202+ onSelected: root.selected(index)
134− onResponded: root.responded(response)
203+ onResponded: root.responded(response)
204+ // The initially selected session lags behind the component completion
205+ // so this provides the initial session name when available
206+ onLoginListSessionChanged: {
207+ if (loginListShown && !loginAreaLoader.sessionUpdated) {
208+ loginAreaLoader.currentSession = loginAreaLoader.item.currentSession
209+ }
210+ }
211+ onPromptlessLogin: root.promptlessLogin()
212+
213+ onSessionChooserButtonClicked: loginListShown = false;
214+ ignoreUnknownSignals: true
215+ }
216+
217+ Connections {
218+ target: !loginListShown ? loginAreaLoader.item : null
219+ onSessionSelected: {
220+ loginAreaLoader.loginListShown = true
221+ loginAreaLoader.sessionUpdated = true
222+ loginAreaLoader.currentSession = sessionName
223+ }
224+ ignoreUnknownSignals: true
225+ }
135 }
226 }
136 }
227 }
137}
228}
qml/Greeter/graphics/session_icons/gnome_badge.pngnew file

Binary file not shown.

qml/Greeter/graphics/session_icons/plasma_badge.pngnew file

Binary file not shown.

qml/Greeter/graphics/session_icons/recovery_console_badge.pngnew file

Binary file not shown.

qml/Greeter/graphics/session_icons/ubuntu_badge.pngnew file

Binary file not shown.

qml/Greeter/graphics/session_icons/unknown_badge.pngnew file

Binary file not shown.

tests/mocks/LightDM/IntegratedLightDM/liblightdm/SessionsModelPrivate.cpp+1−1
@@ -49,7 +49,7 @@ void SessionsModelPrivate::resetEntries_multipleSessions()
49 {"", "", "Ubuntu", ""},
49 {"", "", "Ubuntu", ""},
50 {"", "", "GNOME", ""},
50 {"", "", "GNOME", ""},
51 {"", "", "Plasma", ""},
51 {"", "", "Plasma", ""},
52− {"", "", "Unknown?", ""}
52+ {"", "", "Unknown", ""}
53 };
53 };
54}
54}
55
55
tests/qmltests/Greeter/test_session_badges/gnome_badge.pngnew file

Binary file not shown.

tests/qmltests/Greeter/test_session_badges/plasma_badge.pngnew file

Binary file not shown.

tests/qmltests/Greeter/test_session_badges/recovery_console_badge.pngnew file

Binary file not shown.

tests/qmltests/Greeter/test_session_badges/ubuntu_badge.pngnew file

Binary file not shown.

tests/qmltests/Greeter/test_session_badges/unknown_badge.pngnew file

Binary file not shown.

tests/qmltests/Greeter/tst_WideView.qml+99−2
@@ -110,7 +110,6 @@ Item {
110 Column {
110 Column {
111 anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
111 anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
112 spacing: units.gu(1)
112 spacing: units.gu(1)
113−
114 Row {
113 Row {
115 Button {
114 Button {
116 text: "Show Last Chance"
115 text: "Show Last Chance"
@@ -261,6 +260,21 @@ Item {
261 text: "emergency: " + emergencySpy.count
260 text: "emergency: " + emergencySpy.count
262 }
261 }
263 }
262 }
263+ Row {
264+ CheckBox {
265+ id: multipleSessions
266+ onClicked: {
267+ if (checked) {
268+ LightDM.Sessions.testScenario = "multipleSessions"
269+ } else {
270+ LightDM.Sessions.testScenario = "singleSession"
271+ }
272+ }
273+ }
274+ Label {
275+ text: "Multiple sessions"
276+ }
277+ }
264 Row {
278 Row {
265 Button {
279 Button {
266 text: "Reload View"
280 text: "Reload View"
@@ -311,6 +325,7 @@ Item {
311 when: windowShown
325 when: windowShown
312
326
313 property Item view: loader.status === Loader.Ready ? loader.item : null
327 property Item view: loader.status === Loader.Ready ? loader.item : null
328+ property url testIconDirectory: "./test_session_badges"
314
329
315 function init() {
330 function init() {
316 selectIndex(0); // break binding with text field
331 selectIndex(0); // break binding with text field
@@ -318,6 +333,7 @@ Item {
318 respondedSpy.clear();
333 respondedSpy.clear();
319 teaseSpy.clear();
334 teaseSpy.clear();
320 emergencySpy.clear();
335 emergencySpy.clear();
336+ LightDM.Sessions.testScenario = "multipleSessions"
321 }
337 }
322
338
323 function cleanup() {
339 function cleanup() {
@@ -373,6 +389,87 @@ Item {
373 {tag: "right", x: view.width, offset: 0, count: 1, locked: false},
389 {tag: "right", x: view.width, offset: 0, count: 1, locked: false},
374 ]
390 ]
375 }
391 }
392+
393+ function test_sessionIconsAreValid() {
394+ LightDM.Sessions.testScenario = "multipleSessions"
395+ var originalDirectories = LightDM.Sessions.iconSearchDirectories
396+ LightDM.Sessions.iconSearchDirectories = [testIconDirectory]
397+
398+ // Test the login list icon is valid
399+ var sessionChooserButton = findChild(view, "sessionChooserButton");
400+ compare(sessionChooserButton.visible, true);
401+
402+ var session = String(view.sessionToStart).toLowerCase();
403+ var icon = String(sessionChooserButton.icon);
404+ compare(icon.indexOf(session) > -1, true);
405+
406+ // Test the session list icons are valid
407+ view.loginListShown = false;
408+ var sessionsList = findChild(view, "sessionsList");
409+ var sessionsListSelector = findChild(view, "sessionsListSelector");
410+ tryCompare(sessionsList, "visible", true);
411+ tryCompare(sessionsListSelector, "expanded", true);
412+
413+ waitForRendering(sessionsList)
414+ for (var i = 0; i < LightDM.Sessions.count; i++) {
415+ var delegateName = "sessionDelegate" + String(i);
416+ var currentDelegate = findChild(view, delegateName);
417+ var session = String(currentDelegate.text).toLowerCase();
418+ var icon = String(currentDelegate.iconSource);
419+ compare(icon.indexOf(session) > -1, true);
420+ }
421+ }
422+
423+ function test_choosingNewSessionChangesLoginListIcon() {
424+ // Ensure the default session is selected (Ubuntu)
425+ loader.active = false;
426+ loader.active = true;
427+
428+ LightDM.Sessions.testScenario = "multipleSessions";
429+ var sessionChooserButton = findChild(view, "sessionChooserButton");
430+ var icon = String(sessionChooserButton.icon);
431+ compare(icon.indexOf("ubuntu") > -1, true);
432+
433+ tap(sessionChooserButton)
434+ var sessionsListSelector = findChild(view, "sessionsListSelector");
435+ waitForRendering(sessionsListSelector);
436+ for(var i = 0; i < LightDM.Sessions.count; i++) {
437+ var delegateName = "sessionDelegate" + String(i);
438+ var currentDelegate = findChild(view, delegateName);
439+ if (currentDelegate.text === "GNOME") {
440+ tap(currentDelegate);
441+ var sessionChooserButton = findChild(view, "sessionChooserButton");
442+ waitForRendering(sessionChooserButton);
443+ var icon = String(sessionChooserButton.icon);
444+ break;
445+ }
446+ }
447+
448+ compare(icon.indexOf("gnome") > -1, true,
449+ "Expected icon to contain gnome but it was " + icon);
450+ }
451+
452+ function test_noSessionsDoesntBreakView() {
453+ LightDM.Sessions.testScenario = "noSessions"
454+ compare(LightDM.Sessions.count, 0)
455+ }
456+
457+ function test_sessionIconNotShownWithOneSession() {
458+ LightDM.Sessions.testScenario = "singleSession"
459+ compare(LightDM.Sessions.count, 1);
460+
461+ var sessionChooserButton = findChild(view, "sessionChooserButton");
462+ tryCompare(sessionChooserButton, "visible", false);
463+ }
464+
465+ function test_sessionIconShownWithMultipleSessions() {
466+ LightDM.Sessions.testScenario = "multipleSessions"
467+ compare(LightDM.Sessions.count > 1, true);
468+
469+ var sessionChooserButton = findChild(view, "sessionChooserButton");
470+ tryCompare(sessionChooserButton, "visible", true);
471+ }
472+
376 function test_tease(data) {
473 function test_tease(data) {
377 view.locked = data.locked;
474 view.locked = data.locked;
378 view.dragHandleLeftMargin = data.offset;
475 view.dragHandleLeftMargin = data.offset;
@@ -503,7 +600,7 @@ Item {
503 }
600 }
504
601
505 function test_loginListNotCoveredByKeyboard() {
602 function test_loginListNotCoveredByKeyboard() {
506− var loginList = findChild(view, "loginList");
603+ var loginList = findChild(view, "loginAreaLoader").item;
507 compare(loginList.height, view.height);
604 compare(loginList.height, view.height);
508
605
509 // when the vkb shows up, loginList is moved up to remain fully uncovered
606 // when the vkb shows up, loginList is moved up to remain fully uncovered