on xenial help sign in
Move Lockscreen into Greeter class
1548118Michael Terry
qml/Greeter/Greeter.qml+174−110
@@ -14,36 +14,38 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.0
17+import QtQuick 2.3
18−import Ubuntu.Components 0.1
18+import AccountsService 0.1
19−import Ubuntu.Gestures 0.1
20import LightDM 0.1 as LightDM
19import LightDM 0.1 as LightDM
20+import Ubuntu.Components 1.1
21import "../Components"
21import "../Components"
22
22
23Showable {
23Showable {
24 id: greeter
24 id: greeter
25− enabled: shown
26 created: greeterContentLoader.status == Loader.Ready && greeterContentLoader.item.ready
25 created: greeterContentLoader.status == Loader.Ready && greeterContentLoader.item.ready
27
26
28− x: launcherOffsetProxy + dragOffset
29−
30 property url background
27 property url background
31− property bool loadContent: required
32
28
33 // How far to offset the top greeter layer during a launcher left-drag
29 // How far to offset the top greeter layer during a launcher left-drag
34 property real launcherOffset
30 property real launcherOffset
35
31
36 // 1 when fully shown and 0 when fully hidden
32 // 1 when fully shown and 0 when fully hidden
37− property real showProgress: MathUtils.clamp((width - Math.abs(x)) / width, 0, 1)
33+ property real showProgress: MathUtils.clamp((width - Math.abs(greeterContentLoader.x)) / width, 0, 1)
34+
35+ // True when the greeter is waiting for PAM or other setup process
36+ property bool waiting: true
38
37
39 showAnimation: StandardAnimation { property: "dragOffset"; to: 0; duration: UbuntuAnimation.FastDuration }
38 showAnimation: StandardAnimation { property: "dragOffset"; to: 0; duration: UbuntuAnimation.FastDuration }
40 hideAnimation: __leftHideAnimation
39 hideAnimation: __leftHideAnimation
41
40
42− property alias dragHandleWidth: dragHandle.width
41+ property alias lockscreen: lockscreen
43− property alias model: greeterContentLoader.model
42+
44− property bool locked: true
43+ readonly property bool locked: LightDM.Greeter.active && !LightDM.Greeter.authenticated && !forcedUnlock
44+ property bool forcedUnlock
45+ onForcedUnlockChanged: if (forcedUnlock) lockscreen.hide()
45
46
47+ property bool tabletMode
46− readonly property bool narrowMode: !multiUser && height > width
48+ readonly property bool narrowMode: !multiUser && !tabletMode
47 readonly property bool multiUser: LightDM.Users.count > 1
49 readonly property bool multiUser: LightDM.Users.count > 1
48
50
49 readonly property int currentIndex: greeterContentLoader.currentIndex
51 readonly property int currentIndex: greeterContentLoader.currentIndex
@@ -82,13 +84,13 @@ Showable {
82 }
84 }
83
85
84 function tryToUnlock() {
86 function tryToUnlock() {
85− if (created) {
87+ if (greeterContentLoader.item) {
86 greeterContentLoader.item.tryToUnlock()
88 greeterContentLoader.item.tryToUnlock()
87 }
89 }
88 }
90 }
89
91
90 function reset() {
92 function reset() {
91− if (created) {
93+ if (greeterContentLoader.item) {
92 greeterContentLoader.item.reset()
94 greeterContentLoader.item.reset()
93 }
95 }
94 }
96 }
@@ -109,74 +111,188 @@ Showable {
109 }
111 }
110 }
112 }
111
113
112− // Bi-directional revealer
114+ onShownChanged: {
113− DraggingArea {
115+ if (shown) {
114− id: dragHandle
116+ waiting = true;
115− anchors.fill: parent
116− enabled: (greeter.narrowMode || !greeter.locked) && greeter.enabled && greeter.shown
117− orientation: Qt.Horizontal
118− propagateComposedEvents: true
119
117
120− Component.onCompleted: {
118+ if (narrowMode) {
121− // set evaluators to baseline of dragValue == 0
119+ LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
120+ } else {
122− leftEvaluator.reset()
121+ reset();
123− rightEvaluator.reset()
122+ }
123+ lockedApp = "";
124+ forceActiveFocus();
124 }
125 }
126+ }
125
127
128+ Lockscreen {
129+ id: lockscreen
130+ objectName: "lockscreen"
131+
132+ shown: false
133+ showAnimation: StandardAnimation { property: "opacity"; to: 1 }
134+ hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
135+ anchors.fill: parent
136+ visible: required
137+ background: greeter.background
138+ darkenBackground: 0.4
139+ alphaNumeric: AccountsService.passwordDisplayHint === AccountsService.Keyboard
140+ minPinLength: 4
141+ maxPinLength: 4
142+
143+ property string promptText
144+ infoText: promptText !== "" ? i18n.tr("Enter %1").arg(promptText) :
145+ alphaNumeric ? i18n.tr("Enter passphrase") :
146+ i18n.tr("Enter passcode")
147+ errorText: promptText !== "" ? i18n.tr("Sorry, incorrect %1").arg(promptText) :
148+ alphaNumeric ? i18n.tr("Sorry, incorrect passphrase") + "\n" +
149+ i18n.tr("Please re-enter") :
150+ i18n.tr("Sorry, incorrect passcode")
151+
152+ // FIXME: We *should* show emergency dialer if there is a SIM present,
153+ // regardless of whether the side stage is enabled. But right now,
154+ // the assumption is that narrow screens are phones which have SIMs
155+ // and wider screens are tablets which don't. When we do allow this
156+ // on devices with a side stage and a SIM, work should be done to
157+ // ensure that the main stage is disabled while the dialer is present
158+ // in the side stage. See the FIXME in the stage loader in Shell.qml.
159+ showEmergencyCallButton: !greeter.tabletMode
160+
161+ onEntered: LightDM.Greeter.respond(passphrase);
162+ onCancel: greeter.show()
163+ onEmergencyCall: startLockedApp("dialer-app")
164+
165+ onShownChanged: if (shown) greeter.lockedApp = ""
166+
126− function maybeTease() {
167+ function maybeShow() {
127− if (!greeter.locked || greeter.narrowMode)
168+ if (!greeter.forcedUnlock) {
128− greeter.tease();
169+ show();
170+ }
129 }
171 }
130
172
131− onClicked: maybeTease()
173+ Timer {
132− onDragStart: maybeTease()
174+ id: forcedDelayTimer
133− onPressAndHold: {} // eat event, but no need to tease, as drag will cover it
175+ interval: 1000 * 60
176+ onTriggered: {
177+ if (lockscreen.delayMinutes > 0) {
178+ lockscreen.delayMinutes -= 1
179+ if (lockscreen.delayMinutes > 0) {
180+ start() // go again
181+ }
182+ }
183+ }
184+ }
134
185
135− onDragEnd: {
186+ Component.onCompleted: {
136− if (greeter.dragOffset > 0 && rightEvaluator.shouldAutoComplete()) {
187+ if (greeter.narrowMode) {
137− greeter.hideRight()
188+ LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
138− } else if (greeter.dragOffset < 0 && leftEvaluator.shouldAutoComplete()) {
139− greeter.hide();
140− } else {
141− greeter.show(); // undo drag
142 }
189 }
143 }
190 }
191+ }
192+
193+ Connections {
194+ target: LightDM.Greeter
144
195
145− onDragValueChanged: {
196+ onShowGreeter: greeter.show()
146− // dragValue is kept as a "step" value since we do this adjusting on the fly
197+ onHideGreeter: greeter.login()
147− greeter.dragOffset += dragValue;
198+
199+ onShowPrompt: {
200+ waiting = false;
201+
202+ if (!LightDM.Greeter.active) {
203+ return; // could happen if hideGreeter() comes in before we prompt
204+ }
205+
206+ if (greeter.narrowMode) {
207+ lockscreen.promptText = isDefaultPrompt ? "" : text.toLowerCase();
208+ lockscreen.maybeShow();
209+ }
148 }
210 }
149
211
150− EdgeDragEvaluator {
212+ onPromptlessChanged: {
151− id: rightEvaluator
213+ if (!LightDM.Greeter.active) {
152− trackedPosition: dragHandle.dragValue + greeter.dragOffset
214+ return; // could happen if hideGreeter() comes in before we prompt
153− maxDragDistance: parent.width
215+ }
154− direction: Direction.Rightwards
216+ if (greeter.narrowMode) {
217+ if (LightDM.Greeter.promptless && LightDM.Greeter.authenticated) {
218+ lockscreen.hide()
219+ } else {
220+ lockscreen.reset();
221+ lockscreen.maybeShow();
222+ }
223+ }
155 }
224 }
156
225
157− EdgeDragEvaluator {
226+ onAuthenticationComplete: {
158− id: leftEvaluator
227+ waiting = false;
159− trackedPosition: dragHandle.dragValue + greeter.dragOffset
228+ if (LightDM.Greeter.authenticated) {
160− maxDragDistance: parent.width
229+ AccountsService.failedLogins = 0
161− direction: Direction.Leftwards
230+ }
231+ // Else only penalize user for a failed login if they actually were
232+ // prompted for a password. We do this below after the promptless
233+ // early exit.
234+
235+ if (LightDM.Greeter.promptless) {
236+ return;
237+ }
238+
239+ if (LightDM.Greeter.authenticated) {
240+ greeter.login();
241+ } else {
242+ AccountsService.failedLogins++
243+ if (maxFailedLogins >= 2) { // require at least a warning
244+ if (AccountsService.failedLogins === maxFailedLogins - 1) {
245+ var title = lockscreen.alphaNumeric ?
246+ i18n.tr("Sorry, incorrect passphrase.") :
247+ i18n.tr("Sorry, incorrect passcode.")
248+ var text = i18n.tr("This will be your last attempt.") + " " +
249+ (lockscreen.alphaNumeric ?
250+ i18n.tr("If passphrase is entered incorrectly, your phone will conduct a factory reset and all personal data will be deleted.") :
251+ i18n.tr("If passcode is entered incorrectly, your phone will conduct a factory reset and all personal data will be deleted."))
252+ lockscreen.showInfoPopup(title, text)
253+ } else if (AccountsService.failedLogins >= maxFailedLogins) {
254+ SystemImage.factoryReset() // Ouch!
255+ }
256+ }
257+ if (failedLoginsDelayAttempts > 0 && AccountsService.failedLogins % failedLoginsDelayAttempts == 0) {
258+ lockscreen.delayMinutes = failedLoginsDelayMinutes
259+ forcedDelayTimer.start()
260+ }
261+
262+ lockscreen.clear(true);
263+ if (greeter.narrowMode) {
264+ LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
265+ }
266+ }
162 }
267 }
163 }
268 }
164− TouchGate {
269+
165− targetItem: dragHandle
270+ Binding {
271+ target: LightDM.Greeter
272+ property: "active"
273+ value: greeter.shown || lockscreen.shown || greeter.hasLockedApp
274+ }
275+
276+ Rectangle {
166− anchors.fill: targetItem
277+ anchors.fill: parent
167− enabled: targetItem.enabled
278+ color: "black"
279+ opacity: greeter.showProgress * 0.8
168 }
280 }
169
281
170 Loader {
282 Loader {
171 id: greeterContentLoader
283 id: greeterContentLoader
172 objectName: "greeterContentLoader"
284 objectName: "greeterContentLoader"
173− anchors.fill: parent
285+
286+ x: launcherOffsetProxy + dragOffset
287+ width: parent.width
288+ height: parent.height
289+
174 property var model: LightDM.Users
290 property var model: LightDM.Users
175 property int currentIndex: 0
291 property int currentIndex: 0
176 property var infographicModel: LightDM.Infographic
292 property var infographicModel: LightDM.Infographic
177 readonly property int backgroundTopMargin: -greeter.y
293 readonly property int backgroundTopMargin: -greeter.y
178
294
179− source: loadContent ? "GreeterContent.qml" : ""
295+ source: (greeter.required || lockscreen.required) ? "GreeterContent.qml" : ""
180
296
181 onLoaded: {
297 onLoaded: {
182 selected(currentIndex);
298 selected(currentIndex);
@@ -190,59 +306,7 @@ Showable {
190 greeterContentLoader.currentIndex = uid;
306 greeterContentLoader.currentIndex = uid;
191 }
307 }
192 onUnlocked: greeter.unlocked(uid);
308 onUnlocked: greeter.unlocked(uid);
309+ onTease: greeter.tease()
193 }
310 }
194 }
311 }
195−
196− onTease: showLabelAnimation.start()
197−
198− Label {
199− id: swipeHint
200− visible: greeter.shown
201− property real baseOpacity: 0.5
202− opacity: 0.0
203− anchors.horizontalCenter: parent.horizontalCenter
204− anchors.bottom: parent.bottom
205− anchors.bottomMargin: units.gu(5)
206− text: "《 " + i18n.tr("Unlock") + " 》"
207− color: "white"
208− font.weight: Font.Light
209−
210− SequentialAnimation on opacity {
211− id: showLabelAnimation
212− running: false
213− loops: 2
214−
215− StandardAnimation {
216− from: 0.0
217− to: swipeHint.baseOpacity
218− duration: UbuntuAnimation.SleepyDuration
219− }
220− PauseAnimation { duration: UbuntuAnimation.BriskDuration }
221− StandardAnimation {
222− from: swipeHint.baseOpacity
223− to: 0.0
224− duration: UbuntuAnimation.SleepyDuration
225− }
226− }
227− }
228−
229− // right side shadow
230− Image {
231− anchors.left: parent.right
232− anchors.top: parent.top
233− anchors.bottom: parent.bottom
234− visible: parent.required
235− fillMode: Image.Tile
236− source: "../graphics/dropshadow_right.png"
237− }
238−
239− // left side shadow
240− Image {
241− anchors.right: parent.left
242− anchors.top: parent.top
243− anchors.bottom: parent.bottom
244− visible: parent.required
245− fillMode: Image.Tile
246− source: "../graphics/dropshadow_left.png"
247− }
248}
312}
qml/Greeter/GreeterContent.qml+116−2
@@ -14,10 +14,11 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.0
17+import QtQuick 2.3
18import AccountsService 0.1
18import AccountsService 0.1
19−import Ubuntu.Components 0.1
20import LightDM 0.1 as LightDM
19import LightDM 0.1 as LightDM
20+import Ubuntu.Components 1.1
21+import Ubuntu.Gestures 0.1
21import "../Components"
22import "../Components"
22
23
23Item {
24Item {
@@ -28,6 +29,7 @@ Item {
28
29
29 signal selected(int uid)
30 signal selected(int uid)
30 signal unlocked(int uid)
31 signal unlocked(int uid)
32+ signal tease()
31
33
32 function tryToUnlock() {
34 function tryToUnlock() {
33 if (loginLoader.item) {
35 if (loginLoader.item) {
@@ -41,6 +43,68 @@ Item {
41 }
43 }
42 }
44 }
43
45
46+ onTease: showLabelAnimation.start()
47+
48+ // Bi-directional revealer
49+ DraggingArea {
50+ id: dragHandle
51+ anchors.fill: parent
52+ enabled: greeter.narrowMode || !greeter.locked
53+ orientation: Qt.Horizontal
54+ propagateComposedEvents: true
55+
56+ Component.onCompleted: {
57+ // set evaluators to baseline of dragValue == 0
58+ leftEvaluator.reset();
59+ rightEvaluator.reset();
60+ }
61+
62+ function maybeTease() {
63+ if (!greeter.locked || greeter.narrowMode) {
64+ root.tease();
65+ }
66+ }
67+
68+ onClicked: maybeTease()
69+ onDragStart: maybeTease()
70+ onPressAndHold: {} // eat event, but no need to tease, as drag will cover it
71+
72+ onDragEnd: {
73+ if (greeter.dragOffset > 0 && rightEvaluator.shouldAutoComplete()) {
74+ greeter.hideRight()
75+ } else if (greeter.dragOffset < 0 && leftEvaluator.shouldAutoComplete()) {
76+ greeter.hide();
77+ } else {
78+ greeter.show(); // undo drag
79+ }
80+ }
81+
82+ onDragValueChanged: {
83+ // dragValue is kept as a "step" value since we do this adjusting on the fly
84+ greeter.dragOffset += dragValue;
85+ }
86+
87+ EdgeDragEvaluator {
88+ id: rightEvaluator
89+ trackedPosition: dragHandle.dragValue + greeter.dragOffset
90+ maxDragDistance: parent.width
91+ direction: Direction.Rightwards
92+ }
93+
94+ EdgeDragEvaluator {
95+ id: leftEvaluator
96+ trackedPosition: dragHandle.dragValue + greeter.dragOffset
97+ maxDragDistance: parent.width
98+ direction: Direction.Leftwards
99+ }
100+ }
101+
102+ TouchGate {
103+ targetItem: dragHandle
104+ anchors.fill: targetItem
105+ enabled: targetItem.enabled
106+ }
107+
44 Rectangle {
108 Rectangle {
45 // In case background fails to load
109 // In case background fails to load
46 id: backgroundBackup
110 id: backgroundBackup
@@ -155,4 +219,54 @@ Item {
155 horizontalCenter: parent.horizontalCenter
219 horizontalCenter: parent.horizontalCenter
156 }
220 }
157 }
221 }
222+
223+ Label {
224+ id: swipeHint
225+ property real baseOpacity: 0.5
226+ opacity: 0.0
227+ anchors.horizontalCenter: parent.horizontalCenter
228+ anchors.bottom: parent.bottom
229+ anchors.bottomMargin: units.gu(5)
230+ text: "《 " + i18n.tr("Unlock") + " 》"
231+ color: "white"
232+ font.weight: Font.Light
233+
234+ SequentialAnimation on opacity {
235+ id: showLabelAnimation
236+ running: false
237+ loops: 2
238+
239+ StandardAnimation {
240+ from: 0.0
241+ to: swipeHint.baseOpacity
242+ duration: UbuntuAnimation.SleepyDuration
243+ }
244+ PauseAnimation { duration: UbuntuAnimation.BriskDuration }
245+ StandardAnimation {
246+ from: swipeHint.baseOpacity
247+ to: 0.0
248+ duration: UbuntuAnimation.SleepyDuration
249+ }
250+ }
251+ }
252+
253+ // right side shadow
254+ Image {
255+ anchors.left: parent.right
256+ anchors.top: parent.top
257+ anchors.bottom: parent.bottom
258+ visible: parent.required
259+ fillMode: Image.Tile
260+ source: "../graphics/dropshadow_right.png"
261+ }
262+
263+ // left side shadow
264+ Image {
265+ anchors.right: parent.left
266+ anchors.top: parent.top
267+ anchors.bottom: parent.bottom
268+ visible: parent.required
269+ fillMode: Image.Tile
270+ source: "../graphics/dropshadow_left.png"
271+ }
158}
272}
qml/Shell.qml+8−185
@@ -50,16 +50,17 @@ Item {
50 width: tablet ? units.gu(160) : applicationArguments.hasGeometry() ? applicationArguments.width() : units.gu(40)
50 width: tablet ? units.gu(160) : applicationArguments.hasGeometry() ? applicationArguments.width() : units.gu(40)
51 height: tablet ? units.gu(100) : applicationArguments.hasGeometry() ? applicationArguments.height() : units.gu(71)
51 height: tablet ? units.gu(100) : applicationArguments.hasGeometry() ? applicationArguments.height() : units.gu(71)
52
52
53+ enabled: !greeter.waiting
54+
53 property real edgeSize: units.gu(2)
55 property real edgeSize: units.gu(2)
54 property url defaultBackground: Qt.resolvedUrl(shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg")
56 property url defaultBackground: Qt.resolvedUrl(shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg")
55 property url background: asImageTester.status == Image.Ready ? asImageTester.source
57 property url background: asImageTester.status == Image.Ready ? asImageTester.source
56 : gsImageTester.status == Image.Ready ? gsImageTester.source : defaultBackground
58 : gsImageTester.status == Image.Ready ? gsImageTester.source : defaultBackground
57 readonly property real panelHeight: panel.panelHeight
59 readonly property real panelHeight: panel.panelHeight
58
60
59− readonly property bool locked: LightDM.Greeter.active && !LightDM.Greeter.authenticated && !forcedUnlock
61+ readonly property alias locked: greeter.locked
60 readonly property alias hasLockedApp: greeter.hasLockedApp
62 readonly property alias hasLockedApp: greeter.hasLockedApp
61− readonly property bool forcedUnlock: edgeDemo.running
63+ property alias lockscreen: greeter.lockscreen
62− onForcedUnlockChanged: if (forcedUnlock) lockscreen.hide()
63
64
64 property bool sideStageEnabled: shell.width >= units.gu(100)
65 property bool sideStageEnabled: shell.width >= units.gu(100)
65 readonly property string focusedApplicationId: ApplicationManager.focusedApplicationId
66 readonly property string focusedApplicationId: ApplicationManager.focusedApplicationId
@@ -340,162 +341,6 @@ Item {
340 }
341 }
341 }
342 }
342
343
343− Lockscreen {
344− id: lockscreen
345− objectName: "lockscreen"
346−
347− hides: [launcher, panel.indicators]
348− shown: false
349− enabled: true
350− showAnimation: StandardAnimation { property: "opacity"; to: 1 }
351− hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
352− y: panel.panelHeight
353− visible: required
354− width: parent.width
355− height: parent.height - panel.panelHeight
356− background: shell.background
357− darkenBackground: 0.4
358− alphaNumeric: AccountsService.passwordDisplayHint === AccountsService.Keyboard
359− minPinLength: 4
360− maxPinLength: 4
361−
362− property string promptText
363− infoText: promptText !== "" ? i18n.tr("Enter %1").arg(promptText) :
364− alphaNumeric ? i18n.tr("Enter passphrase") :
365− i18n.tr("Enter passcode")
366− errorText: promptText !== "" ? i18n.tr("Sorry, incorrect %1").arg(promptText) :
367− alphaNumeric ? i18n.tr("Sorry, incorrect passphrase") + "\n" +
368− i18n.tr("Please re-enter") :
369− i18n.tr("Sorry, incorrect passcode")
370−
371− // FIXME: We *should* show emergency dialer if there is a SIM present,
372− // regardless of whether the side stage is enabled. But right now,
373− // the assumption is that narrow screens are phones which have SIMs
374− // and wider screens are tablets which don't. When we do allow this
375− // on devices with a side stage and a SIM, work should be done to
376− // ensure that the main stage is disabled while the dialer is present
377− // in the side stage. See the FIXME in the stage loader in this file.
378− showEmergencyCallButton: !shell.sideStageEnabled
379−
380− onEntered: LightDM.Greeter.respond(passphrase);
381− onCancel: greeter.show()
382− onEmergencyCall: startLockedApp("dialer-app")
383−
384− onShownChanged: if (shown) greeter.lockedApp = ""
385−
386− function maybeShow() {
387− if (!shell.forcedUnlock) {
388− show()
389− }
390− }
391−
392− Timer {
393− id: forcedDelayTimer
394− interval: 1000 * 60
395− onTriggered: {
396− if (lockscreen.delayMinutes > 0) {
397− lockscreen.delayMinutes -= 1
398− if (lockscreen.delayMinutes > 0) {
399− start() // go again
400− }
401− }
402− }
403− }
404−
405− Component.onCompleted: {
406− if (greeter.narrowMode) {
407− LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
408− }
409− }
410− }
411−
412− Connections {
413− target: LightDM.Greeter
414−
415− onShowGreeter: greeter.show()
416− onHideGreeter: greeter.login()
417−
418− onShowPrompt: {
419− shell.enabled = true;
420− if (!LightDM.Greeter.active) {
421− return; // could happen if hideGreeter() comes in before we prompt
422− }
423− if (greeter.narrowMode) {
424− lockscreen.promptText = isDefaultPrompt ? "" : text.toLowerCase();
425− lockscreen.maybeShow();
426− }
427− }
428−
429− onPromptlessChanged: {
430− if (!LightDM.Greeter.active) {
431− return; // could happen if hideGreeter() comes in before we prompt
432− }
433− if (greeter.narrowMode) {
434− if (LightDM.Greeter.promptless && LightDM.Greeter.authenticated) {
435− lockscreen.hide()
436− } else {
437− lockscreen.reset();
438− lockscreen.maybeShow();
439− }
440− }
441− }
442−
443− onAuthenticationComplete: {
444− shell.enabled = true;
445− if (LightDM.Greeter.authenticated) {
446− AccountsService.failedLogins = 0
447− }
448− // Else only penalize user for a failed login if they actually were
449− // prompted for a password. We do this below after the promptless
450− // early exit.
451−
452− if (LightDM.Greeter.promptless) {
453− return;
454− }
455−
456− if (LightDM.Greeter.authenticated) {
457− greeter.login();
458− } else {
459− AccountsService.failedLogins++
460− if (maxFailedLogins >= 2) { // require at least a warning
461− if (AccountsService.failedLogins === maxFailedLogins - 1) {
462− var title = lockscreen.alphaNumeric ?
463− i18n.tr("Sorry, incorrect passphrase.") :
464− i18n.tr("Sorry, incorrect passcode.")
465− var text = i18n.tr("This will be your last attempt.") + " " +
466− (lockscreen.alphaNumeric ?
467− i18n.tr("If passphrase is entered incorrectly, your phone will conduct a factory reset and all personal data will be deleted.") :
468− i18n.tr("If passcode is entered incorrectly, your phone will conduct a factory reset and all personal data will be deleted."))
469− lockscreen.showInfoPopup(title, text)
470− } else if (AccountsService.failedLogins >= maxFailedLogins) {
471− SystemImage.factoryReset() // Ouch!
472− }
473− }
474− if (failedLoginsDelayAttempts > 0 && AccountsService.failedLogins % failedLoginsDelayAttempts == 0) {
475− lockscreen.delayMinutes = failedLoginsDelayMinutes
476− forcedDelayTimer.start()
477− }
478−
479− lockscreen.clear(true);
480− if (greeter.narrowMode) {
481− LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
482− }
483− }
484− }
485− }
486−
487− Binding {
488− target: LightDM.Greeter
489− property: "active"
490− value: greeter.shown || lockscreen.shown || greeter.hasLockedApp
491− }
492−
493− Rectangle {
494− anchors.fill: parent
495− color: "black"
496− opacity: greeter.showProgress * 0.8
497− }
498−
499 Greeter {
344 Greeter {
500 id: greeter
345 id: greeter
501 objectName: "greeter"
346 objectName: "greeter"
@@ -505,20 +350,15 @@ Item {
505
350
506 available: true
351 available: true
507 hides: [launcher, panel.indicators]
352 hides: [launcher, panel.indicators]
508− shown: true
353+ tabletMode: shell.sideStageEnabled
509− loadContent: required || lockscreen.required // keeps content in memory for quick show()
510 launcherOffset: narrowMode ? launcher.progress : 0
354 launcherOffset: narrowMode ? launcher.progress : 0
511−
355+ forcedUnlock: edgeDemo.running
512− locked: shell.locked
513−
514 background: shell.background
356 background: shell.background
515
357
516 y: panel.panelHeight
358 y: panel.panelHeight
517 width: parent.width
359 width: parent.width
518 height: parent.height - panel.panelHeight
360 height: parent.height - panel.panelHeight
519
361
520− dragHandleWidth: shell.edgeSize
521−
522 property bool fullyShown: showProgress === 1.0
362 property bool fullyShown: showProgress === 1.0
523 onFullyShownChanged: {
363 onFullyShownChanged: {
524 // Wait until the greeter is completely covering lockscreen before resetting it.
364 // Wait until the greeter is completely covering lockscreen before resetting it.
@@ -530,7 +370,7 @@ Item {
530
370
531 onShowProgressChanged: {
371 onShowProgressChanged: {
532 if (showProgress === 0) {
372 if (showProgress === 0) {
533− if ((LightDM.Greeter.promptless && LightDM.Greeter.authenticated) || shell.forcedUnlock) {
373+ if ((LightDM.Greeter.promptless && LightDM.Greeter.authenticated) || forcedUnlock) {
534 greeter.login()
374 greeter.login()
535 } else if (narrowMode) {
375 } else if (narrowMode) {
536 lockscreen.clear(false) // to reset focus if necessary
376 lockscreen.clear(false) // to reset focus if necessary
@@ -556,23 +396,6 @@ Item {
556 }
396 }
557 }
397 }
558
398
559− onShownChanged: {
560− if (shown) {
561− // Disable everything so that user can't swipe greeter or
562− // launcher until we get first prompt/authenticate, which
563− // will re-enable the shell.
564− shell.enabled = false;
565−
566− if (greeter.narrowMode) {
567− LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
568− } else {
569− reset()
570− }
571− greeter.lockedApp = "";
572− greeter.forceActiveFocus();
573− }
574− }
575−
576 Component.onCompleted: {
399 Component.onCompleted: {
577 Connectivity.unlockAllModems()
400 Connectivity.unlockAllModems()
578 }
401 }
@@ -590,7 +413,7 @@ Item {
590 Binding {
413 Binding {
591 target: ApplicationManager
414 target: ApplicationManager
592 property: "suspended"
415 property: "suspended"
593− value: (greeter.shown && greeter.showProgress == 1) || lockscreen.shown
416+ value: (greeter.shown && greeter.fullyShown) || lockscreen.shown
594 }
417 }
595 }
418 }
596
419