@@ -26,6 +26,7 @@ StyledItem {
2626
2727 property alias model: userList.model
2828 property alias alphanumeric: promptList.alphanumeric
29+ property alias hasKeyboard: promptList.hasKeyboard
2930 property int currentIndex
3031 property bool locked
3132 property bool waiting
@@ -39,6 +40,8 @@ StyledItem {
3940 property string currentSession // Initially set by LightDM
4041 readonly property string currentUser: userList.currentItem.username
4142
43+ readonly property alias currentUserIndex: userList.currentIndex
44+
4245 signal responded(string response)
4346 signal selected(int index)
4447 signal sessionChooserButtonClicked()
@@ -48,6 +51,7 @@ StyledItem {
4851 }
4952
5053 function showError() {
54+ promptList.loginError = true;
5155 wrongPasswordAnimation.start();
5256 }
5357
@@ -79,6 +83,7 @@ StyledItem {
7983
8084 onCurrentIndexChanged: {
8185 userList.currentIndex = currentIndex;
86+ promptList.loginError = false;
8287 }
8388
8489 LoginAreaContainer {
@@ -93,18 +98,6 @@ StyledItem {
9398
9499 height: Math.max(units.gu(15), promptList.height + units.gu(8))
95100 Behavior on height { NumberAnimation { duration: root.moveDuration; easing.type: Easing.InOutQuad; } }
96−
97− Label {
98− // HACK: Work around https://github.com/ubports/unity8/issues/185
99− text: _realName ? _realName : LightDMService.greeter.authenticationUser
100− visible: userList.count == 1
101− anchors {
102− left: parent.left
103− top: parent.top
104− topMargin: units.gu(2)
105− leftMargin: units.gu(2)
106− }
107− }
108101 }
109102
110103 ListView {
@@ -115,14 +108,16 @@ StyledItem {
115108 anchors.leftMargin: units.gu(2)
116109 anchors.rightMargin: units.gu(2)
117110
118− preferredHighlightBegin: highlightItem.y
119− preferredHighlightEnd: highlightItem.y
111+ preferredHighlightBegin: highlightItem.y + units.gu(1.5)
112+ preferredHighlightEnd: highlightItem.y + units.gu(1.5)
120113 highlightRangeMode: ListView.StrictlyEnforceRange
121114 highlightMoveDuration: root.moveDuration
122115 interactive: count > 1
123116
124117 readonly property bool movingInternally: moveTimer.running || userList.moving
125118
119+ onMovingChanged: if (!moving) root.selected(currentIndex)
120+
126121 onCurrentIndexChanged: {
127122 moveTimer.start();
128123 }
@@ -132,6 +127,7 @@ StyledItem {
132127 height: root.cellHeight
133128
134129 readonly property bool belowHighlight: (userList.currentIndex < 0 && index > 0) || (userList.currentIndex >= 0 && index > userList.currentIndex)
130+ readonly property bool aboveCurrent: (userList.currentIndex > 0 && index < 0) || (userList.currentIndex >= 0 && index < userList.currentIndex)
135131 readonly property int belowOffset: root.highlightedHeight - root.cellHeight
136132 readonly property string userSession: session
137133 readonly property string username: name
@@ -154,41 +150,75 @@ StyledItem {
154150 return 1 - Math.min(1, (Math.abs(highlightDist) + root.cellHeight) / ((root.numAboveBelow + 1) * root.cellHeight))
155151 }
156152
157− FadingLabel {
158− objectName: "username" + index
159− visible: userList.count != 1 // HACK Hide username label until someone sorts out the anchoring with the keyboard-dismiss animation, Work around https://github.com/ubports/unity8/issues/185
153+ Row {
154+ spacing: units.gu(1)
155+// visible: userList.count != 1 // HACK Hide username label until someone sorts out the anchoring with the keyboard-dismiss animation, Work around https://github.com/ubports/unity8/issues/185
160156
161157 anchors {
162− left: parent.left
163158 leftMargin: units.gu(2)
164− right: parent.right
165159 rightMargin: units.gu(2)
160+ horizontalCenter: parent.horizontalCenter
166161 bottom: parent.top
167162 // Add an offset to bottomMargin for any items below the highlight
168− bottomMargin: -(units.gu(4) + (parent.belowHighlight ? parent.belowOffset : 0))
163+ bottomMargin: -(units.gu(4) + (parent.belowHighlight ? parent.belowOffset : parent.aboveCurrent ? -units.gu(5) : 0))
169164 }
170− text: userList.currentIndex === index
171− && name === "*other"
172− && LightDMService.greeter.authenticationUser !== ""
173− ? LightDMService.greeter.authenticationUser : realName
174− color: userList.currentIndex !== index ? theme.palette.normal.raised
175− : theme.palette.normal.raisedText
176−
177− Component.onCompleted: _realName = realName
178−
179− Behavior on anchors.topMargin { NumberAnimation { duration: root.moveDuration; easing.type: Easing.InOutQuad; } }
180165
181166 Rectangle {
182167 id: activeIndicator
183− anchors.horizontalCenter: parent.left
184− anchors.horizontalCenterOffset: -units.gu(1)
185168 anchors.verticalCenter: parent.verticalCenter
186− color: userList.currentIndex !== index ? theme.palette.normal.raised
187− : theme.palette.normal.focus
169+ color: theme.palette.normal.raised
188170 visible: userList.count > 1 && loggedIn
189− height: units.gu(0.5)
171+ height: visible ? units.gu(0.5) : 0
190172 width: height
191173 }
174+
175+ Icon {
176+ id: userIcon
177+ name: "account"
178+ height: userList.currentIndex === index ? units.gu(4.5) : units.gu(3)
179+ width: height
180+ color: theme.palette.normal.raisedSecondaryText
181+ anchors.verticalCenter: parent.verticalCenter
182+ }
183+
184+ Column {
185+ anchors.verticalCenter: parent.verticalCenter
186+ spacing: units.gu(0.25)
187+
188+ FadingLabel {
189+ objectName: "username" + index
190+
191+ text: userList.currentIndex === index
192+ && name === "*other"
193+ && LightDMService.greeter.authenticationUser !== ""
194+ ? LightDMService.greeter.authenticationUser : realName
195+ color: userList.currentIndex !== index ? theme.palette.normal.raised
196+ : theme.palette.normal.raisedSecondaryText
197+ font.weight: userList.currentIndex === index ? Font.Normal : Font.Light
198+ font.pointSize: units.gu(2)
199+
200+ width: highlightItem.width
201+ && contentWidth > highlightItem.width - userIcon.width - units.gu(4)
202+ ? highlightItem.width - userIcon.width - units.gu(4)
203+ : contentWidth
204+
205+ Component.onCompleted: _realName = realName
206+
207+ Behavior on anchors.topMargin { NumberAnimation { duration: root.moveDuration; easing.type: Easing.InOutQuad; } }
208+ }
209+
210+ Row {
211+ spacing: units.gu(1)
212+
213+ FadingLabel {
214+ text: root.alphanumeric ? "Login with password" : "Login with pin"
215+ color: theme.palette.normal.raisedSecondaryText
216+ visible: userList.currentIndex === index && false
217+ font.weight: Font.Light
218+ font.pointSize: units.gu(1.25)
219+ }
220+ }
221+ }
192222 }
193223
194224 MouseArea {
@@ -197,7 +227,7 @@ StyledItem {
197227 right: parent.right
198228 top: parent.top
199229 // Add an offset to topMargin for any items below the highlight
200− topMargin: parent.belowHighlight ? parent.belowOffset : 0
230+ topMargin: parent.belowHighlight ? parent.belowOffset : parent.aboveCurrent ? -units.gu(5) : 0
201231 }
202232 height: parent.height
203233 enabled: userList.currentIndex !== index && parent.opacity > 0
@@ -217,67 +247,6 @@ StyledItem {
217247 }
218248 }
219249
220− // Use an AbstractButton due to icon limitations with Button
221− AbstractButton {
222− id: sessionChooser
223− objectName: "sessionChooserButton"
224−
225− readonly property alias icon: badge.source
226−
227− visible: LightDMService.sessions.count > 1 &&
228− !LightDMService.users.data(userList.currentIndex, LightDMService.userRoles.LoggedInRole)
229−
230− height: units.gu(3.5)
231− width: units.gu(3.5)
232−
233− activeFocusOnTab: true
234− anchors {
235− right: highlightItem.right
236− rightMargin: units.gu(2)
237−
238− top: highlightItem.top
239− topMargin: units.gu(1.5)
240− }
241−
242− Rectangle {
243− id: badgeHighlight
244−
245− anchors.fill: parent
246− visible: parent.activeFocus
247− color: "transparent"
248− border.color: theme.palette.normal.focus
249− border.width: units.dp(1)
250− radius: 3
251− }
252−
253− Icon {
254− id: badge
255− anchors.fill: parent
256− anchors.margins: units.dp(3)
257− keyColor: "#ffffff" // icon providers give us white icons
258− color: theme.palette.normal.raisedSecondaryText
259− source: LightDMService.sessions.iconUrl(root.currentSession)
260− }
261−
262− Keys.onReturnPressed: {
263− sessionChooserButtonClicked();
264− event.accepted = true;
265− }
266−
267− onClicked: {
268− sessionChooserButtonClicked();
269− }
270−
271− // Refresh the icon path if looking at different places at runtime
272− // this is mainly for testing
273− Connections {
274− target: LightDMService.sessions
275− onIconSearchDirectoriesChanged: {
276− badge.source = LightDMService.sessions.iconUrl(root.currentSession)
277− }
278− }
279− }
280−
281250 PromptList {
282251 id: promptList
283252 objectName: "promptList"
@@ -288,6 +257,8 @@ StyledItem {
288257 }
289258 width: highlightItem.width - anchors.margins * 2
290259
260+ focus: true
261+
291262 onClicked: {
292263 interactive = false;
293264 if (root.locked) {