@@ -87,9 +87,9 @@ Item {
8787 }
8888 }
8989
90− function setFakeActiveForApp(app) {
90+ function setLockedApp(app) {
9191 if (shell.locked) {
92− greeter.fakeActiveForApp = app
92+ greeter.lockedApp = app
9393 lockscreen.hide()
9494 }
9595 }
@@ -169,31 +169,37 @@ Item {
169169 Connections {
170170 target: ApplicationManager
171171 onFocusRequested: {
172− if (appId === "dialer-app") {
173− // Always let the dialer-app through. Either user asked
174− // for an emergency call or accepted an incoming call.
175− setFakeActiveForApp(appId)
176− } else if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== appId) {
177− lockscreen.show();
172+ if (greeter.narrowMode) {
173+ if (appId === "dialer-app") {
174+ // Always let the dialer-app through. Either user asked
175+ // for an emergency call or accepted an incoming call.
176+ setLockedApp(appId)
177+ } else if (greeter.hasLockedApp && greeter.lockedApp !== appId) {
178+ greeter.startUnlock()
179+ }
180+ greeter.hide();
181+ } else {
182+ if (LightDM.Greeter.active) {
183+ greeter.startUnlock()
184+ }
178185 }
179− greeter.hide();
180186 }
181187
182188 onFocusedApplicationIdChanged: {
183− if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== ApplicationManager.focusedApplicationId) {
184− lockscreen.show();
189+ if (greeter.hasLockedApp && greeter.lockedApp !== ApplicationManager.focusedApplicationId) {
190+ greeter.startUnlock()
185191 }
186192 panel.indicators.hide();
187193 }
188194
189195 onApplicationAdded: {
190196 if (greeter.shown && appId != "unity8-dash") {
191− greeter.hide();
197+ greeter.startUnlock()
192198 }
193− if (appId === "dialer-app") {
199+ if (greeter.narrowMode && appId === "dialer-app") {
194200 // Always let the dialer-app through. Either user asked
195201 // for an emergency call or accepted an incoming call.
196− setFakeActiveForApp(appId)
202+ setLockedApp(appId)
197203 }
198204 launcher.hide();
199205 }
@@ -201,9 +207,19 @@ Item {
201207
202208 Loader {
203209 id: applicationsDisplayLoader
210+ objectName: "applicationsDisplayLoader"
204211 anchors.fill: parent
205212
206− source: shell.sideStageEnabled ? "Stages/TabletStage.qml" : "Stages/PhoneStage.qml"
213+ // When we have a locked app, we only want to show that one app.
214+ // FIXME: do this in a less traumatic way. We currently only allow
215+ // locked apps in phone mode (see FIXME in Lockscreen component in
216+ // this same file). When that changes, we need to do something
217+ // nicer here. But this code is currently just to prevent a
218+ // theoretical attack where user enters lockedApp mode, then makes
219+ // the screen larger (maybe connects to monitor) and tries to enter
220+ // tablet mode.
221+ property bool tabletMode: shell.sideStageEnabled && !greeter.hasLockedApp
222+ source: tabletMode ? "Stages/TabletStage.qml" : "Stages/PhoneStage.qml"
207223
208224 Binding {
209225 target: applicationsDisplayLoader.item
@@ -229,7 +245,7 @@ Item {
229245 Binding {
230246 target: applicationsDisplayLoader.item
231247 property: "spreadEnabled"
232− value: edgeDemo.stagesEnabled && greeter.fakeActiveForApp === "" // to support emergency dialer hack
248+ value: edgeDemo.stagesEnabled && !greeter.hasLockedApp
233249 }
234250 Binding {
235251 target: applicationsDisplayLoader.item
@@ -304,14 +320,14 @@ Item {
304320 // and wider screens are tablets which don't. When we do allow this
305321 // on devices with a side stage and a SIM, work should be done to
306322 // ensure that the main stage is disabled while the dialer is present
307− // in the side stage.
323+ // in the side stage. See the FIXME in the stage loader in this file.
308324 showEmergencyCallButton: !shell.sideStageEnabled
309325
310326 onEntered: LightDM.Greeter.respond(passphrase);
311327 onCancel: greeter.show()
312− onEmergencyCall: shell.activateApplication("dialer-app") // will automatically enter fake-active mode
328+ onEmergencyCall: shell.activateApplication("dialer-app") // will automatically enter locked-app mode
313329
314− onShownChanged: if (shown) greeter.fakeActiveForApp = ""
330+ onShownChanged: if (shown) greeter.lockedApp = ""
315331
316332 Timer {
317333 id: forcedDelayTimer
@@ -360,11 +376,13 @@ Item {
360376 }
361377
362378 onPromptlessChanged: {
363− if (LightDM.Greeter.promptless && LightDM.Greeter.authenticated) {
364− lockscreen.hide()
365− } else {
366− lockscreen.reset();
367− lockscreen.show();
379+ if (greeter.narrowMode) {
380+ if (LightDM.Greeter.promptless && LightDM.Greeter.authenticated) {
381+ lockscreen.hide()
382+ } else {
383+ lockscreen.reset();
384+ lockscreen.show();
385+ }
368386 }
369387 }
370388
@@ -414,7 +432,7 @@ Item {
414432 Binding {
415433 target: LightDM.Greeter
416434 property: "active"
417− value: greeter.shown || lockscreen.shown || greeter.fakeActiveForApp != ""
435+ value: greeter.shown || lockscreen.shown || greeter.hasLockedApp
418436 }
419437
420438 Rectangle {
@@ -426,7 +444,8 @@ Item {
426444 Item {
427445 // Just a tiny wrapper to adjust greeter's x without messing with its own dragging
428446 id: greeterWrapper
429− x: launcher.progress
447+ objectName: "greeterWrapper"
448+ x: greeter.narrowMode ? launcher.progress : 0
430449 y: panel.panelHeight
431450 width: parent.width
432451 height: parent.height - panel.panelHeight
@@ -439,7 +458,7 @@ Item {
439458 property bool fullyShown: showProgress === 1.0
440459 onFullyShownChanged: {
441460 // Wait until the greeter is completely covering lockscreen before resetting it.
442− if (fullyShown && !LightDM.Greeter.authenticated) {
461+ if (greeter.narrowMode && fullyShown && !LightDM.Greeter.authenticated) {
443462 lockscreen.reset();
444463 lockscreen.show();
445464 }
@@ -448,7 +467,7 @@ Item {
448467 readonly property real showProgress: MathUtils.clamp((1 - x/width) + greeter.showProgress - 1, 0, 1)
449468 onShowProgressChanged: {
450469 if (showProgress === 0) {
451− if (LightDM.Greeter.authenticated) {
470+ if (LightDM.Greeter.promptless && LightDM.Greeter.authenticated) {
452471 greeter.login()
453472 } else if (greeter.narrowMode) {
454473 lockscreen.clear(false) // to reset focus if necessary
@@ -462,13 +481,16 @@ Item {
462481
463482 signal sessionStarted() // helpful for tests
464483
465− property string fakeActiveForApp: ""
484+ property string lockedApp: ""
485+ property bool hasLockedApp: lockedApp !== ""
466486
467487 available: true
468488 hides: [launcher, panel.indicators]
469489 shown: true
470490 loadContent: required || lockscreen.required // keeps content in memory for quick show()
471491
492+ locked: shell.locked
493+
472494 defaultBackground: shell.background
473495
474496 width: parent.width
@@ -476,6 +498,18 @@ Item {
476498
477499 dragHandleWidth: shell.edgeSize
478500
501+ function startUnlock() {
502+ if (narrowMode) {
503+ if (!LightDM.Greeter.authenticated) {
504+ lockscreen.show()
505+ }
506+ hide()
507+ } else {
508+ show()
509+ tryToUnlock()
510+ }
511+ }
512+
479513 function login() {
480514 enabled = false;
481515 if (LightDM.Greeter.startSessionSync()) {
@@ -491,8 +525,10 @@ Item {
491525 if (shown) {
492526 if (greeter.narrowMode) {
493527 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
528+ } else {
529+ reset()
494530 }
495− greeter.fakeActiveForApp = "";
531+ greeter.lockedApp = "";
496532 greeter.forceActiveFocus();
497533 }
498534 }
@@ -537,10 +573,7 @@ Item {
537573 }
538574
539575 if (LightDM.Greeter.active) {
540− if (!LightDM.Greeter.authenticated) {
541− lockscreen.show()
542− }
543− greeter.hide()
576+ greeter.startUnlock()
544577 }
545578
546579 var animate = !LightDM.Greeter.active && !stages.shown
@@ -549,7 +582,8 @@ Item {
549582 }
550583
551584 function showDash() {
552− if (greeter.fakeActiveForApp !== "") { // just in case user gets here
585+ if (greeter.hasLockedApp || // just in case user gets here
586+ (!greeter.narrowMode && shell.locked)) {
553587 return
554588 }
555589
@@ -576,7 +610,7 @@ Item {
576610 anchors.fill: parent //because this draws indicator menus
577611 indicators {
578612 hides: [launcher]
579− available: edgeDemo.panelEnabled && (!shell.locked || AccountsService.enableIndicatorsWhileLocked) && greeter.fakeActiveForApp === ""
613+ available: edgeDemo.panelEnabled && (!shell.locked || AccountsService.enableIndicatorsWhileLocked) && !greeter.hasLockedApp
580614 contentEnabled: edgeDemo.panelContentEnabled
581615 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
582616 panelHeight: units.gu(3)
@@ -587,7 +621,7 @@ Item {
587621 ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).fullscreen
588622
589623 fullscreenMode: (topmostApplicationIsFullscreen && !LightDM.Greeter.active && launcher.progress == 0)
590− || greeter.fakeActiveForApp !== ""
624+ || greeter.hasLockedApp
591625 }
592626
593627 Launcher {
@@ -600,7 +634,7 @@ Item {
600634 anchors.bottom: parent.bottom
601635 width: parent.width
602636 dragAreaWidth: shell.edgeSize
603− available: edgeDemo.launcherEnabled && (!shell.locked || AccountsService.enableLauncherWhileLocked) && greeter.fakeActiveForApp === ""
637+ available: edgeDemo.launcherEnabled && (!shell.locked || AccountsService.enableLauncherWhileLocked) && !greeter.hasLockedApp
604638
605639 onShowDashHome: showHome()
606640 onDash: showDash()
@@ -610,8 +644,8 @@ Item {
610644 }
611645 }
612646 onLauncherApplicationSelected: {
613− if (greeter.fakeActiveForApp !== "") {
614− lockscreen.show()
647+ if (greeter.hasLockedApp) {
648+ greeter.startUnlock()
615649 }
616650 if (!edgeDemo.running)
617651 shell.activateApplication(appId)