Add lock screen appearance settings

This commit is contained in:
Gabriel Brown
2026-08-18 15:00:18 -04:00
parent 3520700983
commit a80a6f4dda
8 changed files with 358 additions and 1 deletions
@@ -75,6 +75,24 @@ SettingsPage {
}
}
SettingsCard {
title: "Lock screen"
subtitle: LockScreen.lastError !== ""
? LockScreen.lastError
: "A representative preview of the screen shown before authentication."
LockScreenPreview {
width: parent.width
}
ChoiceRow { setting: "lockBackgroundMode" }
SliderRow { setting: "lockBlurLevel"; zeroLabel: "Off" }
ToggleRow { setting: "lockShowClock" }
ToggleRow { setting: "lockShowDate" }
ToggleRow { setting: "lockShowUser" }
ToggleRow { setting: "lockFadeOnEmpty"; divider: false }
}
SettingsCard {
title: "Colour scheme"
subtitle: ColorScheme.lastError !== ""
@@ -0,0 +1,152 @@
import Quickshell
import QtQuick
import qs.config
import qs.services
Rectangle {
id: root
property string backgroundMode: DesktopPreferences.get("lockBackgroundMode")
property int blurLevel: DesktopPreferences.get("lockBlurLevel")
property bool showClock: DesktopPreferences.get("lockShowClock")
property bool showDate: DesktopPreferences.get("lockShowDate")
property bool showUser: DesktopPreferences.get("lockShowUser")
property bool fadeOnEmpty: DesktopPreferences.get("lockFadeOnEmpty")
property bool use24Hour: DesktopPreferences.get("use24Hour")
property string wallpaperPath: Wallpaper.active !== ""
? Wallpaper.active
: (Wallpaper.configured !== "" ? Wallpaper.configured : Wallpaper.shippedPath)
readonly property string previewMode: root.backgroundMode
readonly property real blurStrength: Math.max(0, Math.min(1, root.blurLevel / 5))
readonly property bool wallpaperVisible: wallpaper.visible
readonly property bool clockVisible: clockLabel.visible
readonly property bool dateVisible: dateLabel.visible
readonly property bool userVisible: userLabel.visible
readonly property bool passwordVisible: passwordField.visible
width: parent ? parent.width : 620
implicitHeight: 230
radius: Theme.cardRadius
clip: true
color: Theme.bg
border.width: 1
border.color: Theme.alpha(Theme.fg, 0.10)
Image {
id: wallpaper
anchors.fill: parent
visible: root.backgroundMode === "wallpaper"
source: visible && root.wallpaperPath !== "" ? root.wallpaperPath : ""
asynchronous: true
cache: true
fillMode: Image.PreserveAspectCrop
sourceSize.width: 960
sourceSize.height: 540
}
// Screenshot mode stays representative instead of taking a real desktop
// capture inside Settings. The layered window silhouettes communicate the
// selected softness without a live ShaderEffect or GPU repaint loop.
Rectangle {
anchors.fill: parent
visible: root.backgroundMode === "screenshot"
color: Theme.bgDark
Rectangle {
x: parent.width * 0.10
y: parent.height * 0.12
width: parent.width * 0.45
height: parent.height * 0.66
radius: 14 + root.blurStrength * 10
color: Theme.alpha(Theme.bgHighlight, 0.52 - root.blurStrength * 0.18)
border.width: 1
border.color: Theme.alpha(Theme.accent, 0.14)
}
Rectangle {
x: parent.width * 0.48
y: parent.height * 0.24
width: parent.width * 0.40
height: parent.height * 0.57
radius: 14 + root.blurStrength * 10
color: Theme.alpha(Theme.bgPanel, 0.64 - root.blurStrength * 0.20)
border.width: 1
border.color: Theme.alpha(Theme.accentSecondary, 0.13)
}
}
Rectangle {
anchors.fill: parent
color: root.backgroundMode === "wallpaper"
? Theme.alpha(Theme.bg, 0.42)
: Theme.alpha(Theme.bg, 0.12 + root.blurStrength * 0.16)
}
Text {
id: clockLabel
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: 26
visible: root.showClock
text: Qt.formatDateTime(clock.date, root.use24Hour ? "HH:mm" : "h:mm")
color: Theme.fg
font.family: Theme.fontFamily
font.pixelSize: 42
font.weight: Font.Light
}
Text {
id: dateLabel
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: clockLabel.visible ? clockLabel.bottom : parent.top
anchors.topMargin: clockLabel.visible ? 1 : 35
visible: root.showDate
text: Qt.formatDateTime(clock.date, "dddd, MMMM d")
color: Theme.fgDim
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSizeSmall
}
Rectangle {
id: passwordField
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: root.showUser ? 48 : 30
visible: !root.fadeOnEmpty
width: Math.min(270, parent.width * 0.48)
height: 36
radius: height / 2
color: Theme.alpha(Theme.bgPanel, 0.84)
border.width: 1
border.color: Theme.alpha(Theme.accent, 0.78)
Text {
anchors.centerIn: parent
text: "Password"
color: Theme.fgDim
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSizeSmall
font.italic: true
}
}
Text {
id: userLabel
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 19
visible: root.showUser
text: Quickshell.env("USER") || "User"
color: Theme.alpha(Theme.fg, 0.90)
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
}
SystemClock {
id: clock
precision: SystemClock.Minutes
}
}
@@ -78,6 +78,11 @@ the owner instead of duplicating it.
| `lockMinutes` | Power | Privacy | Idle timing owns the mechanism; privacy owns the expectation that the unattended desktop locks. |
| `lockOnSleep` | Power | Privacy | Suspend owns the transition; privacy owns whether waking requires authentication. |
Lock-screen visuals belong only to **Appearance**: background source, blur,
clock, date, user name, and password-field presentation. **Power** owns when
the session locks, while **Privacy** keeps only the established timing mirrors
above. Visual controls must not be copied onto either page.
Mirrors must remain the same schema-backed control, never a second preference
or a copied default. Additions to this table require a concrete discoverability
reason and an update to `tests/quickshell/settings-ownership-contract.sh`.
@@ -155,6 +160,7 @@ file with `qs -p`, and discover its PID from the exact Config path in
| `$XDG_STATE_HOME/panama/panama-home.json` | Home accessory favourites and aliases |
| `$XDG_STATE_HOME/panama/backups/` | Settings snapshots |
| `$XDG_STATE_HOME/panama/hypridle.conf` | Generated idle config |
| `$XDG_STATE_HOME/panama/hyprlock.conf` | Generated lock-screen appearance |
`SystemSettings.restoreDefaults()` spans all of them. A reset that silently
skipped one would be worse than having no reset, because nothing would say so.
@@ -29,6 +29,7 @@ ChoiceRow 1.0 ChoiceRow.qml
ActionRow 1.0 ActionRow.qml
TextRow 1.0 TextRow.qml
DesktopPreview 1.0 DesktopPreview.qml
LockScreenPreview 1.0 LockScreenPreview.qml
PowerPage 1.0 PowerPage.qml
DateTimePage 1.0 DateTimePage.qml
AccessibilityPage 1.0 AccessibilityPage.qml