1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-04-16 02:32:09 -04:00

lock screen format override

This commit is contained in:
bbedward
2025-08-12 19:25:33 -04:00
parent ac5a0fe995
commit fc1beca5e7
3 changed files with 1398 additions and 1379 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,16 +1,15 @@
pragma ComponentBehavior
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Effects
import QtQuick.Layouts
import Quickshell
import Quickshell.Services.Pam
import Quickshell.Io
import Quickshell.Services.Pam
import qs.Common
import qs.Modals
import qs.Services
import qs.Widgets
import qs.Modals
pragma ComponentBehavior
Item {
id: root
@@ -20,35 +19,32 @@ Item {
property bool unlocking: false
property var powerModal: null
property string confirmAction: ""
property var facts: ["Light takes 100,000 years to escape the Sun's core, then just 8 minutes to reach us.", "A teaspoon of neutron star matter would weigh a billion tons here on Earth.", "Right now, 100 trillion solar neutrinos are passing through your body every second.", "The Sun burns 4 million tons of itself into pure energy every second.", "The universe still glows with leftover heat from the Big Bang—just 2.7 degrees above absolute zero.", "There's a nebula out there that's actually colder than empty space itself.", "We've detected black holes crashing together by measuring spacetime stretch by less than 1/10,000th the width of a proton.", "Some cosmic radio bursts release more energy in milliseconds than our Sun does in days.", "Our galaxy might be crawling with billions of rogue planets drifting alone in the dark.", "Distant galaxies can move away from us faster than light because space itself is stretching.", "The edge of what we can see is 46.5 billion light-years away, even though the universe is only 13.8 billion years old.", "The universe is mostly invisible: 5% regular matter, 27% dark matter, 68% dark energy.", "A day on Venus lasts longer than its entire year around the Sun.", "On Mercury, the time between sunrises is 176 Earth days long.", "In about 4.5 billion years, our galaxy will smash into Andromeda.", "Most of the gold in your jewelry was forged when neutron stars collided somewhere in space.", "A black hole the mass of our Sun would take longer to evaporate than the current age of the universe... times a trillion trillion trillion trillion trillion.", "The fastest spinning star we know rotates 716 times per second.", "Cosmic rays create particles that shouldn't make it to Earth's surface, but time dilation lets them sneak through.", "Jupiter's magnetic field is so huge that if we could see it, it would look bigger than the Moon in our sky."]
property string randomFact: ""
signal unlockRequested
Component.onCompleted: {
pickRandomFact()
WeatherService.addRef()
UserInfoService.refreshUserInfo()
}
signal unlockRequested()
function pickRandomFact() {
randomFact = facts[Math.floor(Math.random() * facts.length)]
randomFact = facts[Math.floor(Math.random() * facts.length)];
}
Component.onCompleted: {
pickRandomFact();
WeatherService.addRef();
UserInfoService.refreshUserInfo();
}
onDemoModeChanged: {
if (demoMode) {
pickRandomFact()
}
}
if (demoMode)
pickRandomFact();
}
Component.onDestruction: {
WeatherService.removeRef()
WeatherService.removeRef();
}
Image {
id: wallpaperBackground
anchors.fill: parent
source: SessionData.wallpaperPath || ""
fillMode: Image.PreserveAspectCrop
@@ -56,14 +52,14 @@ Item {
asynchronous: true
cache: true
visible: source !== ""
layer.enabled: true
layer.effect: MultiEffect {
autoPaddingEnabled: false
blurEnabled: true
blur: 0.8
blurMax: 32
blurMultiplier: 1.0
blurMultiplier: 1
}
Behavior on opacity {
@@ -71,7 +67,9 @@ Item {
duration: Theme.mediumDuration
easing.type: Theme.standardEasing
}
}
}
Rectangle {
@@ -82,6 +80,7 @@ Item {
SystemClock {
id: systemClock
precision: SystemClock.Seconds
}
@@ -97,12 +96,10 @@ Item {
StyledText {
id: clockText
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
text: SettingsData.use24HourClock ? Qt.formatTime(
systemClock.date,
"H:mm") : Qt.formatTime(
systemClock.date, "h:mm AP")
text: SettingsData.use24HourClock ? Qt.formatTime(systemClock.date, "H:mm") : Qt.formatTime(systemClock.date, "h:mm AP")
font.pixelSize: 120
font.weight: Font.Light
color: "white"
@@ -113,11 +110,12 @@ Item {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: clockText.bottom
anchors.topMargin: -20
text: Qt.formatDate(new Date(), "dddd, MMMM d")
text: Qt.formatDate(systemClock.date, SettingsData.lockDateFormat)
font.pixelSize: Theme.fontSizeXLarge
color: "white"
opacity: 0.9
}
}
ColumnLayout {
@@ -132,9 +130,11 @@ Item {
Item {
id: avatarContainer
property bool hasImage: profileImageLoader.status === Image.Ready
Layout.preferredWidth: 60
Layout.preferredHeight: 60
property bool hasImage: profileImageLoader.status === Image.Ready
Rectangle {
anchors.fill: parent
@@ -147,12 +147,15 @@ Item {
Image {
id: profileImageLoader
source: {
if (PortalService.profileImage === "")
return ""
return "";
if (PortalService.profileImage.startsWith("/"))
return "file://" + PortalService.profileImage
return PortalService.profileImage
return "file://" + PortalService.profileImage;
return PortalService.profileImage;
}
smooth: true
asynchronous: true
@@ -174,6 +177,7 @@ Item {
Item {
id: circularMask
width: 60 - 10
height: 60 - 10
layer.enabled: true
@@ -186,6 +190,7 @@ Item {
color: "black"
antialiasing: true
}
}
Rectangle {
@@ -200,6 +205,7 @@ Item {
size: Theme.iconSize + 4
color: Theme.primaryText
}
}
DankIcon {
@@ -207,32 +213,24 @@ Item {
name: "warning"
size: Theme.iconSize + 4
color: Theme.primaryText
visible: PortalService.profileImage !== ""
&& profileImageLoader.status === Image.Error
visible: PortalService.profileImage !== "" && profileImageLoader.status === Image.Error
}
}
Rectangle {
property bool showPassword: false
Layout.fillWidth: true
Layout.preferredHeight: 60
radius: Theme.cornerRadius
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g,
Theme.surfaceContainer.b, 0.9)
border.color: passwordField.activeFocus ? Theme.primary : Qt.rgba(
1, 1, 1, 0.3)
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.9)
border.color: passwordField.activeFocus ? Theme.primary : Qt.rgba(1, 1, 1, 0.3)
border.width: passwordField.activeFocus ? 2 : 1
property bool showPassword: false
Behavior on border.color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
DankIcon {
id: lockIcon
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
@@ -243,69 +241,68 @@ Item {
TextInput {
id: passwordField
anchors.fill: parent
anchors.leftMargin: lockIcon.width + Theme.spacingM * 2
anchors.rightMargin: (revealButton.visible ? revealButton.width + Theme.spacingM : 0)
+ (enterButton.visible ? enterButton.width + Theme.spacingM : 0)
+ (loadingSpinner.visible ? loadingSpinner.width
+ Theme.spacingM : Theme.spacingM)
anchors.rightMargin: (revealButton.visible ? revealButton.width + Theme.spacingM : 0) + (enterButton.visible ? enterButton.width + Theme.spacingM : 0) + (loadingSpinner.visible ? loadingSpinner.width + Theme.spacingM : Theme.spacingM)
opacity: 0
focus: !demoMode
enabled: !demoMode
echoMode: parent.showPassword ? TextInput.Normal : TextInput.Password
onTextChanged: {
if (!demoMode)
root.passwordBuffer = text;
}
onAccepted: {
if (!demoMode && root.passwordBuffer.length > 0 && !pam.active) {
console.log("Enter pressed, starting PAM authentication");
pam.start();
}
}
Keys.onPressed: (event) => {
if (demoMode)
return ;
if (pam.active) {
console.log("PAM is active, ignoring input");
event.accepted = true;
return ;
}
}
Timer {
id: focusTimer
interval: 100
running: !demoMode
onTriggered: passwordField.forceActiveFocus()
}
onTextChanged: {
if (!demoMode) {
root.passwordBuffer = text
}
}
onAccepted: {
if (!demoMode && root.passwordBuffer.length > 0 && !pam.active) {
console.log("Enter pressed, starting PAM authentication")
pam.start()
}
}
Keys.onPressed: event => {
if (demoMode)
return
if (pam.active) {
console.log("PAM is active, ignoring input")
event.accepted = true
return
}
}
}
StyledText {
id: placeholder
property string pamState: ""
anchors.left: lockIcon.right
anchors.leftMargin: Theme.spacingM
anchors.right: (revealButton.visible ? revealButton.left : (enterButton.visible ? enterButton.left : (loadingSpinner.visible ? loadingSpinner.left : parent.right)))
anchors.rightMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
property string pamState: ""
text: {
if (demoMode)
return ""
if (root.unlocking)
return "Unlocking..."
if (pam.active)
return "Authenticating..."
return "hunter2"
}
return "";
if (root.unlocking)
return "Unlocking...";
if (pam.active)
return "Authenticating...";
return "hunter2";
}
color: root.unlocking ? Theme.primary : (pam.active ? Theme.primary : Theme.outline)
font.pixelSize: Theme.fontSizeMedium
opacity: (demoMode || root.passwordBuffer.length === 0) ? 1 : 0
@@ -315,6 +312,7 @@ Item {
duration: Theme.mediumDuration
easing.type: Theme.standardEasing
}
}
Behavior on color {
@@ -322,7 +320,9 @@ Item {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
StyledText {
@@ -331,17 +331,14 @@ Item {
anchors.right: (revealButton.visible ? revealButton.left : (enterButton.visible ? enterButton.left : (loadingSpinner.visible ? loadingSpinner.left : parent.right)))
anchors.rightMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
text: {
if (demoMode) {
return "••••••••"
} else if (parent.showPassword) {
return root.passwordBuffer
} else {
return "•".repeat(Math.min(root.passwordBuffer.length, 25))
if (demoMode)
return "••••••••";
else if (parent.showPassword)
return root.passwordBuffer;
else
return "•".repeat(Math.min(root.passwordBuffer.length, 25));
}
}
color: Theme.surfaceText
font.pixelSize: parent.showPassword ? Theme.fontSizeMedium : Theme.fontSizeLarge
opacity: (demoMode || root.passwordBuffer.length > 0) ? 1 : 0
@@ -352,24 +349,27 @@ Item {
duration: Theme.mediumDuration
easing.type: Theme.standardEasing
}
}
}
DankActionButton {
id: revealButton
anchors.right: enterButton.visible ? enterButton.left : (loadingSpinner.visible ? loadingSpinner.left : parent.right)
anchors.rightMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
iconName: parent.showPassword ? "visibility_off" : "visibility"
buttonSize: 32
visible: !demoMode && root.passwordBuffer.length > 0 && !pam.active
&& !root.unlocking
visible: !demoMode && root.passwordBuffer.length > 0 && !pam.active && !root.unlocking
enabled: visible
onClicked: parent.showPassword = !parent.showPassword
}
Rectangle {
id: loadingSpinner
anchors.right: enterButton.visible ? enterButton.left : parent.right
anchors.rightMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
@@ -388,6 +388,7 @@ Item {
SequentialAnimation on scale {
running: root.unlocking
NumberAnimation {
from: 0
to: 1.2
@@ -395,6 +396,7 @@ Item {
easing.type: Easing.BezierSpline
easing.bezierCurve: Anims.emphasizedDecel
}
NumberAnimation {
from: 1.2
to: 1
@@ -402,7 +404,9 @@ Item {
easing.type: Easing.BezierSpline
easing.bezierCurve: Anims.emphasizedAccel
}
}
}
Item {
@@ -415,8 +419,7 @@ Item {
radius: 10
anchors.centerIn: parent
color: "transparent"
border.color: Qt.rgba(Theme.primary.r, Theme.primary.g,
Theme.primary.b, 0.3)
border.color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.3)
border.width: 2
}
@@ -434,9 +437,7 @@ Item {
height: parent.height / 2
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
color: Qt.rgba(Theme.surfaceContainer.r,
Theme.surfaceContainer.g,
Theme.surfaceContainer.b, 0.9)
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.9)
}
RotationAnimation on rotation {
@@ -446,24 +447,27 @@ Item {
from: 0
to: 360
}
}
}
}
DankActionButton {
id: enterButton
anchors.right: parent.right
anchors.rightMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
iconName: "keyboard_return"
buttonSize: 36
visible: (demoMode || (root.passwordBuffer.length > 0 && !pam.active
&& !root.unlocking))
visible: (demoMode || (root.passwordBuffer.length > 0 && !pam.active && !root.unlocking))
enabled: !demoMode
onClicked: {
if (!demoMode) {
console.log("Enter button clicked, starting PAM authentication")
pam.start()
console.log("Enter button clicked, starting PAM authentication");
pam.start();
}
}
@@ -472,9 +476,21 @@ Item {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
Behavior on border.color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
}
StyledText {
@@ -482,12 +498,15 @@ Item {
Layout.preferredHeight: placeholder.pamState ? 20 : 0
text: {
if (placeholder.pamState === "error")
return "Authentication error - try again"
return "Authentication error - try again";
if (placeholder.pamState === "max")
return "Too many attempts - locked out"
return "Too many attempts - locked out";
if (placeholder.pamState === "fail")
return "Incorrect password - try again"
return ""
return "Incorrect password - try again";
return "";
}
color: Theme.error
font.pixelSize: Theme.fontSizeSmall
@@ -500,6 +519,7 @@ Item {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
Behavior on Layout.preferredHeight {
@@ -507,8 +527,11 @@ Item {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
}
StyledText {
@@ -526,8 +549,7 @@ Item {
anchors.top: parent.top
anchors.right: parent.right
anchors.margins: Theme.spacingXL
text: WeatherService.weather.available && WeatherService.weather.city
&& WeatherService.weather.city !== "Unknown" ? `${WeatherService.weather.city} ${(SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp)}°${(SettingsData.useFahrenheit ? "F" : "C")}` : ""
text: WeatherService.weather.available && WeatherService.weather.city && WeatherService.weather.city !== "Unknown" ? `${WeatherService.weather.city} ${(SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp)}°${(SettingsData.useFahrenheit ? "F" : "C")}` : ""
font.pixelSize: Theme.fontSizeMedium
color: "white"
horizontalAlignment: Text.AlignRight
@@ -555,11 +577,10 @@ Item {
iconColor: Theme.error
buttonSize: 40
onClicked: {
if (demoMode) {
console.log("Demo: Power")
} else {
powerDialog.open()
}
if (demoMode)
console.log("Demo: Power");
else
powerDialog.open();
}
}
@@ -567,11 +588,10 @@ Item {
iconName: "refresh"
buttonSize: 40
onClicked: {
if (demoMode) {
console.log("Demo: Reboot")
} else {
rebootDialog.open()
}
if (demoMode)
console.log("Demo: Reboot");
else
rebootDialog.open();
}
}
@@ -579,13 +599,13 @@ Item {
iconName: "logout"
buttonSize: 40
onClicked: {
if (demoMode) {
console.log("Demo: Logout")
} else {
logoutDialog.open()
}
if (demoMode)
console.log("Demo: Logout");
else
logoutDialog.open();
}
}
}
StyledText {
@@ -601,56 +621,58 @@ Item {
wrapMode: Text.NoWrap
visible: randomFact !== ""
}
}
FileView {
id: pamConfigWatcher
path: "/etc/pam.d/dankshell"
printErrors: false
}
PamContext {
id: pam
config: pamConfigWatcher.loaded ? "dankshell" : "login"
config: pamConfigWatcher.loaded ? "dankshell" : "login"
onResponseRequiredChanged: {
if (demoMode)
return
console.log("PAM response required:", responseRequired)
return ;
console.log("PAM response required:", responseRequired);
if (!responseRequired)
return
console.log("Responding to PAM with password buffer length:",
root.passwordBuffer.length)
respond(root.passwordBuffer)
}
return ;
onCompleted: res => {
console.log("Responding to PAM with password buffer length:", root.passwordBuffer.length);
respond(root.passwordBuffer);
}
onCompleted: (res) => {
if (demoMode)
return
console.log("PAM authentication completed with result:", res)
return ;
console.log("PAM authentication completed with result:", res);
if (res === PamResult.Success) {
console.log("Authentication successful, unlocking")
root.unlocking = true
passwordField.text = ""
root.passwordBuffer = ""
root.unlockRequested()
return
console.log("Authentication successful, unlocking");
root.unlocking = true;
passwordField.text = "";
root.passwordBuffer = "";
root.unlockRequested();
return ;
}
console.log("Authentication failed:", res)
console.log("Authentication failed:", res);
if (res === PamResult.Error)
placeholder.pamState = "error"
placeholder.pamState = "error";
else if (res === PamResult.MaxTries)
placeholder.pamState = "max"
placeholder.pamState = "max";
else if (res === PamResult.Failed)
placeholder.pamState = "fail"
placeholderDelay.restart()
placeholder.pamState = "fail";
placeholderDelay.restart();
}
}
Timer {
id: placeholderDelay
interval: 4000
onTriggered: placeholder.pamState = ""
}
@@ -663,18 +685,20 @@ Item {
Rectangle {
id: powerDialog
function open() {
visible = true;
}
function close() {
visible = false;
}
anchors.fill: parent
color: Qt.rgba(0, 0, 0, 0.8)
visible: false
z: 1000
function open() {
visible = true
}
function close() {
visible = false
}
Rectangle {
anchors.centerIn: parent
width: 320
@@ -711,11 +735,7 @@ Item {
width: 100
height: 40
radius: Theme.cornerRadius
color: cancelMouse1.pressed ? Qt.rgba(
Theme.surfaceVariant.r,
Theme.surfaceVariant.g,
Theme.surfaceVariant.b,
0.7) : cancelMouse1.containsMouse ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.9) : Theme.surfaceVariant
color: cancelMouse1.pressed ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.7) : cancelMouse1.containsMouse ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.9) : Theme.surfaceVariant
StyledText {
anchors.centerIn: parent
@@ -726,25 +746,20 @@ Item {
MouseArea {
id: cancelMouse1
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: powerDialog.close()
}
}
Rectangle {
width: 100
height: 40
radius: Theme.cornerRadius
color: powerMouse.pressed ? Qt.rgba(
Theme.error.r, Theme.error.g,
Theme.error.b,
0.8) : powerMouse.containsMouse ? Qt.rgba(
Theme.error.r,
Theme.error.g,
Theme.error.b,
1.0) : Theme.error
color: powerMouse.pressed ? Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.8) : powerMouse.containsMouse ? Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 1) : Theme.error
StyledText {
anchors.centerIn: parent
@@ -756,34 +771,42 @@ Item {
MouseArea {
id: powerMouse
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
powerDialog.close()
Quickshell.execDetached(["systemctl", "poweroff"])
powerDialog.close();
Quickshell.execDetached(["systemctl", "poweroff"]);
}
}
}
}
}
}
}
Rectangle {
id: rebootDialog
function open() {
visible = true;
}
function close() {
visible = false;
}
anchors.fill: parent
color: Qt.rgba(0, 0, 0, 0.8)
visible: false
z: 1000
function open() {
visible = true
}
function close() {
visible = false
}
Rectangle {
anchors.centerIn: parent
width: 320
@@ -820,11 +843,7 @@ Item {
width: 100
height: 40
radius: Theme.cornerRadius
color: cancelMouse2.pressed ? Qt.rgba(
Theme.surfaceVariant.r,
Theme.surfaceVariant.g,
Theme.surfaceVariant.b,
0.7) : cancelMouse2.containsMouse ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.9) : Theme.surfaceVariant
color: cancelMouse2.pressed ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.7) : cancelMouse2.containsMouse ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.9) : Theme.surfaceVariant
StyledText {
anchors.centerIn: parent
@@ -835,25 +854,20 @@ Item {
MouseArea {
id: cancelMouse2
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: rebootDialog.close()
}
}
Rectangle {
width: 100
height: 40
radius: Theme.cornerRadius
color: rebootMouse.pressed ? Qt.rgba(
Theme.primary.r, Theme.primary.g,
Theme.primary.b,
0.8) : rebootMouse.containsMouse ? Qt.rgba(
Theme.primary.r,
Theme.primary.g,
Theme.primary.b,
1.0) : Theme.primary
color: rebootMouse.pressed ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.8) : rebootMouse.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 1) : Theme.primary
StyledText {
anchors.centerIn: parent
@@ -865,34 +879,42 @@ Item {
MouseArea {
id: rebootMouse
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
rebootDialog.close()
Quickshell.execDetached(["systemctl", "reboot"])
rebootDialog.close();
Quickshell.execDetached(["systemctl", "reboot"]);
}
}
}
}
}
}
}
Rectangle {
id: logoutDialog
function open() {
visible = true;
}
function close() {
visible = false;
}
anchors.fill: parent
color: Qt.rgba(0, 0, 0, 0.8)
visible: false
z: 1000
function open() {
visible = true
}
function close() {
visible = false
}
Rectangle {
anchors.centerIn: parent
width: 320
@@ -929,11 +951,7 @@ Item {
width: 100
height: 40
radius: Theme.cornerRadius
color: cancelMouse3.pressed ? Qt.rgba(
Theme.surfaceVariant.r,
Theme.surfaceVariant.g,
Theme.surfaceVariant.b,
0.7) : cancelMouse3.containsMouse ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.9) : Theme.surfaceVariant
color: cancelMouse3.pressed ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.7) : cancelMouse3.containsMouse ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.9) : Theme.surfaceVariant
StyledText {
anchors.centerIn: parent
@@ -944,25 +962,20 @@ Item {
MouseArea {
id: cancelMouse3
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: logoutDialog.close()
}
}
Rectangle {
width: 100
height: 40
radius: Theme.cornerRadius
color: logoutMouse.pressed ? Qt.rgba(
Theme.primary.r, Theme.primary.g,
Theme.primary.b,
0.8) : logoutMouse.containsMouse ? Qt.rgba(
Theme.primary.r,
Theme.primary.g,
Theme.primary.b,
1.0) : Theme.primary
color: logoutMouse.pressed ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.8) : logoutMouse.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 1) : Theme.primary
StyledText {
anchors.centerIn: parent
@@ -974,17 +987,24 @@ Item {
MouseArea {
id: logoutMouse
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
logoutDialog.close()
NiriService.quit()
logoutDialog.close();
NiriService.quit();
}
}
}
}
}
}
}
}

View File

@@ -98,7 +98,7 @@ Item {
DankDropdown {
width: parent.width
height: 50
text: "Format"
text: "Top Bar Format"
description: "Preview: " + Qt.formatDate(new Date(), SettingsData.clockDateFormat)
currentValue: {
// Find matching preset or show "Custom"
@@ -153,12 +153,70 @@ Item {
}
}
DankDropdown {
width: parent.width
height: 50
text: "Lock Screen Format"
description: "Preview: " + Qt.formatDate(new Date(), SettingsData.lockDateFormat)
currentValue: {
// Find matching preset or show "Custom"
const presets = [{
"format": "ddd d",
"label": "Day Date"
}, {
"format": "ddd MMM d",
"label": "Day Month Date"
}, {
"format": "MMM d",
"label": "Month Date"
}, {
"format": "M/d",
"label": "Numeric (M/D)"
}, {
"format": "d/M",
"label": "Numeric (D/M)"
}, {
"format": "ddd d MMM yyyy",
"label": "Full with Year"
}, {
"format": "yyyy-MM-dd",
"label": "ISO Date"
}, {
"format": "dddd, MMMM d",
"label": "Full Day & Month"
}];
const match = presets.find((p) => {
return p.format === SettingsData.lockDateFormat;
});
return match ? match.label : "Custom: " + SettingsData.lockDateFormat;
}
options: ["Day Date", "Day Month Date", "Month Date", "Numeric (M/D)", "Numeric (D/M)", "Full with Year", "ISO Date", "Full Day & Month", "Custom..."]
onValueChanged: (value) => {
const formatMap = {
"Day Date": "ddd d",
"Day Month Date": "ddd MMM d",
"Month Date": "MMM d",
"Numeric (M/D)": "M/d",
"Numeric (D/M)": "d/M",
"Full with Year": "ddd d MMM yyyy",
"ISO Date": "yyyy-MM-dd",
"Full Day & Month": "dddd, MMMM d"
};
if (value === "Custom...") {
customLockFormatInput.visible = true;
} else {
customLockFormatInput.visible = false;
SettingsData.setLockDateFormat(formatMap[value]);
}
}
}
DankTextField {
id: customFormatInput
width: parent.width
visible: false
placeholderText: "Enter custom format (e.g., ddd MMM d)"
placeholderText: "Enter custom top bar format (e.g., ddd MMM d)"
text: SettingsData.clockDateFormat
onTextChanged: {
if (visible && text)
@@ -167,6 +225,20 @@ Item {
}
}
DankTextField {
id: customLockFormatInput
width: parent.width
visible: false
placeholderText: "Enter custom lock screen format (e.g., dddd, MMMM d)"
text: SettingsData.lockDateFormat
onTextChanged: {
if (visible && text)
SettingsData.setLockDateFormat(text);
}
}
Rectangle {
width: parent.width
height: formatHelp.implicitHeight + Theme.spacingM * 2