Border the lock input with the theme color4 like AGS

This commit is contained in:
2026-08-21 15:04:29 -04:00
parent 000ff69560
commit 076561c428
3 changed files with 54 additions and 14 deletions
+10 -7
View File
@@ -9,6 +9,7 @@ Item {
property string backgroundPath: ""
property int backgroundVersion: 0
property string brandingText: ""
property string paletteColor4: ""
property bool fingerprintConfigured: false
property bool authenticatingPassword: false
property string failureMessage: ""
@@ -45,16 +46,18 @@ Item {
readonly property bool showPasswordCursor: inputEnabled && !authenticatingPassword && failureMessage.length === 0
readonly property bool errorState: failureMessage.length > 0
// An empty field reads as resting and a filled one as active, which is the
// .theme-chip treatment in ags/style.css: a translucent accent border that
// goes solid once the tile is in use. The spec is built here rather than
// read from the [lock] theme tokens, since those carry the shell's own
// heavier look. Color.accent and Color.background still follow the theme,
// so this tracks a theme change exactly like the AGS widgets do.
// The AGS border pair: containers rest on alpha(@color4, 0.5) and go to a
// solid @accent once in use. An empty field reads as resting and a filled
// one as active. The spec is built here rather than read from the [lock]
// theme tokens, since those carry the shell's own heavier look; the colors
// themselves still come from the active theme, so this follows a theme
// change exactly like the AGS widgets do. color4 falls back to the accent
// for a palette that does not define one.
readonly property bool inputActive: passwordText.length > 0 || authenticatingPassword
readonly property color inputRestingBorder: paletteColor4.length > 0 ? paletteColor4 : Color.accent
readonly property color inputBorderColor: errorState
? Color.urgent
: (inputActive ? Color.accent : Util.alpha(Color.accent, 0.6))
: (inputActive ? Color.accent : Util.alpha(root.inputRestingBorder, 0.5))
readonly property color inputBackground: Util.alpha(Color.background, 0.6)
readonly property var inputBorderSpec: Border.flat(root.inputBorderColor, root.outlineThickness)
+27
View File
@@ -16,6 +16,7 @@ Item {
readonly property string userName: Quickshell.env("USER") || Quickshell.env("LOGNAME")
readonly property string currentBackgroundLink: stateHome + "/omarchy/current/background"
readonly property string brandingPath: home + "/.config/omarchy/branding/screensaver.txt"
readonly property string currentThemePath: stateHome + "/omarchy/current/theme"
property bool lockRequested: false
property bool pendingSessionLock: false
@@ -31,6 +32,7 @@ Item {
property string backgroundPath: ""
property int backgroundVersion: 0
property string brandingText: ""
property string paletteColor4: ""
property string lastEvent: "init"
property string lastEventAt: ""
property bool strandedLock: false
@@ -273,6 +275,7 @@ Item {
backgroundPath: root.backgroundPath
backgroundVersion: root.backgroundVersion
brandingText: root.brandingText
paletteColor4: root.paletteColor4
fingerprintConfigured: root.fingerprintConfigured
authenticatingPassword: root.authenticatingPassword
failureMessage: root.failureMessage
@@ -304,6 +307,7 @@ Item {
backgroundPath: root.backgroundPath
backgroundVersion: root.backgroundVersion
brandingText: root.brandingText
paletteColor4: root.paletteColor4
fingerprintConfigured: root.fingerprintConfigured
authenticatingPassword: false
failureMessage: ""
@@ -485,6 +489,29 @@ Item {
else armBlankTimer()
}
// The Color singleton exposes only foreground, background, accent, urgent,
// and muted, so the raw color4 slot the AGS stylesheet borders with has to
// be read here. Same file and same shape Color itself parses; the current
// theme directory is a real directory rewritten in place on every theme
// change, so watching the file is enough to follow a theme switch.
function readPaletteColor4(raw) {
var lines = String(raw || "").split("\n")
for (var i = 0; i < lines.length; i++) {
var match = lines[i].match(/^\s*color4\s*=\s*["']?(#[0-9A-Fa-f]{6})/)
if (match) return match[1]
}
return ""
}
FileView {
path: root.currentThemePath + "/colors.toml"
watchChanges: true
printErrors: false
onLoaded: root.paletteColor4 = root.readPaletteColor4(text())
onLoadFailed: root.paletteColor4 = ""
onFileChanged: reload()
}
// The same file the screensaver paints. Watched so an edit through
// `omarchy branding screensaver text` shows up on the next lock without a
// shell restart. A missing file simply leaves the lock screen unbranded.