@@ -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 }
@@ -133,6 +133,13 @@ Item {
133133 z: edgeDemo.z + 10
134134 }
135135
136+ Binding {
137+ target: ApplicationManager
138+ property: "forceDashActive"
139+ value: launcher.shown || launcher.dashSwipe
140+ }
141+
142+
136143 WindowKeysFilter {
137144 // Handle but do not filter out volume keys
138145 Keys.onVolumeUpPressed: { volumeControl.volumeUp(); event.accepted = false; }
@@ -169,32 +176,37 @@ Item {
169176 Connections {
170177 target: ApplicationManager
171178 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();
179+ if (greeter.narrowMode) {
180+ if (appId === "dialer-app") {
181+ // Always let the dialer-app through. Either user asked
182+ // for an emergency call or accepted an incoming call.
183+ setLockedApp(appId)
184+ } else if (greeter.hasLockedApp && greeter.lockedApp !== appId) {
185+ greeter.startUnlock()
186+ }
187+ greeter.hide();
188+ } else {
189+ if (LightDM.Greeter.active) {
190+ greeter.startUnlock()
191+ }
178192 }
179− greeter.hide();
180− launcher.hide();
181193 }
182194
183195 onFocusedApplicationIdChanged: {
184− if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== ApplicationManager.focusedApplicationId) {
185− lockscreen.show();
196+ if (greeter.hasLockedApp && greeter.lockedApp !== ApplicationManager.focusedApplicationId) {
197+ greeter.startUnlock()
186198 }
187199 panel.indicators.hide();
188200 }
189201
190202 onApplicationAdded: {
191203 if (greeter.shown && appId != "unity8-dash") {
192− greeter.hide();
204+ greeter.startUnlock()
193205 }
194− if (appId === "dialer-app") {
206+ if (greeter.narrowMode && appId === "dialer-app") {
195207 // Always let the dialer-app through. Either user asked
196208 // for an emergency call or accepted an incoming call.
197− setFakeActiveForApp(appId)
209+ setLockedApp(appId)
198210 }
199211 launcher.hide();
200212 }
@@ -202,9 +214,19 @@ Item {
202214
203215 Loader {
204216 id: applicationsDisplayLoader
217+ objectName: "applicationsDisplayLoader"
205218 anchors.fill: parent
206219
207− source: shell.sideStageEnabled ? "Stages/TabletStage.qml" : "Stages/PhoneStage.qml"
220+ // When we have a locked app, we only want to show that one app.
221+ // FIXME: do this in a less traumatic way. We currently only allow
222+ // locked apps in phone mode (see FIXME in Lockscreen component in
223+ // this same file). When that changes, we need to do something
224+ // nicer here. But this code is currently just to prevent a
225+ // theoretical attack where user enters lockedApp mode, then makes
226+ // the screen larger (maybe connects to monitor) and tries to enter
227+ // tablet mode.
228+ property bool tabletMode: shell.sideStageEnabled && !greeter.hasLockedApp
229+ source: tabletMode ? "Stages/TabletStage.qml" : "Stages/PhoneStage.qml"
208230
209231 Binding {
210232 target: applicationsDisplayLoader.item
@@ -230,7 +252,7 @@ Item {
230252 Binding {
231253 target: applicationsDisplayLoader.item
232254 property: "spreadEnabled"
233− value: edgeDemo.stagesEnabled && greeter.fakeActiveForApp === "" // to support emergency dialer hack
255+ value: edgeDemo.stagesEnabled && !greeter.hasLockedApp
234256 }
235257 Binding {
236258 target: applicationsDisplayLoader.item
@@ -305,14 +327,14 @@ Item {
305327 // and wider screens are tablets which don't. When we do allow this
306328 // on devices with a side stage and a SIM, work should be done to
307329 // ensure that the main stage is disabled while the dialer is present
308− // in the side stage.
330+ // in the side stage. See the FIXME in the stage loader in this file.
309331 showEmergencyCallButton: !shell.sideStageEnabled
310332
311333 onEntered: LightDM.Greeter.respond(passphrase);
312334 onCancel: greeter.show()
313− onEmergencyCall: shell.activateApplication("dialer-app") // will automatically enter fake-active mode
335+ onEmergencyCall: shell.activateApplication("dialer-app") // will automatically enter locked-app mode
314336
315− onShownChanged: if (shown) greeter.fakeActiveForApp = ""
337+ onShownChanged: if (shown) greeter.lockedApp = ""
316338
317339 Timer {
318340 id: forcedDelayTimer
@@ -361,11 +383,13 @@ Item {
361383 }
362384
363385 onPromptlessChanged: {
364− if (LightDM.Greeter.promptless && LightDM.Greeter.authenticated) {
365− lockscreen.hide()
366− } else {
367− lockscreen.reset();
368− lockscreen.show();
386+ if (greeter.narrowMode) {
387+ if (LightDM.Greeter.promptless && LightDM.Greeter.authenticated) {
388+ lockscreen.hide()
389+ } else {
390+ lockscreen.reset();
391+ lockscreen.show();
392+ }
369393 }
370394 }
371395
@@ -415,7 +439,7 @@ Item {
415439 Binding {
416440 target: LightDM.Greeter
417441 property: "active"
418− value: greeter.shown || lockscreen.shown || greeter.fakeActiveForApp != ""
442+ value: greeter.shown || lockscreen.shown || greeter.hasLockedApp
419443 }
420444
421445 Rectangle {
@@ -427,7 +451,8 @@ Item {
427451 Item {
428452 // Just a tiny wrapper to adjust greeter's x without messing with its own dragging
429453 id: greeterWrapper
430− x: launcher.progress
454+ objectName: "greeterWrapper"
455+ x: greeter.narrowMode ? launcher.progress : 0
431456 y: panel.panelHeight
432457 width: parent.width
433458 height: parent.height - panel.panelHeight
@@ -440,7 +465,7 @@ Item {
440465 property bool fullyShown: showProgress === 1.0
441466 onFullyShownChanged: {
442467 // Wait until the greeter is completely covering lockscreen before resetting it.
443− if (fullyShown && !LightDM.Greeter.authenticated) {
468+ if (greeter.narrowMode && fullyShown && !LightDM.Greeter.authenticated) {
444469 lockscreen.reset();
445470 lockscreen.show();
446471 }
@@ -449,7 +474,7 @@ Item {
449474 readonly property real showProgress: MathUtils.clamp((1 - x/width) + greeter.showProgress - 1, 0, 1)
450475 onShowProgressChanged: {
451476 if (showProgress === 0) {
452− if (LightDM.Greeter.authenticated) {
477+ if (LightDM.Greeter.promptless && LightDM.Greeter.authenticated) {
453478 greeter.login()
454479 } else if (greeter.narrowMode) {
455480 lockscreen.clear(false) // to reset focus if necessary
@@ -463,13 +488,16 @@ Item {
463488
464489 signal sessionStarted() // helpful for tests
465490
466− property string fakeActiveForApp: ""
491+ property string lockedApp: ""
492+ property bool hasLockedApp: lockedApp !== ""
467493
468494 available: true
469495 hides: [launcher, panel.indicators]
470496 shown: true
471497 loadContent: required || lockscreen.required // keeps content in memory for quick show()
472498
499+ locked: shell.locked
500+
473501 defaultBackground: shell.background
474502
475503 width: parent.width
@@ -477,6 +505,18 @@ Item {
477505
478506 dragHandleWidth: shell.edgeSize
479507
508+ function startUnlock() {
509+ if (narrowMode) {
510+ if (!LightDM.Greeter.authenticated) {
511+ lockscreen.show()
512+ }
513+ hide()
514+ } else {
515+ show()
516+ tryToUnlock()
517+ }
518+ }
519+
480520 function login() {
481521 enabled = false;
482522 if (LightDM.Greeter.startSessionSync()) {
@@ -492,8 +532,10 @@ Item {
492532 if (shown) {
493533 if (greeter.narrowMode) {
494534 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
535+ } else {
536+ reset()
495537 }
496− greeter.fakeActiveForApp = "";
538+ greeter.lockedApp = "";
497539 greeter.forceActiveFocus();
498540 }
499541 }
@@ -539,10 +581,7 @@ Item {
539581 }
540582
541583 if (LightDM.Greeter.active) {
542− if (!LightDM.Greeter.authenticated) {
543− lockscreen.show()
544− }
545− greeter.hide()
584+ greeter.startUnlock()
546585 }
547586
548587 var animate = !LightDM.Greeter.active && !stages.shown
@@ -551,7 +590,8 @@ Item {
551590 }
552591
553592 function showDash() {
554− if (greeter.fakeActiveForApp !== "") { // just in case user gets here
593+ if (greeter.hasLockedApp || // just in case user gets here
594+ (!greeter.narrowMode && shell.locked)) {
555595 return
556596 }
557597
@@ -578,7 +618,7 @@ Item {
578618 anchors.fill: parent //because this draws indicator menus
579619 indicators {
580620 hides: [launcher]
581− available: edgeDemo.panelEnabled && (!shell.locked || AccountsService.enableIndicatorsWhileLocked) && greeter.fakeActiveForApp === ""
621+ available: edgeDemo.panelEnabled && (!shell.locked || AccountsService.enableIndicatorsWhileLocked) && !greeter.hasLockedApp
582622 contentEnabled: edgeDemo.panelContentEnabled
583623 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
584624 panelHeight: units.gu(3)
@@ -589,7 +629,7 @@ Item {
589629 ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).fullscreen
590630
591631 fullscreenMode: (topmostApplicationIsFullscreen && !LightDM.Greeter.active && launcher.progress == 0)
592− || greeter.fakeActiveForApp !== ""
632+ || greeter.hasLockedApp
593633 }
594634
595635 Launcher {
@@ -602,22 +642,18 @@ Item {
602642 anchors.bottom: parent.bottom
603643 width: parent.width
604644 dragAreaWidth: shell.edgeSize
605− available: edgeDemo.launcherEnabled && (!shell.locked || AccountsService.enableLauncherWhileLocked) && greeter.fakeActiveForApp === ""
645+ available: edgeDemo.launcherEnabled && (!shell.locked || AccountsService.enableLauncherWhileLocked) && !greeter.hasLockedApp
606646
607647 onShowDashHome: showHome()
608− onDash: {
609− if (ApplicationManager.focusedApplicationId != "unity8-dash") {
610− showDash()
611− }
612− }
648+ onDash: showDash()
613649 onDashSwipeChanged: {
614650 if (dashSwipe) {
615651 dash.setCurrentScope("clickscope", false, true)
616652 }
617653 }
618654 onLauncherApplicationSelected: {
619− if (greeter.fakeActiveForApp !== "") {
620− lockscreen.show()
655+ if (greeter.hasLockedApp) {
656+ greeter.startUnlock()
621657 }
622658 if (!edgeDemo.running)
623659 shell.activateApplication(appId)