diff --git a/lookandfeel/contents/lockscreen/LockScreenUi.qml b/lookandfeel/contents/lockscreen/LockScreenUi.qml --- a/lookandfeel/contents/lockscreen/LockScreenUi.qml +++ b/lookandfeel/contents/lockscreen/LockScreenUi.qml @@ -28,7 +28,6 @@ import "../components" PlasmaCore.ColorScope { - id: lockScreenRoot colorGroup: PlasmaCore.Theme.ComplementaryColorGroup @@ -69,110 +68,182 @@ visible: false } - Clock { - anchors.bottom: parent.verticalCenter - anchors.bottomMargin: units.gridUnit * 13 - anchors.horizontalCenter: parent.horizontalCenter - } - - ListModel { - id: users + Item { + id: lockScreenRoot - Component.onCompleted: { - users.append({name: kscreenlocker_userName, - realName: kscreenlocker_userName, - icon: kscreenlocker_userImage, + x: parent.x + y: parent.y + width: parent.width + height: parent.height - }) - } - } + Component.onCompleted: PropertyAnimation { id: launchAnimation; target: lockScreenRoot; property: "opacity"; from: 0; to: 1; duration: 1000 } - StackView { - id: mainStack - anchors.fill: parent - focus: true //StackView is an implicit focus scope, so we need to give this focus so the item inside will have it - initialItem: MainBlock { - userListModel: users - notificationMessage: { - var text = "" - if (keystateSource.data["Caps Lock"]["Locked"]) { - text += i18nd("plasma_lookandfeel_org.kde.lookandfeel","Caps Lock is on") - if (root.notification) { - text += " • " + states: [ + State { + name: "onOtherSession" + // for slide out animation + PropertyChanges { target: lockScreenRoot; y: lockScreenRoot.height } + // we also change the opacity just to be sure it's not visible even on unexpected screen dimension changes with possible race conditions + PropertyChanges { target: lockScreenRoot; opacity: 0 } + } + ] + + transitions: + Transition { + // we only animate switchting to another session, because kscreenlocker doesn't get notified when + // coming from another session back and so we wouldn't know when to trigger the animation exactly + from: "" + to: "onOtherSession" + + PropertyAnimation { id: stateChangeAnimation; properties: "y"; duration: 300; easing: Easing.InQuad} + PropertyAnimation { properties: "opacity"; duration: 300} + + onRunningChanged: { + // after the animation has finished switch session: since we only animate the transition TO state "onOtherSession" + // and not the other way around, we don't have to check the state we transitioned into + if (/* lockScreenRoot.state == "onOtherSession" && */ !running) { + mainStack.currentItem.switchSession() } } - text += root.notification - return text } - onLoginRequest: { - root.notification = "" - authenticator.tryUnlock(password) + Clock { + anchors.bottom: parent.verticalCenter + anchors.bottomMargin: units.gridUnit * 13 + anchors.horizontalCenter: parent.horizontalCenter + } + + ListModel { + id: users + + Component.onCompleted: { + users.append({name: kscreenlocker_userName, + realName: kscreenlocker_userName, + icon: kscreenlocker_userImage, + + }) } + } + + StackView { + id: mainStack + anchors.fill: parent + focus: true //StackView is an implicit focus scope, so we need to give this focus so the item inside will have it + + initialItem: MainBlock { + id: mainBlock - actionItems: [ - ActionButton { - text: i18nd("org.kde.plasma_lookandfeel_org.kde.lookandfeel", "Switch User") - iconSource: "system-switch-user" - onClicked: mainStack.push(switchSessionPage) - visible: sessionsModel.canSwitchUser + Stack.onStatusChanged: { + // prepare for presenting again to the user + if (Stack.status == Stack.Activating) { + mainPasswordBox.remove(0, mainPasswordBox.length) + mainPasswordBox.focus = true + } + } + userListModel: users + notificationMessage: { + var text = "" + if (keystateSource.data["Caps Lock"]["Locked"]) { + text += i18nd("plasma_lookandfeel_org.kde.lookandfeel","Caps Lock is on") + if (root.notification) { + text += " • " + } + } + text += root.notification + return text } - ] + + onLoginRequest: { + root.notification = "" + authenticator.tryUnlock(password) + } + + actionItems: [ + ActionButton { + text: i18nd("org.kde.plasma_lookandfeel_org.kde.lookandfeel", "Switch User") + iconSource: "system-switch-user" + onClicked: mainStack.push(switchSessionPage) + visible: sessionsModel.canSwitchUser + } + ] + } } - } - Component { - id: switchSessionPage - SessionManagementScreen { - userListModel: sessionsModel + Component { + id: switchSessionPage + SessionManagementScreen { + property var switchSession: finalSwitchSession - PlasmaComponents.Button { - Layout.fillWidth: true - text: userListCurrentIndex == sessionsModel.count - 1 ? i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Start New Session") : i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Switch Session") - onClicked: { + Stack.onStatusChanged: { + if (Stack.status == Stack.Activating) { + focus = true + } + } + + userListModel: sessionsModel + + // initiating animation of lockscreen for session switch + function initSwitchSession() { + lockScreenRoot.state = 'onOtherSession' + } + + // initiating session switch and preparing lockscreen for possible return of user + function finalSwitchSession() { + mainStack.pop({immediate:true}) sessionsModel.switchUser(userListCurrentModelData.vtNumber) - mainStack.pop() + lockScreenRoot.state = '' } - } - actionItems: [ - ActionButton { - iconSource: "go-previous" - text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Back") - onClicked: mainStack.pop() + Keys.onLeftPressed: userList.decrementCurrentIndex() + Keys.onRightPressed: userList.incrementCurrentIndex() + Keys.onEnterPressed: initSwitchSession() + Keys.onReturnPressed: initSwitchSession() + Keys.onEscapePressed: mainStack.pop() + + PlasmaComponents.Button { + Layout.fillWidth: true + text: userListCurrentIndex == sessionsModel.count - 1 ? i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Start New Session") : i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Switch Session") + onClicked: initSwitchSession() } - ] - } - } - Loader { - active: root.viewVisible - source: "LockOsd.qml" - anchors { - horizontalCenter: parent.horizontalCenter - bottom: parent.bottom + actionItems: [ + ActionButton { + iconSource: "go-previous" + text: i18nd("plasma_lookandfeel_org.kde.lookandfeel","Back") + onClicked: mainStack.pop() + } + ] + } } - } - RowLayout { - id: footer - anchors { - bottom: parent.bottom - left: parent.left - right: parent.right - margins: units.smallSpacing + Loader { + active: root.viewVisible + source: "LockOsd.qml" + anchors { + horizontalCenter: parent.horizontalCenter + bottom: parent.bottom + } } - KeyboardLayoutButton { - } + RowLayout { + id: footer + anchors { + bottom: parent.bottom + left: parent.left + right: parent.right + margins: units.smallSpacing + } - Item { - Layout.fillWidth: true - } + KeyboardLayoutButton { + } - Battery {} - } + Item { + Layout.fillWidth: true + } + Battery {} + } + } Component.onCompleted: { // version support checks diff --git a/lookandfeel/contents/lockscreen/MainBlock.qml b/lookandfeel/contents/lockscreen/MainBlock.qml --- a/lookandfeel/contents/lockscreen/MainBlock.qml +++ b/lookandfeel/contents/lockscreen/MainBlock.qml @@ -28,6 +28,8 @@ import "../components" SessionManagementScreen { + + property Item mainPasswordBox: passwordBox /* * Login has been requested with the following username and password * If username field is visible, it will be taken from that, otherwise from the "name" property of the currentIndex