2023-05-13 15:15:52 +00:00
|
|
|
// SPDX-FileCopyrightText: 2019 Nicolas Fella <nicolas.fella@gmx.de>
|
2024-06-26 02:57:42 +00:00
|
|
|
// SPDX-FileCopyrightText: 2021-2024 Devin Lin <devin@kde.org>
|
2023-05-13 15:15:52 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2014-08-20 10:10:58 +00:00
|
|
|
|
2023-05-13 15:15:52 +00:00
|
|
|
import QtQuick
|
|
|
|
|
import QtQuick.Controls
|
|
|
|
|
import QtQuick.Layouts
|
2021-12-22 23:29:00 +00:00
|
|
|
|
2023-09-05 15:34:49 +00:00
|
|
|
import org.kde.plasma.core as PlasmaCore
|
2023-10-20 20:01:56 +00:00
|
|
|
import org.kde.notificationmanager as Notifications
|
2024-04-04 18:56:30 +00:00
|
|
|
import org.kde.plasma.private.mobileshell.dpmsplugin as DPMS
|
2024-07-23 02:22:54 +00:00
|
|
|
import org.kde.plasma.components 3.0 as PC3
|
2021-12-22 23:29:00 +00:00
|
|
|
|
2022-05-21 03:41:11 +00:00
|
|
|
import org.kde.kirigami 2.12 as Kirigami
|
|
|
|
|
|
2022-04-10 17:44:37 +00:00
|
|
|
/**
|
|
|
|
|
* Lockscreen component that is loaded after the device is locked.
|
2022-12-09 15:54:02 +00:00
|
|
|
*
|
2022-04-10 17:44:37 +00:00
|
|
|
* Special attention must be paid to ensuring the GUI loads as fast as possible.
|
|
|
|
|
*/
|
2022-12-09 15:54:02 +00:00
|
|
|
Item {
|
2020-02-01 14:21:24 +00:00
|
|
|
id: root
|
|
|
|
|
|
2024-06-26 02:57:42 +00:00
|
|
|
readonly property var lockScreenState: LockScreenState {}
|
|
|
|
|
readonly property var notifModel: Notifications.WatchedNotificationsModel {}
|
2022-12-09 15:54:02 +00:00
|
|
|
|
2024-06-26 02:57:42 +00:00
|
|
|
// Only show widescreen mode for short height devices (ex. phone landscape)
|
|
|
|
|
readonly property bool isWidescreen: root.height < 720 && (root.height < root.width * 0.75)
|
2021-05-05 19:48:06 +00:00
|
|
|
property bool notificationsShown: false
|
2022-12-09 15:54:02 +00:00
|
|
|
|
2024-07-23 02:22:54 +00:00
|
|
|
property var passwordBar: flickableLoader.item ? flickableLoader.item.passwordBar : null
|
2022-12-09 15:54:02 +00:00
|
|
|
|
2024-06-26 02:57:42 +00:00
|
|
|
Component.onCompleted: {
|
|
|
|
|
forceActiveFocus();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Listen for keyboard events, and focus on input area
|
2022-06-24 03:35:54 +00:00
|
|
|
Keys.onPressed: {
|
2024-07-23 02:22:54 +00:00
|
|
|
if (flickableLoader.item) {
|
|
|
|
|
root.lockScreenState.isKeyboardMode = true;
|
|
|
|
|
flickableLoader.item.goToOpenPosition();
|
|
|
|
|
passwordBar.textField.forceActiveFocus();
|
|
|
|
|
}
|
2022-06-24 03:35:54 +00:00
|
|
|
}
|
2022-12-09 15:54:02 +00:00
|
|
|
|
2024-06-26 02:57:42 +00:00
|
|
|
// Wallpaper blur
|
2022-02-17 05:52:34 +00:00
|
|
|
Loader {
|
2024-07-23 02:22:54 +00:00
|
|
|
id: wallpaperLoader
|
2020-02-01 14:21:24 +00:00
|
|
|
anchors.fill: parent
|
2024-07-23 02:22:54 +00:00
|
|
|
active: false
|
2022-02-17 05:52:34 +00:00
|
|
|
asynchronous: true
|
2024-07-23 02:22:54 +00:00
|
|
|
|
|
|
|
|
// This take a while to load, don't pause initial lockscreen loading for it
|
|
|
|
|
Timer {
|
|
|
|
|
running: true
|
|
|
|
|
repeat: false
|
|
|
|
|
onTriggered: wallpaperLoader.active = true
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-17 05:52:34 +00:00
|
|
|
sourceComponent: WallpaperBlur {
|
|
|
|
|
source: wallpaper
|
2024-07-23 02:22:54 +00:00
|
|
|
opacity: flickableLoader.item ? flickableLoader.item.openFactor : 0
|
2020-08-31 01:38:46 +00:00
|
|
|
}
|
|
|
|
|
}
|
2022-12-09 15:54:02 +00:00
|
|
|
|
2022-05-21 03:41:11 +00:00
|
|
|
Connections {
|
|
|
|
|
target: root.lockScreenState
|
2022-12-09 15:54:02 +00:00
|
|
|
|
2024-06-26 02:57:42 +00:00
|
|
|
// Ensure keypad is opened when password is updated (ex. keyboard)
|
2022-05-21 03:41:11 +00:00
|
|
|
function onPasswordChanged() {
|
2024-07-23 02:22:54 +00:00
|
|
|
if (root.lockScreenState.password !== "" && flickableLoader.item) {
|
|
|
|
|
flickableLoader.item.goToOpenPosition();
|
2024-06-26 02:57:42 +00:00
|
|
|
}
|
2022-05-21 03:41:11 +00:00
|
|
|
}
|
|
|
|
|
}
|
2021-05-05 19:48:06 +00:00
|
|
|
|
2024-04-04 18:56:30 +00:00
|
|
|
// when screen turns off, reset state
|
|
|
|
|
DPMS.DPMSUtil {
|
|
|
|
|
id: dpms
|
|
|
|
|
|
|
|
|
|
onDpmsTurnedOff: (screen) => {
|
|
|
|
|
if (screen.name === Screen.name) {
|
2024-07-23 02:22:54 +00:00
|
|
|
if (flickableLoader.item) {
|
|
|
|
|
flickableLoader.item.goToClosePosition();
|
|
|
|
|
}
|
2024-04-04 18:56:30 +00:00
|
|
|
lockScreenState.resetPassword();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-25 01:13:52 +00:00
|
|
|
Item {
|
2024-06-26 02:57:42 +00:00
|
|
|
id: lockscreenContainer
|
2022-02-12 05:19:44 +00:00
|
|
|
anchors.fill: parent
|
2022-12-09 15:54:02 +00:00
|
|
|
|
2024-06-26 02:57:42 +00:00
|
|
|
// Header bar and action drawer
|
2024-06-28 15:04:32 +00:00
|
|
|
HeaderComponent {
|
|
|
|
|
id: headerBar
|
|
|
|
|
z: 1
|
2022-12-09 15:54:02 +00:00
|
|
|
anchors.fill: parent
|
2024-06-28 15:04:32 +00:00
|
|
|
statusBarHeight: Kirigami.Units.gridUnit * 1.25
|
2024-07-23 02:22:54 +00:00
|
|
|
openFactor: flickableLoader.item ? flickableLoader.item.openFactor : 0
|
2024-06-28 15:04:32 +00:00
|
|
|
notificationsModel: root.notifModel
|
|
|
|
|
onPasswordRequested: root.askPassword()
|
2022-06-18 20:47:41 +00:00
|
|
|
}
|
2022-12-09 15:54:02 +00:00
|
|
|
|
2024-07-23 02:22:54 +00:00
|
|
|
// Add loading indicator when status bar has not loaded yet
|
|
|
|
|
PC3.BusyIndicator {
|
|
|
|
|
id: flickableLoadingBusyIndicator
|
|
|
|
|
anchors.centerIn: parent
|
|
|
|
|
visible: flickableLoader.status != Loader.Ready
|
2022-12-09 15:54:02 +00:00
|
|
|
|
2024-07-23 02:22:54 +00:00
|
|
|
implicitHeight: Kirigami.Units.iconSizes.huge
|
|
|
|
|
implicitWidth: Kirigami.Units.iconSizes.huge
|
2024-07-03 02:10:29 +00:00
|
|
|
|
2024-07-23 02:22:54 +00:00
|
|
|
Kirigami.Theme.inherit: false
|
|
|
|
|
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
|
|
|
|
|
}
|
2022-12-09 15:54:02 +00:00
|
|
|
|
2024-07-23 02:22:54 +00:00
|
|
|
// Load flickable async
|
|
|
|
|
Loader {
|
|
|
|
|
id: flickableLoader
|
|
|
|
|
|
|
|
|
|
active: false
|
|
|
|
|
asynchronous: true
|
|
|
|
|
opacity: status == Loader.Ready ? 1 : 0
|
|
|
|
|
visible: opacity > 0
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
|
|
|
|
|
Behavior on opacity {
|
|
|
|
|
NumberAnimation {}
|
2024-07-03 02:10:29 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-23 02:22:54 +00:00
|
|
|
// 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
|
2024-07-08 01:54:14 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-23 02:22:54 +00:00
|
|
|
// 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();
|
2022-12-09 15:54:02 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-23 02:22:54 +00:00
|
|
|
// Unlock lockscreen if it's already unlocked and keypad is opened
|
|
|
|
|
onOpened: {
|
|
|
|
|
if (root.lockScreenState.canBeUnlocked) {
|
|
|
|
|
Qt.quit();
|
2024-06-26 02:57:42 +00:00
|
|
|
}
|
2024-07-23 02:22:54 +00:00
|
|
|
}
|
2022-12-09 15:54:02 +00:00
|
|
|
|
2024-07-23 02:22:54 +00:00
|
|
|
// 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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-12-09 15:54:02 +00:00
|
|
|
|
2024-07-23 02:22:54 +00:00
|
|
|
// Clear entered password after closing keypad
|
|
|
|
|
onOpenFactorChanged: {
|
|
|
|
|
if (flickable.openFactor < 0.1) {
|
|
|
|
|
root.passwordBar.clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-12-09 15:54:02 +00:00
|
|
|
|
2024-07-23 02:22:54 +00:00
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
fullHeight: root.height
|
|
|
|
|
|
|
|
|
|
lockScreenState: root.lockScreenState
|
|
|
|
|
notificationsModel: root.notifModel
|
|
|
|
|
onNotificationsShownChanged: root.notificationsShown = notificationsShown
|
|
|
|
|
onPasswordRequested: flickable.goToOpenPosition()
|
|
|
|
|
|
|
|
|
|
anchors.topMargin: headerBar.statusBarHeight
|
|
|
|
|
anchors.top: parent.top
|
|
|
|
|
anchors.bottom: parent.bottom
|
|
|
|
|
anchors.left: parent.left
|
|
|
|
|
anchors.right: parent.right
|
|
|
|
|
}
|
2022-12-09 15:54:02 +00:00
|
|
|
|
2024-07-23 02:22:54 +00:00
|
|
|
// scroll up icon
|
|
|
|
|
BottomIconIndicator {
|
|
|
|
|
id: scrollUpIconLoader
|
|
|
|
|
lockScreenState: root.lockScreenState
|
|
|
|
|
opacity: Math.max(0, 1 - flickable.openFactor * 2)
|
2023-10-23 06:42:38 +00:00
|
|
|
|
2024-07-23 02:22:54 +00:00
|
|
|
anchors.bottom: parent.bottom
|
|
|
|
|
anchors.bottomMargin: Kirigami.Units.gridUnit + flickable.position * 0.1
|
|
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
|
|
}
|
2022-12-09 15:54:02 +00:00
|
|
|
|
2024-07-23 02:22:54 +00:00
|
|
|
Rectangle {
|
|
|
|
|
id: keypadScrim
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
visible: opacity > 0
|
|
|
|
|
opacity: flickable.openFactor
|
|
|
|
|
color: Qt.rgba(0, 0, 0, 0.5)
|
|
|
|
|
}
|
2022-12-09 15:54:02 +00:00
|
|
|
|
2024-07-23 02:22:54 +00:00
|
|
|
Keypad {
|
|
|
|
|
id: keypad
|
|
|
|
|
visible: !root.lockScreenState.canBeUnlocked // don't show for passwordless login
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
openProgress: flickable.openFactor
|
|
|
|
|
lockScreenState: root.lockScreenState
|
2022-12-09 15:54:02 +00:00
|
|
|
|
2024-07-23 02:22:54 +00:00
|
|
|
// only show in last 50% of anim
|
|
|
|
|
opacity: (flickable.openFactor - 0.5) * 2
|
|
|
|
|
transform: Translate { y: (flickable.keypadHeight - flickable.position) * 0.1 }
|
|
|
|
|
}
|
2019-10-31 06:20:36 +00:00
|
|
|
}
|
2014-08-28 13:21:53 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|