mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
lockscreen: Async load everything and add spinner
This improves the speed initial lockscreen load, and now loads the keypad async. Also adjust the password bar opacity to be consistent with the keys.
This commit is contained in:
parent
d60fea6bdf
commit
dea468b393
2 changed files with 145 additions and 87 deletions
|
|
@ -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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue