File: LockScreen.qml

package info (click to toggle)
plasma-mobile 6.5.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 20,412 kB
  • sloc: xml: 38,474; cpp: 18,529; javascript: 139; sh: 82; makefile: 5
file content (220 lines) | stat: -rw-r--r-- 7,116 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
// SPDX-FileCopyrightText: 2019 Nicolas Fella <nicolas.fella@gmx.de>
// SPDX-FileCopyrightText: 2021-2024 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

import org.kde.plasma.core as PlasmaCore
import org.kde.notificationmanager as Notifications
import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.plasma.private.mobileshell.state as MobileShellState
import org.kde.plasma.private.mobileshell.dpmsplugin as DPMS
import org.kde.plasma.components 3.0 as PC3
import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings

import org.kde.kirigami 2.12 as Kirigami

/**
 * Lockscreen component that is loaded after the device is locked.
 *
 * Special attention must be paid to ensuring the GUI loads as fast as possible.
 */
Item {
    id: root

    readonly property var lockScreenState: LockScreenState {}
    readonly property var notifModel: Notifications.WatchedNotificationsModel {}

    // Only show widescreen mode for short height devices (ex. phone landscape)
    readonly property bool isWidescreen: root.height < Kirigami.Units.gridUnit * 25 && (root.height < root.width * 0.75)
    property bool notificationsShown: false

    property var passwordBar: flickable.passwordBar

    Component.onCompleted: {
        forceActiveFocus();
    }

    // Listen for keyboard events, and focus on input area
    Keys.onPressed: (event) => {
        root.lockScreenState.isKeyboardMode = true;
        flickable.goToOpenPosition();
        passwordBar.textField.forceActiveFocus();

        passwordBar.keyPress(event.text);
    }

    Connections {
        target: MobileShellState.ShellDBusClient

        function onOpenLockScreenKeypadRequested() {
            flickable.goToOpenPosition();
        }
    }

    // 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
        }
    }

    Connections {
        target: root.lockScreenState

        // Ensure keypad is opened when password is updated (ex. keyboard)
        function onPasswordChanged() {
            if (root.lockScreenState.password !== "") {
                flickable.goToOpenPosition();
            }
        }
    }

    // when screen turns off, reset state
    DPMS.DPMSUtil {
        id: dpms

        onDpmsTurnedOff: (screen) => {
            if (screen.name === Screen.name) {
                flickable.goToClosePosition();
                lockScreenState.resetPassword();
            }
        }
    }

    // Container for lockscreen contents
    Item {
        id: lockscreenContainer
        anchors.fill: parent

        FlickContainer {
            id: flickable
            anchors.fill: parent
            property alias passwordBar: keypad.passwordBar

            // Speed up animation when passwordless
            animationDuration: Kirigami.Units.veryLongDuration

            // 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();
                }
            }

            // 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();
                    }
                }
            }

            // Clear entered password after closing keypad
            onOpenFactorChanged: {
                if (flickable.openFactor < 0.1 && !flickable.movingUp) {
                    root.passwordBar.clear();
                }
            }

            // scroll up icon
            BottomIconIndicator {
                id: scrollUpIconLoader
                lockScreenState: root.lockScreenState
                opacity: Math.max(0, 1 - flickable.openFactor * 2)

                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)
            }

            MouseArea {
                // Disable "double tap to lock" to avoid accidental locking
                // when the keypad is open, and the user is typing their password.
                enabled: flickable.openFactor < 0.1
                anchors.fill: parent

                onDoubleClicked: (mouse) => {
                    if (ShellSettings.KWinSettings.doubleTapWakeup) {
                        deviceLock.triggerLock();
                    }
                }

                MobileShell.DeviceLock {
                    id: deviceLock
                }
            }

            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 }
            }
        }

        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
                }
            ]

            lockScreenState: root.lockScreenState
            notificationsModel: root.notifModel
            onNotificationsShownChanged: root.notificationsShown = notificationsShown
            onPasswordRequested: flickable.goToOpenPosition()

            scrollLock: flickable.openFactor > 0.2
            z: scrollLock ? -1 : 0

            anchors.fill: parent
        }
    }
}