@@ -16,23 +16,27 @@
17import QtQuick 2.4
17import QtQuick 2.4
18import Ubuntu.Components 1.3
18import Ubuntu.Components 1.3
20FocusScope {
21FocusScope {
24+ property alias background: coverPage.background
25+ property alias backgroundTopMargin: coverPage.backgroundTopMargin
23 property alias dragHandleLeftMargin: coverPage.dragHandleLeftMargin
26 property alias dragHandleLeftMargin: coverPage.dragHandleLeftMargin
27+ property alias infographicModel: coverPage.infographicModel
24 property alias launcherOffset: coverPage.launcherOffset
28 property alias launcherOffset: coverPage.launcherOffset
25− property alias currentIndex: loginList.currentIndex
29+ property alias loginListShown: loginAreaLoader.loginListShown
30+ property int currentIndex // Set from outside
26 property int delayMinutes // TODO
31 property int delayMinutes // TODO
27− property alias backgroundTopMargin: coverPage.backgroundTopMargin
32+ property bool alphanumeric // unused
28− property alias background: coverPage.background
29 property bool locked
33 property bool locked
30− property alias alphanumeric: loginList.alphanumeric
34+ property alias sessionToStart: loginAreaLoader.currentSession
31− property alias userModel: loginList.model
35+ property var userModel // Set from outside
32− property alias infographicModel: coverPage.infographicModel
36+
37+ readonly property bool animating: coverPage.showAnimation.running || coverPage.hideAnimation.running
33 readonly property bool fullyShown: coverPage.showProgress === 1
38 readonly property bool fullyShown: coverPage.showProgress === 1
34 readonly property bool required: coverPage.required
39 readonly property bool required: coverPage.required
35− readonly property bool animating: coverPage.showAnimation.running || coverPage.hideAnimation.running
37 // so that it can be replaced in tests with a mock object
41 // so that it can be replaced in tests with a mock object
38 property var inputMethod: Qt.inputMethod
42 property var inputMethod: Qt.inputMethod
@@ -43,38 +47,39 @@ FocusScope {
43 signal tease()
47 signal tease()
44 signal emergencyCall() // unused
48 signal emergencyCall() // unused
46− function showMessage(html) {
50+ /***** Functions that depend on LoginList being loaded *****/
47− loginList.showMessage(html);
51+ // A decorator to only call LoginList functions when its shown
48− }
52+ function ifLoginlistShownThen(f) {
49−
53+ return function() {
50− function showPrompt(text, isSecret, isDefaultPrompt) {
54+ if (loginListShown) f.apply(this, arguments);
51− loginList.showPrompt(text, isSecret, isDefaultPrompt);
55+ }
54− function showLastChance() {
58− function hide() {
58+ readonly property var notifyAuthenticationFailed: ifLoginlistShownThen(doNotifyAuthenticationFailed);
59− coverPage.hide();
59+ function doNotifyAuthenticationFailed() {
60+ loginAreaLoader.item.showError();
62− function notifyAuthenticationSucceeded() {
63+ readonly property var reset: ifLoginlistShownThen(doReset);
63− // Nothing needed
64+ function doReset() {
65+ loginAreaLoader.item.reset();
66− function notifyAuthenticationFailed() {
68+ readonly property var showMessage: ifLoginlistShownThen(doShowMessage);
67− loginList.showError();
69+ function doShowMessage(html) {
70+ loginAreaLoader.item.showMessage(html);
70− function reset() {
73+ readonly property var showPrompt: ifLoginlistShownThen(doShowPrompt);
71− loginList.reset();
74+ function doShowPrompt(text, isSecret, isDefaultPrompt) {
75+ loginAreaLoader.item.showPrompt(text, isSecret, isDefaultPrompt);
78+ readonly property var tryToUnlock: ifLoginlistShownThen(doTryToUnlock);
74− function tryToUnlock(toTheRight) {
79+ function doTryToUnlock(toTheRight) {
75 if (root.locked) {
80 if (root.locked) {
76 coverPage.show();
81 coverPage.show();
77− loginList.tryToUnlock();
82+ loginAreaLoader.item.tryToUnlock();
78 return false;
83 return false;
80 var coverChanged = coverPage.shown;
85 var coverChanged = coverPage.shown;
@@ -87,6 +92,19 @@ FocusScope {
95+ /***** Functions that are agnostic of what object is loaded *****/
100+ function notifyAuthenticationSucceeded() {
104+ function showLastChance() {
90 Rectangle {
108 Rectangle {
91 anchors.fill: parent
109 anchors.fill: parent
92 color: "black"
110 color: "black"
@@ -102,7 +120,7 @@ FocusScope {
103 infographics {
121 infographics {
104 height: 0.75 * parent.height
122 height: 0.75 * parent.height
105− anchors.leftMargin: loginList.x + loginList.width
123+ anchors.leftMargin: loginAreaLoader.x + loginAreaLoader.width
108 onTease: root.tease()
126 onTease: root.tease()
@@ -113,25 +131,98 @@ FocusScope {
116− LoginList {
134+ Loader {
117− id: loginList
135+ id: loginAreaLoader
118− objectName: "loginList"
136+ objectName: "loginAreaLoader"
138+ // True when LoginList is shown, false when SessionList is shown
139+ property bool loginListShown: true
140+ property bool sessionUpdated: false
141+ property string currentSession: LightDMService.sessions.defaultSession // Set as soon as LoginList is loaded
143+ source: loginListShown ? "LoginList.qml" : "SessionsList.qml"
144+ onSourceChanged: loadingAnimation.running = true
120 anchors {
146 anchors {
121 left: parent.left
147 left: parent.left
122 leftMargin: Math.min(parent.width * 0.16, units.gu(20))
148 leftMargin: Math.min(parent.width * 0.16, units.gu(20))
123 top: parent.top
149 top: parent.top
125 width: units.gu(29)
152 width: units.gu(29)
153+ height: inputMethod && inputMethod.visible ?
126− height: inputMethod && inputMethod.visible ? parent.height - inputMethod.keyboardRectangle.height
154+ parent.height - inputMethod.keyboardRectangle.height : parent.height
128 Behavior on height { UbuntuNumberAnimation {} }
156 Behavior on height { UbuntuNumberAnimation {} }
130− locked: root.locked
158+ UbuntuNumberAnimation {
159+ id: loadingAnimation
160+ target: loginAreaLoader.item
162+ from: loader.item ? loader.item.width : 0
132− onPromptlessLogin: root.promptlessLogin()
167+ Binding {
168+ target: loginAreaLoader.item
169+ property: "currentIndex"
170+ value: loginListShown ? root.currentIndex : null
174+ target: loginAreaLoader.item
180+ target: loginAreaLoader.item
182+ value: loginListShown ? root.userModel : null
185+ // Only inform LoginList if the session isn't the user's default session
186+ // because LoginList gets the default session on its own
188+ target: loginAreaLoader.item
189+ property: "selectedSession"
190+ value: loginListShown && loginAreaLoader.sessionUpdated ?
191+ loginAreaLoader.currentSession : null
195+ target: loginAreaLoader.item
196+ property: "initiallySelectedSession"
197+ value: !loginListShown ? loginAreaLoader.currentSession : null
201+ target: loginListShown ? loginAreaLoader.item : null
133− onSelected: root.selected(index)
202+ onSelected: root.selected(index)
134− onResponded: root.responded(response)
203+ onResponded: root.responded(response)
204+ // The initially selected session lags behind the component completion
205+ // so this provides the initial session name when available
206+ onLoginListSessionChanged: {
207+ if (loginListShown && !loginAreaLoader.sessionUpdated) {
208+ loginAreaLoader.currentSession = loginAreaLoader.item.currentSession
211+ onPromptlessLogin: root.promptlessLogin()
213+ onSessionChooserButtonClicked: loginListShown = false;
214+ ignoreUnknownSignals: true
218+ target: !loginListShown ? loginAreaLoader.item : null
219+ onSessionSelected: {
220+ loginAreaLoader.loginListShown = true
221+ loginAreaLoader.sessionUpdated = true
222+ loginAreaLoader.currentSession = sessionName
224+ ignoreUnknownSignals: true