diff --git a/shell/contents/lockscreen/LockScreen.qml b/shell/contents/lockscreen/LockScreen.qml index 66300249..aed6a40c 100644 --- a/shell/contents/lockscreen/LockScreen.qml +++ b/shell/contents/lockscreen/LockScreen.qml @@ -9,7 +9,7 @@ import QtQuick.Layouts import org.kde.plasma.core as PlasmaCore import org.kde.notificationmanager as Notifications import org.kde.plasma.private.mobileshell.dpmsplugin as DPMS - +import org.kde.plasma.components 3.0 as PC3 import org.kde.kirigami 2.12 as Kirigami @@ -28,30 +28,38 @@ Item { readonly property bool isWidescreen: root.height < 720 && (root.height < root.width * 0.75) property bool notificationsShown: false - property var passwordBar: keypad.passwordBar + property var passwordBar: flickableLoader.item ? flickableLoader.item.passwordBar : null Component.onCompleted: { forceActiveFocus(); - - // Go to closed position when loaded - flickable.position = 0; - flickable.goToClosePosition(); } // Listen for keyboard events, and focus on input area Keys.onPressed: { - root.lockScreenState.isKeyboardMode = true; - flickable.goToOpenPosition(); - passwordBar.textField.forceActiveFocus(); + if (flickableLoader.item) { + root.lockScreenState.isKeyboardMode = true; + flickableLoader.item.goToOpenPosition(); + passwordBar.textField.forceActiveFocus(); + } } // Wallpaper blur Loader { + id: wallpaperLoader anchors.fill: parent + active: false asynchronous: true + + // This take a while to load, don't pause initial lockscreen loading for it + Timer { + running: true + repeat: false + onTriggered: wallpaperLoader.active = true + } + sourceComponent: WallpaperBlur { source: wallpaper - opacity: flickable.openFactor + opacity: flickableLoader.item ? flickableLoader.item.openFactor : 0 } } @@ -60,8 +68,8 @@ Item { // Ensure keypad is opened when password is updated (ex. keyboard) function onPasswordChanged() { - if (root.lockScreenState.password !== "") { - flickable.goToOpenPosition(); + if (root.lockScreenState.password !== "" && flickableLoader.item) { + flickableLoader.item.goToOpenPosition(); } } } @@ -72,7 +80,9 @@ Item { onDpmsTurnedOff: (screen) => { if (screen.name === Screen.name) { - flickable.goToClosePosition(); + if (flickableLoader.item) { + flickableLoader.item.goToClosePosition(); + } lockScreenState.resetPassword(); } } @@ -88,102 +98,147 @@ Item { z: 1 anchors.fill: parent statusBarHeight: Kirigami.Units.gridUnit * 1.25 - openFactor: flickable.openFactor + openFactor: flickableLoader.item ? flickableLoader.item.openFactor : 0 notificationsModel: root.notifModel onPasswordRequested: root.askPassword() } - FlickContainer { - id: flickable + // Add loading indicator when status bar has not loaded yet + PC3.BusyIndicator { + id: flickableLoadingBusyIndicator + anchors.centerIn: parent + visible: flickableLoader.status != Loader.Ready + + implicitHeight: Kirigami.Units.iconSizes.huge + implicitWidth: Kirigami.Units.iconSizes.huge + + Kirigami.Theme.inherit: false + Kirigami.Theme.colorSet: Kirigami.Theme.Complementary + } + + // Load flickable async + Loader { + id: flickableLoader + + active: false + asynchronous: true + opacity: status == Loader.Ready ? 1 : 0 + visible: opacity > 0 anchors.fill: parent - // Speed up animation when passwordless - animationDuration: root.lockScreenState.canBeUnlocked ? 400 : 800 + Behavior on opacity { + NumberAnimation {} + } - // Distance to swipe to fully open keypad - keypadHeight: Kirigami.Units.gridUnit * 20 - - // Unlock lockscreen if it's already unlocked and keypad is opened - onOpened: { - if (root.lockScreenState.canBeUnlocked) { - Qt.quit(); + // This take a while to load, don't pause initial lockscreen and wallpaper loading for it + Timer { + id: loadTimer + running: true + repeat: false + onTriggered: { + flickableLoader.active = true } } - // Unlock lockscreen if it's already unlocked and keypad is open - Connections { - target: root.lockScreenState - function onCanBeUnlockedChanged() { - if (root.lockScreenState.canBeUnlocked && flickable.openFactor > 0.8) { + // Container for lockscreen contents + sourceComponent: FlickContainer { + id: flickable + property alias passwordBar: keypad.passwordBar + + // Speed up animation when passwordless + animationDuration: root.lockScreenState.canBeUnlocked ? 400 : 800 + + // Distance to swipe to fully open keypad + keypadHeight: Kirigami.Units.gridUnit * 20 + + Component.onCompleted: { + // Go to closed position when loaded + flickable.position = 0; + flickable.goToClosePosition(); + } + + // Unlock lockscreen if it's already unlocked and keypad is opened + onOpened: { + if (root.lockScreenState.canBeUnlocked) { Qt.quit(); } } - } - // Clear entered password after closing keypad - onOpenFactorChanged: { - if (flickable.openFactor < 0.1) { - root.passwordBar.clear(); - } - } - - LockScreenContent { - id: lockScreenContent - - isVertical: !root.isWidescreen - opacity: Math.max(0, 1 - flickable.openFactor * 2) - transform: [ - Scale { - origin.x: lockScreenContent.width / 2 - origin.y: lockScreenContent.height / 2 - yScale: 1 - (flickable.openFactor * 2) * 0.1 - xScale: 1 - (flickable.openFactor * 2) * 0.1 + // Unlock lockscreen if it's already unlocked and keypad is open + Connections { + target: root.lockScreenState + function onCanBeUnlockedChanged() { + if (root.lockScreenState.canBeUnlocked && flickable.openFactor > 0.8) { + Qt.quit(); + } } - ] + } - fullHeight: root.height + // Clear entered password after closing keypad + onOpenFactorChanged: { + if (flickable.openFactor < 0.1) { + root.passwordBar.clear(); + } + } - lockScreenState: root.lockScreenState - notificationsModel: root.notifModel - onNotificationsShownChanged: root.notificationsShown = notificationsShown - onPasswordRequested: flickable.goToOpenPosition() + LockScreenContent { + id: lockScreenContent - anchors.topMargin: headerBar.statusBarHeight - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - } + isVertical: !root.isWidescreen + opacity: Math.max(0, 1 - flickable.openFactor * 2) + transform: [ + Scale { + origin.x: lockScreenContent.width / 2 + origin.y: lockScreenContent.height / 2 + yScale: 1 - (flickable.openFactor * 2) * 0.1 + xScale: 1 - (flickable.openFactor * 2) * 0.1 + } + ] - // scroll up icon - BottomIconIndicator { - id: scrollUpIconLoader - lockScreenState: root.lockScreenState - opacity: Math.max(0, 1 - flickable.openFactor * 2) + fullHeight: root.height - anchors.bottom: parent.bottom - anchors.bottomMargin: Kirigami.Units.gridUnit + flickable.position * 0.1 - anchors.horizontalCenter: parent.horizontalCenter - } + lockScreenState: root.lockScreenState + notificationsModel: root.notifModel + onNotificationsShownChanged: root.notificationsShown = notificationsShown + onPasswordRequested: flickable.goToOpenPosition() - Rectangle { - id: keypadScrim - anchors.fill: parent - visible: opacity > 0 - opacity: flickable.openFactor - color: Qt.rgba(0, 0, 0, 0.5) - } + anchors.topMargin: headerBar.statusBarHeight + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + } - Keypad { - id: keypad - visible: !root.lockScreenState.canBeUnlocked // don't show for passwordless login - anchors.fill: parent - openProgress: flickable.openFactor - lockScreenState: root.lockScreenState + // scroll up icon + BottomIconIndicator { + id: scrollUpIconLoader + lockScreenState: root.lockScreenState + opacity: Math.max(0, 1 - flickable.openFactor * 2) - // only show in last 50% of anim - opacity: (flickable.openFactor - 0.5) * 2 - transform: Translate { y: (flickable.keypadHeight - flickable.position) * 0.1 } + anchors.bottom: parent.bottom + anchors.bottomMargin: Kirigami.Units.gridUnit + flickable.position * 0.1 + anchors.horizontalCenter: parent.horizontalCenter + } + + Rectangle { + id: keypadScrim + anchors.fill: parent + visible: opacity > 0 + opacity: flickable.openFactor + color: Qt.rgba(0, 0, 0, 0.5) + } + + Keypad { + id: keypad + visible: !root.lockScreenState.canBeUnlocked // don't show for passwordless login + anchors.fill: parent + openProgress: flickable.openFactor + lockScreenState: root.lockScreenState + + // only show in last 50% of anim + opacity: (flickable.openFactor - 0.5) * 2 + transform: Translate { y: (flickable.keypadHeight - flickable.position) * 0.1 } + } } } } diff --git a/shell/contents/lockscreen/PasswordBar.qml b/shell/contents/lockscreen/PasswordBar.qml index 300258e0..ea0052a9 100644 --- a/shell/contents/lockscreen/PasswordBar.qml +++ b/shell/contents/lockscreen/PasswordBar.qml @@ -25,7 +25,7 @@ Rectangle { readonly property color headerTextInactiveColor: Qt.rgba(255, 255, 255, 0.4) radius: Kirigami.Units.largeSpacing - color: Qt.rgba(255, 255, 255, 0.3) + color: Qt.rgba(255, 255, 255, 0.2) // model for shown dots // we need to use a listmodel to avoid all delegates from reloading @@ -164,6 +164,8 @@ Rectangle { // toggle between showing keypad and not ToolButton { id: keyboardToggle + Kirigami.Theme.inherit: false + Kirigami.Theme.colorSet: Kirigami.Theme.Complementary anchors.right: parent.right anchors.top: parent.top @@ -175,6 +177,7 @@ Rectangle { implicitWidth: height icon.name: root.lockScreenState.isKeyboardMode ? "input-dialpad-symbolic" : "input-keyboard-virtual-symbolic" + icon.color: 'white' onClicked: { root.lockScreenState.isKeyboardMode = !root.lockScreenState.isKeyboardMode; if (root.lockScreenState.isKeyboardMode) {