@@ -88,9 +88,9 @@ Item {
8888 }
8989 }
9090
91− function setFakeActiveForApp(app) {
91+ function setLockedApp(app) {
9292 if (shell.locked) {
93− greeter.fakeActiveForApp = app
93+ greeter.lockedApp = app
9494 lockscreen.hide()
9595 }
9696 }
@@ -170,31 +170,37 @@ Item {
170170 Connections {
171171 target: ApplicationManager
172172 onFocusRequested: {
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− setFakeActiveForApp(appId)
177− } else if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== appId) {
178− lockscreen.show();
173+ if (greeter.narrowMode) {
174+ if (appId === "dialer-app") {
175+ // Always let the dialer-app through. Either user asked
176+ // for an emergency call or accepted an incoming call.
177+ setLockedApp(appId)
178+ } else if (greeter.hasLockedApp && greeter.lockedApp !== appId) {
179+ greeter.startUnlock()
180+ }
181+ greeter.hide();
182+ } else {
183+ if (LightDM.Greeter.active) {
184+ greeter.startUnlock()
185+ }
179186 }
180− greeter.hide();
181187 }
182188
183189 onFocusedApplicationIdChanged: {
184− if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== ApplicationManager.focusedApplicationId) {
185− lockscreen.show();
190+ if (greeter.hasLockedApp && greeter.lockedApp !== ApplicationManager.focusedApplicationId) {
191+ greeter.startUnlock()
186192 }
187193 panel.indicators.hide();
188194 }
189195
190196 onApplicationAdded: {
191197 if (greeter.shown && appId != "unity8-dash") {
192− greeter.hide();
198+ greeter.startUnlock()
193199 }
194− if (appId === "dialer-app") {
200+ if (greeter.narrowMode && appId === "dialer-app") {
195201 // Always let the dialer-app through. Either user asked
196202 // for an emergency call or accepted an incoming call.
197− setFakeActiveForApp(appId)
203+ setLockedApp(appId)
198204 }
199205 launcher.hide();
200206 }
@@ -202,9 +208,19 @@ Item {
202208
203209 Loader {
204210 id: applicationsDisplayLoader
211+ objectName: "applicationsDisplayLoader"
205212 anchors.fill: parent
206213
207− source: shell.sideStageEnabled ? "Stages/TabletStage.qml" : "Stages/PhoneStage.qml"
214+ // When we have a locked app, we only want to show that one app.
215+ // FIXME: do this in a less traumatic way. We currently only allow
216+ // locked apps in phone mode (see FIXME in Lockscreen component in
217+ // this same file). When that changes, we need to do something
218+ // nicer here. But this code is currently just to prevent a
219+ // theoretical attack where user enters lockedApp mode, then makes
220+ // the screen larger (maybe connects to monitor) and tries to enter
221+ // tablet mode.
222+ property bool tabletMode: shell.sideStageEnabled && !greeter.hasLockedApp
223+ source: tabletMode ? "Stages/TabletStage.qml" : "Stages/PhoneStage.qml"
208224
209225 Binding {
210226 target: applicationsDisplayLoader.item
@@ -230,7 +246,7 @@ Item {
230246 Binding {
231247 target: applicationsDisplayLoader.item
232248 property: "spreadEnabled"
233− value: edgeDemo.stagesEnabled && greeter.fakeActiveForApp === "" // to support emergency dialer hack
249+ value: edgeDemo.stagesEnabled && !greeter.hasLockedApp
234250 }
235251 Binding {
236252 target: applicationsDisplayLoader.item
@@ -305,14 +321,14 @@ Item {
305321 // and wider screens are tablets which don't. When we do allow this
306322 // on devices with a side stage and a SIM, work should be done to
307323 // ensure that the main stage is disabled while the dialer is present
308− // in the side stage.
324+ // in the side stage. See the FIXME in the stage loader in this file.
309325 showEmergencyCallButton: !shell.sideStageEnabled
310326
311327 onEntered: LightDM.Greeter.respond(passphrase);
312328 onCancel: greeter.show()
313− onEmergencyCall: shell.activateApplication("dialer-app") // will automatically enter fake-active mode
329+ onEmergencyCall: shell.activateApplication("dialer-app") // will automatically enter locked-app mode
314330
315− onShownChanged: if (shown) greeter.fakeActiveForApp = ""
331+ onShownChanged: if (shown) greeter.lockedApp = ""
316332
317333 Timer {
318334 id: forcedDelayTimer
@@ -361,11 +377,13 @@ Item {
361377 }
362378
363379 onPromptlessChanged: {
364− if (LightDM.Greeter.promptless && LightDM.Greeter.authenticated) {
365− lockscreen.hide()
366− } else {
367− lockscreen.reset();
368− lockscreen.show();
380+ if (greeter.narrowMode) {
381+ if (LightDM.Greeter.promptless && LightDM.Greeter.authenticated) {
382+ lockscreen.hide()
383+ } else {
384+ lockscreen.reset();
385+ lockscreen.show();
386+ }
369387 }
370388 }
371389
@@ -415,7 +433,7 @@ Item {
415433 Binding {
416434 target: LightDM.Greeter
417435 property: "active"
418− value: greeter.shown || lockscreen.shown || greeter.fakeActiveForApp != ""
436+ value: greeter.shown || lockscreen.shown || greeter.hasLockedApp
419437 }
420438
421439 Rectangle {
@@ -427,7 +445,8 @@ Item {
427445 Item {
428446 // Just a tiny wrapper to adjust greeter's x without messing with its own dragging
429447 id: greeterWrapper
430− x: launcher.progress
448+ objectName: "greeterWrapper"
449+ x: greeter.narrowMode ? launcher.progress : 0
431450 y: panel.panelHeight
432451 width: parent.width
433452 height: parent.height - panel.panelHeight
@@ -440,7 +459,7 @@ Item {
440459 property bool fullyShown: showProgress === 1.0
441460 onFullyShownChanged: {
442461 // Wait until the greeter is completely covering lockscreen before resetting it.
443− if (fullyShown && !LightDM.Greeter.authenticated) {
462+ if (greeter.narrowMode && fullyShown && !LightDM.Greeter.authenticated) {
444463 lockscreen.reset();
445464 lockscreen.show();
446465 }
@@ -449,7 +468,7 @@ Item {
449468 readonly property real showProgress: MathUtils.clamp((1 - x/width) + greeter.showProgress - 1, 0, 1)
450469 onShowProgressChanged: {
451470 if (showProgress === 0) {
452− if (LightDM.Greeter.authenticated) {
471+ if (LightDM.Greeter.promptless && LightDM.Greeter.authenticated) {
453472 greeter.login()
454473 } else if (greeter.narrowMode) {
455474 lockscreen.clear(false) // to reset focus if necessary
@@ -463,13 +482,16 @@ Item {
463482
464483 signal sessionStarted() // helpful for tests
465484
466− property string fakeActiveForApp: ""
485+ property string lockedApp: ""
486+ property bool hasLockedApp: lockedApp !== ""
467487
468488 available: true
469489 hides: [launcher, panel.indicators]
470490 shown: true
471491 loadContent: required || lockscreen.required // keeps content in memory for quick show()
472492
493+ locked: shell.locked
494+
473495 defaultBackground: shell.background
474496
475497 width: parent.width
@@ -477,6 +499,18 @@ Item {
477499
478500 dragHandleWidth: shell.edgeSize
479501
502+ function startUnlock() {
503+ if (narrowMode) {
504+ if (!LightDM.Greeter.authenticated) {
505+ lockscreen.show()
506+ }
507+ hide()
508+ } else {
509+ show()
510+ tryToUnlock()
511+ }
512+ }
513+
480514 function login() {
481515 enabled = false;
482516 if (LightDM.Greeter.startSessionSync()) {
@@ -492,8 +526,10 @@ Item {
492526 if (shown) {
493527 if (greeter.narrowMode) {
494528 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
529+ } else {
530+ reset()
495531 }
496− greeter.fakeActiveForApp = "";
532+ greeter.lockedApp = "";
497533 greeter.forceActiveFocus();
498534 }
499535 }
@@ -538,10 +574,7 @@ Item {
538574 }
539575
540576 if (LightDM.Greeter.active) {
541− if (!LightDM.Greeter.authenticated) {
542− lockscreen.show()
543− }
544− greeter.hide()
577+ greeter.startUnlock()
545578 }
546579
547580 var animate = !LightDM.Greeter.active && !stages.shown
@@ -550,7 +583,8 @@ Item {
550583 }
551584
552585 function showDash() {
553− if (greeter.fakeActiveForApp !== "") { // just in case user gets here
586+ if (greeter.hasLockedApp || // just in case user gets here
587+ (!greeter.narrowMode && shell.locked)) {
554588 return
555589 }
556590
@@ -577,7 +611,7 @@ Item {
577611 anchors.fill: parent //because this draws indicator menus
578612 indicators {
579613 hides: [launcher]
580− available: edgeDemo.panelEnabled && (!shell.locked || AccountsService.enableIndicatorsWhileLocked) && greeter.fakeActiveForApp === ""
614+ available: edgeDemo.panelEnabled && (!shell.locked || AccountsService.enableIndicatorsWhileLocked) && !greeter.hasLockedApp
581615 contentEnabled: edgeDemo.panelContentEnabled
582616 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
583617
@@ -598,7 +632,7 @@ Item {
598632 ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).fullscreen
599633
600634 fullscreenMode: (topmostApplicationIsFullscreen && !LightDM.Greeter.active && launcher.progress == 0)
601− || greeter.fakeActiveForApp !== ""
635+ || greeter.hasLockedApp
602636 }
603637
604638 Launcher {
@@ -611,7 +645,7 @@ Item {
611645 anchors.bottom: parent.bottom
612646 width: parent.width
613647 dragAreaWidth: shell.edgeSize
614− available: edgeDemo.launcherEnabled && (!shell.locked || AccountsService.enableLauncherWhileLocked) && greeter.fakeActiveForApp === ""
648+ available: edgeDemo.launcherEnabled && (!shell.locked || AccountsService.enableLauncherWhileLocked) && !greeter.hasLockedApp
615649
616650 onShowDashHome: showHome()
617651 onDash: showDash()
@@ -621,8 +655,8 @@ Item {
621655 }
622656 }
623657 onLauncherApplicationSelected: {
624− if (greeter.fakeActiveForApp !== "") {
625− lockscreen.show()
658+ if (greeter.hasLockedApp) {
659+ greeter.startUnlock()
626660 }
627661 if (!edgeDemo.running)
628662 shell.activateApplication(appId)