@@ -21,19 +21,28 @@ import Unity.Application 0.1
21import Ubuntu.Components 0.1
21import Ubuntu.Components 0.1
22import Ubuntu.Gestures 0.1
22import Ubuntu.Gestures 0.1
23import Unity.Launcher 0.1
23import Unity.Launcher 0.1
24+import LightDM 0.1 as LightDM
24import Powerd 0.1
25import Powerd 0.1
25import SessionBroadcast 0.1
26import SessionBroadcast 0.1
26−import SessionManager 0.1
27import "Dash"
27import "Dash"
28import "Launcher"
29import "Launcher"
29import "Panel"
30import "Panel"
30import "Components"
31import "Components"
31import "Notifications"
32import "Notifications"
32import Unity.Notifications 1.0 as NotificationBackend
33import Unity.Notifications 1.0 as NotificationBackend
34−BasicShell {
35+FocusScope {
38+ // this is only here to select the width / height of the window if not running fullscreen
39+ property bool tablet: false
40+ width: tablet ? units.gu(160) : applicationArguments.hasGeometry() ? applicationArguments.width() : units.gu(40)
41+ height: tablet ? units.gu(100) : applicationArguments.hasGeometry() ? applicationArguments.height() : units.gu(71)
43+ property real edgeSize: units.gu(2)
44+ property url defaultBackground: Qt.resolvedUrl(shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg")
45+ property url background
37 readonly property real panelHeight: panel.panelHeight
46 readonly property real panelHeight: panel.panelHeight
39 property bool dashShown: dash.shown
48 property bool dashShown: dash.shown
@@ -69,7 +78,17 @@ BasicShell {
69 id: backgroundSettings
78 id: backgroundSettings
70 schema.id: "org.gnome.desktop.background"
79 schema.id: "org.gnome.desktop.background"
72− backgroundSource: backgroundSettings.pictureUri
81+ property url gSettingsPicture: backgroundSettings.pictureUri != undefined && backgroundSettings.pictureUri.length > 0 ? backgroundSettings.pictureUri : shell.defaultBackground
82+ onGSettingsPictureChanged: {
83+ shell.background = gSettingsPicture
90+ Keys.onVolumeUpPressed: volumeControl.volumeUp()
91+ Keys.onVolumeDownPressed: volumeControl.volumeDown()
75 id: underlayClipper
94 id: underlayClipper
@@ -116,9 +135,10 @@ BasicShell {
117 objectName: "dash"
136 objectName: "dash"
138+ available: !greeter.shown && !lockscreen.shown
119 hides: [stages, launcher, panel.indicators]
139 hides: [stages, launcher, panel.indicators]
120− shown: disappearingAnimationProgress !== 1.0
140+ shown: disappearingAnimationProgress !== 1.0 && greeterWrapper.showProgress !== 1.0
121− enabled: disappearingAnimationProgress === 0.0 && edgeDemo.dashEnabled
141+ enabled: disappearingAnimationProgress === 0.0 && greeterWrapper.showProgress === 0.0 && edgeDemo.dashEnabled
123 anchors {
143 anchors {
124 fill: parent
144 fill: parent
@@ -206,6 +226,7 @@ BasicShell {
206 shown = true;
226 shown = true;
207 panel.indicators.hide();
227 panel.indicators.hide();
208 edgeDemo.stopDemo();
228 edgeDemo.stopDemo();
209 if (!ApplicationManager.focusedApplicationId && ApplicationManager.count > 0 && focusApp) {
230 if (!ApplicationManager.focusedApplicationId && ApplicationManager.count > 0 && focusApp) {
210 ApplicationManager.focusApplication(ApplicationManager.get(0).appId);
231 ApplicationManager.focusApplication(ApplicationManager.get(0).appId);
@@ -246,12 +267,6 @@ BasicShell {
250− target: ApplicationManager
251− property: "suspended"
252− value: !SessionManager.active
256 id: applicationsDisplayLoader
271 id: applicationsDisplayLoader
257 anchors.fill: parent
272 anchors.fill: parent
@@ -276,9 +291,132 @@ BasicShell {
296+ objectName: "lockscreen"
298+ readonly property int backgroundTopMargin: -panel.panelHeight
300+ hides: [launcher, panel.indicators]
303+ showAnimation: StandardAnimation { property: "opacity"; to: 1 }
304+ hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
305+ y: panel.panelHeight
306+ x: required ? 0 : - width
308+ height: parent.height - panel.panelHeight
309+ background: shell.background
313+ onEntered: LightDM.Greeter.respond(passphrase);
314+ onCancel: greeter.show()
316+ Component.onCompleted: {
317+ if (LightDM.Users.count == 1) {
318+ LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
324+ target: LightDM.Greeter
327+ if (LightDM.Users.count == 1) {
328+ // TODO: There's no better way for now to determine if its a PIN or a passphrase.
329+ if (text == "PIN") {
330+ lockscreen.alphaNumeric = false
332+ lockscreen.alphaNumeric = true
334+ lockscreen.placeholderText = i18n.tr("Please enter %1").arg(text);
339+ onAuthenticationComplete: {
340+ if (LightDM.Greeter.promptless) {
343+ if (LightDM.Greeter.authenticated) {
346+ lockscreen.clear(true);
352+ anchors.fill: parent
354+ opacity: greeterWrapper.showProgress * 0.8
358+ // Just a tiny wrapper to adjust greeter's x without messing with its own dragging
360+ x: launcher.progress
361+ y: panel.panelHeight
363+ height: parent.height - panel.panelHeight
366+ enabled: !launcher.dashSwipe
367+ StandardAnimation {}
370+ readonly property real showProgress: MathUtils.clamp((1 - x/width) + greeter.showProgress - 1, 0, 1)
374+ objectName: "greeter"
377+ hides: [launcher, panel.indicators]
380+ defaultBackground: shell.background
383+ height: parent.height
385+ dragHandleWidth: shell.edgeSize
390+ // If there is only one user, we start authenticating with that one here.
391+ // If there are more users, the Greeter will handle that
392+ if (LightDM.Users.count == 1) {
393+ LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
395+ greeter.forceActiveFocus();
399+ onUnlocked: greeter.hide()
401+ // Update launcher items for new user
402+ var user = LightDM.Users.data(uid, LightDM.UserRoles.NameRole);
403+ AccountsService.user = user;
404+ LauncherModel.setUser(user);
407+ onTease: launcher.tease()
410+ target: ApplicationManager
411+ property: "suspended"
412+ value: greeter.shown && greeterWrapper.showProgress == 1
279 InputFilterArea {
417 InputFilterArea {
280 anchors.fill: parent
418 anchors.fill: parent
281− blockInput: ApplicationManager.focusedApplicationId.length === 0 || launcher.shown
419+ blockInput: ApplicationManager.focusedApplicationId.length === 0 || greeter.shown || lockscreen.shown || launcher.shown
282 || panel.indicators.shown
420 || panel.indicators.shown
@@ -290,7 +428,7 @@ BasicShell {
290 // We ignore any display-off signals when the proximity sensor
428 // We ignore any display-off signals when the proximity sensor
291 // is active. This usually indicates something like a phone call.
429 // is active. This usually indicates something like a phone call.
292 if (status == Powerd.Off && (flags & Powerd.UseProximity) == 0) {
430 if (status == Powerd.Off && (flags & Powerd.UseProximity) == 0) {
293− SessionManager.lock();
431+ greeter.showNow();
296 // No reason to chew demo CPU when user isn't watching
434 // No reason to chew demo CPU when user isn't watching
@@ -302,12 +440,17 @@ BasicShell {
305− function showHome(fromLauncher) {
443+ function showHome() {
306− var animate = fromLauncher && !stages.shown
444+ var animate = !greeter.shown && !stages.shown
307 dash.setCurrentScope("clickscope", animate, false)
446 dash.setCurrentScope("clickscope", animate, false)
308 stages.hide()
447 stages.hide()
450+ function hideIndicatorMenu(delay) {
451+ panel.hideIndicatorMenu(delay);
312 id: overlay
455 id: overlay
@@ -324,8 +467,8 @@ BasicShell {
325 property string focusedAppId: ApplicationManager.focusedApplicationId
468 property string focusedAppId: ApplicationManager.focusedApplicationId
326 property var focusedApplication: ApplicationManager.findApplication(focusedAppId)
469 property var focusedApplication: ApplicationManager.findApplication(focusedAppId)
327− fullscreenMode: focusedApplication && stages.fullscreen
470+ fullscreenMode: focusedApplication && stages.fullscreen && !greeter.shown && !lockscreen.shown
328− searchVisible: dash.shown && dash.searchable
471+ searchVisible: !greeter.shown && !lockscreen.shown && dash.shown && dash.searchable
330 InputFilterArea {
473 InputFilterArea {
331 anchors {
474 anchors {
@@ -363,9 +506,8 @@ BasicShell {
363 if (edgeDemo.running)
506 if (edgeDemo.running)
366− showHome(true)
509+ showHome()
369 onDash: {
511 onDash: {
370 if (stages.shown && !stages.overlayMode) {
512 if (stages.shown && !stages.overlayMode) {
371 if (!stages.locked) {
513 if (!stages.locked) {
@@ -373,6 +515,10 @@ BasicShell {
373 launcher.hide();
515 launcher.hide();
518+ if (greeter.shown) {
519+ greeter.hideRight();
377 onDashSwipeChanged: if (dashSwipe && stages.shown) dash.setCurrentScope("clickscope", false, true)
523 onDashSwipeChanged: if (dashSwipe && stages.shown) dash.setCurrentScope("clickscope", false, true)
378 onLauncherApplicationSelected: {
524 onLauncherApplicationSelected: {
@@ -389,7 +535,7 @@ BasicShell {
389 Rectangle {
535 Rectangle {
390 id: modalNotificationBackground
536 id: modalNotificationBackground
392− visible: notifications.useModal && (notifications.state == "narrow")
538+ visible: notifications.useModal && !greeter.shown && (notifications.state == "narrow")
393 color: "#000000"
539 color: "#000000"
394 anchors.fill: parent
540 anchors.fill: parent
395 opacity: 0.5
541 opacity: 0.5
@@ -436,18 +582,11 @@ BasicShell {
436 blockInput: height > 0
582 blockInput: height > 0
441− target: SessionManager
443− if (!SessionManager.active) {
445− panel.indicators.hide()
588+ onFocusChanged: if (!focus) forceActiveFocus();
451 InputFilterArea {
590 InputFilterArea {
452 anchors {
591 anchors {
453 top: parent.top
592 top: parent.top
@@ -468,6 +607,12 @@ BasicShell {
468 blockInput: true
607 blockInput: true
471 OSKController {
616 OSKController {
472 anchors.topMargin: panel.panelHeight
617 anchors.topMargin: panel.panelHeight
473 anchors.fill: parent // as needs to know the geometry of the shell
618 anchors.fill: parent // as needs to know the geometry of the shell
@@ -499,6 +644,7 @@ BasicShell {
500 EdgeDemo {
645 EdgeDemo {
501 id: edgeDemo
646 id: edgeDemo
502 launcher: launcher
648 launcher: launcher
503 dash: dash
649 dash: dash
504 indicators: panel.indicators
650 indicators: panel.indicators
@@ -507,6 +653,6 @@ BasicShell {
508 Connections {
654 Connections {
509 target: SessionBroadcast
655 target: SessionBroadcast
510− onShowHome: showHome(false)
656+ onShowHome: showHome()