Commit d2646417 authored by Devin Lin's avatar Devin Lin 🎨
Browse files

lockscreen: Refactor and use loaders to speed up lockscreen load time

parent 2fa24cd0
Pipeline #138867 passed with stages
in 1 minute and 22 seconds
/*
SPDX-FileCopyrightText: 2019 Nicolas Fella <nicolas.fella@gmx.de>
SPDX-License-Identifier: GPL-2.0-or-later
* SPDX-FileCopyrightText: 2019 Nicolas Fella <nicolas.fella@gmx.de>
* SPDX-License-Identifier: GPL-2.0-or-later
*/
import QtQuick 2.8
......@@ -12,10 +11,13 @@ import QtGraphicalEffects 1.12
import org.kde.plasma.core 2.0
ColumnLayout {
id: root
property int layoutAlignment
readonly property bool softwareRendering: GraphicsInfo.api === GraphicsInfo.Software
readonly property bool is24HourTime: Qt.locale().timeFormat(Locale.ShortFormat).toLowerCase().indexOf("ap") === -1
property int alignment
Layout.alignment: alignment
Layout.alignment: layoutAlignment
spacing: Units.gridUnit
Label {
......@@ -24,7 +26,7 @@ ColumnLayout {
style: softwareRendering ? Text.Outline : Text.Normal
styleColor: softwareRendering ? ColorScope.backgroundColor : "transparent" // no outline, doesn't matter
Layout.alignment: alignment
Layout.alignment: root.layoutAlignment
font.weight: Font.Light // this font weight may switch to regular on distros that don't have a light variant
font.pointSize: 36
layer.enabled: true
......@@ -35,13 +37,14 @@ ColumnLayout {
color: "#757575"
}
}
Label {
text: Qt.formatDate(timeSource.data["Local"]["DateTime"], "ddd, MMM d")
color: ColorScope.textColor
style: softwareRendering ? Text.Outline : Text.Normal
styleColor: softwareRendering ? ColorScope.backgroundColor : "transparent" // no outline, doesn't matter
Layout.alignment: alignment
Layout.alignment: root.layoutAlignment
font.pointSize: 10
layer.enabled: true
layer.effect: DropShadow {
......@@ -51,6 +54,7 @@ ColumnLayout {
color: "#757575"
}
}
DataSource {
id: timeSource
engine: "time"
......
......@@ -31,6 +31,9 @@ Flickable {
}
function updateState() {
// don't update state if at end
if (position <= 0 || position >= keypadHeight) return;
if (movingUp) {
goToOpenPosition();
} else {
......@@ -72,7 +75,7 @@ Flickable {
property real oldContentY
onContentYChanged: {
positionChangedDueToFlickable = true;
position += (contentY - oldContentY);
position = Math.max(0, Math.min(keypadHeight, position + (contentY - oldContentY)));
oldContentY = contentY;
}
......
/*
This file is part of the KDE project.
SPDX-FileCopyrightText: 2014 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
import QtQuick 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
PlasmaCore.FrameSvgItem {
id: osd
property alias timeout: osdItem.timeout
property alias osdValue: osdItem.osdValue
property alias osdMaxValue: osdItem.osdMaxValue
property alias icon: osdItem.icon
property alias showingProgress: osdItem.showingProgress
objectName: "onScreenDisplay"
visible: false
width: osdItem.width + margins.left + margins.right
height: osdItem.height + margins.top + margins.bottom
imagePath: "widgets/background"
function show() {
osd.visible = true;
hideAnimation.restart();
}
// avoid leaking ColorScope of lock screen theme into the OSD "popup"
PlasmaCore.ColorScope {
width: osdItem.width
height: osdItem.height
anchors.centerIn: parent
colorGroup: PlasmaCore.Theme.NormalColorGroup
OsdItem {
id: osdItem
}
}
SequentialAnimation {
id: hideAnimation
// prevent press and hold from flickering
PauseAnimation { duration: 100 }
NumberAnimation {
target: osd
property: "opacity"
from: 1
to: 0
duration: osd.timeout
easing.type: Easing.InQuad
}
ScriptAction {
script: {
osd.visible = false;
osd.opacity = 1;
osd.icon = "";
osd.osdValue = 0;
}
}
}
}
/*
* SPDX-FileCopyrightText: 2019 Nicolas Fella <nicolas.fella@gmx.de>
* SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com>
* SPDX-FileCopyrightText: 2021-2022 Devin Lin <espidev@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
......@@ -8,12 +8,9 @@
import QtQuick 2.12
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import QtGraphicalEffects 1.12
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.workspace.keyboardlayout 1.0
import org.kde.notificationmanager 1.1 as Notifications
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
PlasmaCore.ColorScope {
id: root
......@@ -22,42 +19,27 @@ PlasmaCore.ColorScope {
property bool isWidescreen: root.height < root.width * 0.75
property bool notificationsShown: false
property bool is24HourTime: Qt.locale().timeFormat(Locale.ShortFormat).toLowerCase().indexOf("ap") === -1
colorGroup: PlasmaCore.Theme.ComplementaryColorGroup
anchors.fill: parent
readonly property bool drawerOpen: flickable.openFactor >= 1
function isPinDrawerOpen() {
return flickable.openFactor >= 1;
}
function askPassword() {
flickable.goToOpenPosition();
}
colorGroup: PlasmaCore.Theme.ComplementaryColorGroup
anchors.fill: parent
Notifications.WatchedNotificationsModel {
id: notifModel
}
// blur background once keypad is open
FastBlur {
id: blur
cached: true
// wallpaper blur
Loader {
anchors.fill: parent
source: wallpaper
radius: 50
opacity: 0
property bool doBlur: notificationsShown || isPinDrawerOpen() // only blur once animation finished for performance
Behavior on doBlur {
NumberAnimation {
target: blur
property: "opacity"
duration: 1000
to: blur.doBlur ? 0 : 1
easing.type: Easing.InOutQuad
}
asynchronous: true
sourceComponent: WallpaperBlur {
source: wallpaper
blur: root.notificationsShown || root.drawerOpen // only blur once animation finished for performance
}
}
......@@ -67,7 +49,12 @@ PlasmaCore.ColorScope {
property real openFactor: position / keypadHeight
Component.onCompleted: flickable.goToClosePosition()
keypadHeight: PlasmaCore.Units.gridUnit * 20
Component.onCompleted: {
flickable.position = 0;
flickable.goToClosePosition();
}
onPositionChanged: {
if (position > keypadHeight) {
......@@ -77,171 +64,50 @@ PlasmaCore.ColorScope {
}
}
keypadHeight: PlasmaCore.Units.gridUnit * 20
Item {
width: flickable.width
height: flickable.height
y: flickable.contentY // effectively anchored to the screen
// header bar
Loader {
id: headerBar
asynchronous: true
anchors {
top: parent.top
left: parent.left
right: parent.right
}
height: PlasmaCore.Units.gridUnit * 1.25
StatusBarComponent {
id: statusBar
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
opacity: 1 - flickable.openFactor
sourceComponent: MobileShell.StatusBar {
id: statusBar
colorGroup: PlasmaCore.Theme.ComplementaryColorGroup
backgroundColor: "transparent"
showSecondRow: false
showDropShadow: true
showTime: false
disableSystemTray: true // HACK: prevent SIGABRT
}
}
// phone lockscreen component
Loader {
LockScreenNarrowContent {
id: phoneComponent
visible: !isWidescreen
active: visible
opacity: 1 - flickable.openFactor
asynchronous: true
anchors {
top: parent.top
bottom: scrollUpIcon.top
left: parent.left
right: parent.right
topMargin: item && !root.notificationsShown ? Math.round(root.height / 2 - (item.implicitHeight / 2 + PlasmaCore.Units.gridUnit * 2)) : PlasmaCore.Units.gridUnit * 5
bottomMargin: PlasmaCore.Units.gridUnit
}
Behavior on anchors.topMargin {
NumberAnimation {
duration: loadTimer.running ? 0 : PlasmaCore.Units.longDuration
easing.type: Easing.InOutQuad
}
}
fullHeight: root.height
// avoid topMargin animation when item is being loaded
onLoaded: loadTimer.restart();
Timer {
id: loadTimer
interval: PlasmaCore.Units.longDuration
}
anchors.top: parent.top
anchors.bottom: scrollUpIcon.top
anchors.left: parent.left
anchors.right: parent.right
// move while swiping up
transform: Translate { y: Math.round((1 - phoneComponent.opacity) * (-root.height / 6)) }
sourceComponent: ColumnLayout {
id: phoneClockComponent
spacing: 0
Clock {
id: phoneClock
alignment: Qt.AlignHCenter
Layout.bottomMargin: PlasmaCore.Units.gridUnit * 2 // keep spacing even if media controls are gone
}
MobileShell.MediaControlsWidget {
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
Layout.maximumWidth: PlasmaCore.Units.gridUnit * 25
Layout.leftMargin: PlasmaCore.Units.gridUnit
Layout.rightMargin: PlasmaCore.Units.gridUnit
}
NotificationsComponent {
Layout.fillHeight: true
Layout.fillWidth: true
Layout.maximumWidth: PlasmaCore.Units.gridUnit * (25 + 2) // clip margins
topMargin: PlasmaCore.Units.gridUnit
leftMargin: PlasmaCore.Units.gridUnit
rightMargin: PlasmaCore.Units.gridUnit
}
}
}
// tablet lockscreen component
Loader {
LockScreenWideScreenContent {
id: tabletComponent
visible: isWidescreen
active: visible
opacity: 1 - flickable.openFactor
asynchronous: true
anchors.top: headerBar.bottom
anchors.top: statusBar.bottom
anchors.bottom: scrollUpIcon.top
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: scrollUpIcon.top
// move while swiping up
transform: Translate { y: Math.round((1 - phoneComponent.opacity) * (-root.height / 6)) }
sourceComponent: Item {
Item {
id: tabletClockComponent
width: parent.width / 2
anchors {
top: parent.top
bottom: parent.bottom
left: parent.left
leftMargin: PlasmaCore.Units.gridUnit * 3
}
ColumnLayout {
id: tabletLayout
anchors.centerIn: parent
spacing: PlasmaCore.Units.gridUnit
Clock {
id: tabletClock
alignment: Qt.AlignLeft
Layout.fillWidth: true
Layout.minimumWidth: PlasmaCore.Units.gridUnit * 20
}
MobileShell.MediaControlsWidget {
Layout.alignment: Qt.AlignLeft
Layout.fillWidth: true
Layout.maximumWidth: PlasmaCore.Units.gridUnit * 25
}
}
}
// tablet notifications list
ColumnLayout {
id: tabletNotificationsList
anchors {
top: parent.top
bottom: parent.bottom
left: tabletClockComponent.right
right: parent.right
rightMargin: PlasmaCore.Units.gridUnit
}
NotificationsComponent {
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
Layout.fillWidth: true
Layout.fillHeight: true
Layout.topMargin: PlasmaCore.Units.gridUnit * 2
Layout.bottomMargin: PlasmaCore.Units.gridUnit
Layout.minimumWidth: PlasmaCore.Units.gridUnit * 15
Layout.maximumWidth: PlasmaCore.Units.gridUnit * 25
leftMargin: PlasmaCore.Units.gridUnit
rightMargin: PlasmaCore.Units.gridUnit
bottomMargin: PlasmaCore.Units.gridUnit
topMargin: PlasmaCore.Units.gridUnit
}
}
}
}
// scroll up icon
......@@ -279,20 +145,13 @@ PlasmaCore.ColorScope {
Keypad {
id: keypad
Layout.fillWidth: true
focus: true
swipeProgress: flickable.openFactor
Layout.fillWidth: true
onPasswordChanged: {
passwordFlickable.contentY = passwordFlickable.contentHeight - passwordFlickable.height
}
onPasswordChanged: flickable.goToOpenPosition()
}
}
}
}
LockOsd {
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: PlasmaCore.Units.largeSpacing
}
}
/*
* SPDX-FileCopyrightText: 2021-2022 Devin Lin <espidev@gmail.com>
* SPDX-License-Identifier: GPL-2.0-or-later
*/
import QtQuick 2.12
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.workspace.keyboardlayout 1.0
import org.kde.notificationmanager 1.1 as Notifications
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
Loader {
id: root
asynchronous: true
property real fullHeight
property bool notificationsShown: false
// avoid topMargin animation when item is being loaded
onLoaded: loadTimer.restart();
Timer {
id: loadTimer
interval: PlasmaCore.Units.longDuration
}
// move while swiping up
transform: Translate { y: Math.round((1 - phoneComponent.opacity) * (-root.height / 6)) }
sourceComponent: Item {
ColumnLayout {
id: column
spacing: 0
// center clock when no notifications are shown, otherwise move the clock upward
anchors.topMargin: !root.notificationsShown ? Math.round(root.fullHeight / 2 - (column.implicitHeight / 2)) : PlasmaCore.Units.gridUnit * 5
anchors.bottomMargin: PlasmaCore.Units.gridUnit
anchors.fill: parent
// animate
Behavior on anchors.topMargin {
NumberAnimation {
duration: loadTimer.running ? 0 : PlasmaCore.Units.longDuration
easing.type: Easing.InOutQuad
}
}
Clock {
layoutAlignment: Qt.AlignHCenter
Layout.bottomMargin: PlasmaCore.Units.gridUnit * 2 // keep spacing even if media controls are gone
}
MobileShell.MediaControlsWidget {
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
Layout.maximumWidth: PlasmaCore.Units.gridUnit * 25
Layout.leftMargin: PlasmaCore.Units.gridUnit
Layout.rightMargin: PlasmaCore.Units.gridUnit
}
NotificationsComponent {
id: notificationComponent
Layout.fillHeight: true
Layout.fillWidth: true
Layout.maximumWidth: PlasmaCore.Units.gridUnit * (25 + 2) // clip margins
topMargin: PlasmaCore.Units.gridUnit
leftMargin: PlasmaCore.Units.gridUnit
rightMargin: PlasmaCore.Units.gridUnit
onNotificationsShownChanged: root.notificationsShown = notificationsShown
}
}
}
}
/*
* SPDX-FileCopyrightText: 2021-2022 Devin Lin <espidev@gmail.com>
* SPDX-License-Identifier: GPL-2.0-or-later
*/
import QtQuick 2.12
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.workspace.keyboardlayout 1.0
import org.kde.notificationmanager 1.1 as Notifications
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
Loader {
id: tabletComponent
asynchronous: true
property bool notificationsShown: false
sourceComponent: Item {
Item {
id: tabletClockComponent
width: parent.width / 2
anchors {
top: parent.top
bottom: parent.bottom
left: parent.left
leftMargin: PlasmaCore.Units.gridUnit * 3
}
ColumnLayout {
id: tabletLayout
anchors.centerIn: parent
spacing: PlasmaCore.Units.gridUnit
Clock {
layoutAlignment: Qt.AlignLeft
Layout.fillWidth: true
Layout.minimumWidth: PlasmaCore.Units.gridUnit * 20
}
MobileShell.MediaControlsWidget {
Layout.alignment: Qt.AlignLeft
Layout.fillWidth: true
Layout.maximumWidth: PlasmaCore.Units.gridUnit * 25
}
}
}
// tablet notifications list
ColumnLayout {
id: tabletNotificationsList
anchors {
top: parent.top
bottom: parent.bottom
left: tabletClockComponent.right
right: parent.right
rightMargin: PlasmaCore.Units.gridUnit
}
NotificationsComponent {
id: notificationComponent
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
Layout.fillWidth: true
Layout.fillHeight: true
Layout.topMargin: PlasmaCore.Units.gridUnit * 2
Layout.bottomMargin: PlasmaCore.Units.gridUnit
Layout.minimumWidth: PlasmaCore.Units.gridUnit * 15
Layout.maximumWidth: PlasmaCore.Units.gridUnit * 25
leftMargin: PlasmaCore.Units.gridUnit
rightMargin: PlasmaCore.Units.gridUnit
bottomMargin: PlasmaCore.Units.gridUnit
topMargin: PlasmaCore.Units.gridUnit
onNotificationsShownChanged: root.notificationsShown = notificationsShown
}
}
}