mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-24 21:42:51 -05:00
@@ -243,6 +243,8 @@ Singleton {
|
|||||||
property bool lockBeforeSuspend: false
|
property bool lockBeforeSuspend: false
|
||||||
property bool preventIdleForMedia: false
|
property bool preventIdleForMedia: false
|
||||||
property bool loginctlLockIntegration: true
|
property bool loginctlLockIntegration: true
|
||||||
|
property bool fadeToLockEnabled: false
|
||||||
|
property int fadeToLockGracePeriod: 5
|
||||||
property string launchPrefix: ""
|
property string launchPrefix: ""
|
||||||
property var brightnessDevicePins: ({})
|
property var brightnessDevicePins: ({})
|
||||||
property var wifiNetworkPins: ({})
|
property var wifiNetworkPins: ({})
|
||||||
|
|||||||
@@ -145,6 +145,8 @@ var SPEC = {
|
|||||||
lockBeforeSuspend: { def: false },
|
lockBeforeSuspend: { def: false },
|
||||||
preventIdleForMedia: { def: false },
|
preventIdleForMedia: { def: false },
|
||||||
loginctlLockIntegration: { def: true },
|
loginctlLockIntegration: { def: true },
|
||||||
|
fadeToLockEnabled: { def: false },
|
||||||
|
fadeToLockGracePeriod: { def: 5 },
|
||||||
launchPrefix: { def: "" },
|
launchPrefix: { def: "" },
|
||||||
brightnessDevicePins: { def: {} },
|
brightnessDevicePins: { def: {} },
|
||||||
wifiNetworkPins: { def: {} },
|
wifiNetworkPins: { def: {} },
|
||||||
|
|||||||
@@ -63,6 +63,46 @@ Item {
|
|||||||
id: lock
|
id: lock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Variants {
|
||||||
|
model: Quickshell.screens
|
||||||
|
|
||||||
|
delegate: Loader {
|
||||||
|
id: fadeWindowLoader
|
||||||
|
required property var modelData
|
||||||
|
active: SettingsData.fadeToLockEnabled
|
||||||
|
asynchronous: false
|
||||||
|
|
||||||
|
sourceComponent: FadeToLockWindow {
|
||||||
|
screen: fadeWindowLoader.modelData
|
||||||
|
|
||||||
|
onFadeCompleted: {
|
||||||
|
IdleService.lockRequested();
|
||||||
|
}
|
||||||
|
|
||||||
|
onFadeCancelled: {
|
||||||
|
console.log("Fade to lock cancelled by user on screen:", fadeWindowLoader.modelData.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: IdleService
|
||||||
|
enabled: fadeWindowLoader.item !== null
|
||||||
|
|
||||||
|
function onFadeToLockRequested() {
|
||||||
|
if (fadeWindowLoader.item) {
|
||||||
|
fadeWindowLoader.item.startFade();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCancelFadeToLock() {
|
||||||
|
if (fadeWindowLoader.item) {
|
||||||
|
fadeWindowLoader.item.cancelFade();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: dankBarRepeater
|
id: dankBarRepeater
|
||||||
model: ScriptModel {
|
model: ScriptModel {
|
||||||
|
|||||||
@@ -76,10 +76,10 @@ Item {
|
|||||||
checked: SessionService.loginctlAvailable && SettingsData.loginctlLockIntegration
|
checked: SessionService.loginctlAvailable && SettingsData.loginctlLockIntegration
|
||||||
enabled: SessionService.loginctlAvailable
|
enabled: SessionService.loginctlAvailable
|
||||||
onToggled: checked => {
|
onToggled: checked => {
|
||||||
if (SessionService.loginctlAvailable) {
|
if (SessionService.loginctlAvailable) {
|
||||||
SettingsData.set("loginctlLockIntegration", checked)
|
SettingsData.set("loginctlLockIntegration", checked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
@@ -160,6 +160,40 @@ Item {
|
|||||||
onToggled: checked => SettingsData.set("preventIdleForMedia", checked)
|
onToggled: checked => SettingsData.set("preventIdleForMedia", checked)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DankToggle {
|
||||||
|
width: parent.width
|
||||||
|
text: I18n.tr("Fade to lock screen")
|
||||||
|
description: I18n.tr("Gradually fade the screen before locking with a configurable grace period")
|
||||||
|
checked: SettingsData.fadeToLockEnabled
|
||||||
|
onToggled: checked => SettingsData.set("fadeToLockEnabled", checked)
|
||||||
|
}
|
||||||
|
|
||||||
|
DankDropdown {
|
||||||
|
id: fadeGracePeriodDropdown
|
||||||
|
property var periodOptions: ["1 second", "2 seconds", "3 seconds", "4 seconds", "5 seconds", "10 seconds", "15 seconds", "20 seconds", "30 seconds"]
|
||||||
|
property var periodValues: [1, 2, 3, 4, 5, 10, 15, 20, 30]
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
addHorizontalPadding: true
|
||||||
|
text: I18n.tr("Fade grace period")
|
||||||
|
options: periodOptions
|
||||||
|
visible: SettingsData.fadeToLockEnabled
|
||||||
|
enabled: SettingsData.fadeToLockEnabled
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
const currentPeriod = SettingsData.fadeToLockGracePeriod;
|
||||||
|
const index = periodValues.indexOf(currentPeriod);
|
||||||
|
currentValue = index >= 0 ? periodOptions[index] : "5 seconds";
|
||||||
|
}
|
||||||
|
|
||||||
|
onValueChanged: value => {
|
||||||
|
const index = periodOptions.indexOf(value);
|
||||||
|
if (index >= 0) {
|
||||||
|
SettingsData.set("fadeToLockGracePeriod", periodValues[index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DankDropdown {
|
DankDropdown {
|
||||||
id: lockDropdown
|
id: lockDropdown
|
||||||
property var timeoutOptions: ["Never", "1 minute", "2 minutes", "3 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes", "30 minutes", "1 hour", "1 hour 30 minutes", "2 hours", "3 hours"]
|
property var timeoutOptions: ["Never", "1 minute", "2 minutes", "3 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes", "30 minutes", "1 hour", "1 hour 30 minutes", "2 hours", "3 hours"]
|
||||||
@@ -172,29 +206,29 @@ Item {
|
|||||||
Connections {
|
Connections {
|
||||||
target: powerCategory
|
target: powerCategory
|
||||||
function onCurrentIndexChanged() {
|
function onCurrentIndexChanged() {
|
||||||
const currentTimeout = powerCategory.currentIndex === 0 ? SettingsData.acLockTimeout : SettingsData.batteryLockTimeout
|
const currentTimeout = powerCategory.currentIndex === 0 ? SettingsData.acLockTimeout : SettingsData.batteryLockTimeout;
|
||||||
const index = lockDropdown.timeoutValues.indexOf(currentTimeout)
|
const index = lockDropdown.timeoutValues.indexOf(currentTimeout);
|
||||||
lockDropdown.currentValue = index >= 0 ? lockDropdown.timeoutOptions[index] : "Never"
|
lockDropdown.currentValue = index >= 0 ? lockDropdown.timeoutOptions[index] : "Never";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
const currentTimeout = powerCategory.currentIndex === 0 ? SettingsData.acLockTimeout : SettingsData.batteryLockTimeout
|
const currentTimeout = powerCategory.currentIndex === 0 ? SettingsData.acLockTimeout : SettingsData.batteryLockTimeout;
|
||||||
const index = timeoutValues.indexOf(currentTimeout)
|
const index = timeoutValues.indexOf(currentTimeout);
|
||||||
currentValue = index >= 0 ? timeoutOptions[index] : "Never"
|
currentValue = index >= 0 ? timeoutOptions[index] : "Never";
|
||||||
}
|
}
|
||||||
|
|
||||||
onValueChanged: value => {
|
onValueChanged: value => {
|
||||||
const index = timeoutOptions.indexOf(value)
|
const index = timeoutOptions.indexOf(value);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
const timeout = timeoutValues[index]
|
const timeout = timeoutValues[index];
|
||||||
if (powerCategory.currentIndex === 0) {
|
if (powerCategory.currentIndex === 0) {
|
||||||
SettingsData.set("acLockTimeout", timeout)
|
SettingsData.set("acLockTimeout", timeout);
|
||||||
} else {
|
} else {
|
||||||
SettingsData.set("batteryLockTimeout", timeout)
|
SettingsData.set("batteryLockTimeout", timeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankDropdown {
|
DankDropdown {
|
||||||
@@ -209,29 +243,29 @@ Item {
|
|||||||
Connections {
|
Connections {
|
||||||
target: powerCategory
|
target: powerCategory
|
||||||
function onCurrentIndexChanged() {
|
function onCurrentIndexChanged() {
|
||||||
const currentTimeout = powerCategory.currentIndex === 0 ? SettingsData.acMonitorTimeout : SettingsData.batteryMonitorTimeout
|
const currentTimeout = powerCategory.currentIndex === 0 ? SettingsData.acMonitorTimeout : SettingsData.batteryMonitorTimeout;
|
||||||
const index = monitorDropdown.timeoutValues.indexOf(currentTimeout)
|
const index = monitorDropdown.timeoutValues.indexOf(currentTimeout);
|
||||||
monitorDropdown.currentValue = index >= 0 ? monitorDropdown.timeoutOptions[index] : "Never"
|
monitorDropdown.currentValue = index >= 0 ? monitorDropdown.timeoutOptions[index] : "Never";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
const currentTimeout = powerCategory.currentIndex === 0 ? SettingsData.acMonitorTimeout : SettingsData.batteryMonitorTimeout
|
const currentTimeout = powerCategory.currentIndex === 0 ? SettingsData.acMonitorTimeout : SettingsData.batteryMonitorTimeout;
|
||||||
const index = timeoutValues.indexOf(currentTimeout)
|
const index = timeoutValues.indexOf(currentTimeout);
|
||||||
currentValue = index >= 0 ? timeoutOptions[index] : "Never"
|
currentValue = index >= 0 ? timeoutOptions[index] : "Never";
|
||||||
}
|
}
|
||||||
|
|
||||||
onValueChanged: value => {
|
onValueChanged: value => {
|
||||||
const index = timeoutOptions.indexOf(value)
|
const index = timeoutOptions.indexOf(value);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
const timeout = timeoutValues[index]
|
const timeout = timeoutValues[index];
|
||||||
if (powerCategory.currentIndex === 0) {
|
if (powerCategory.currentIndex === 0) {
|
||||||
SettingsData.set("acMonitorTimeout", timeout)
|
SettingsData.set("acMonitorTimeout", timeout);
|
||||||
} else {
|
} else {
|
||||||
SettingsData.set("batteryMonitorTimeout", timeout)
|
SettingsData.set("batteryMonitorTimeout", timeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankDropdown {
|
DankDropdown {
|
||||||
@@ -246,29 +280,29 @@ Item {
|
|||||||
Connections {
|
Connections {
|
||||||
target: powerCategory
|
target: powerCategory
|
||||||
function onCurrentIndexChanged() {
|
function onCurrentIndexChanged() {
|
||||||
const currentTimeout = powerCategory.currentIndex === 0 ? SettingsData.acSuspendTimeout : SettingsData.batterySuspendTimeout
|
const currentTimeout = powerCategory.currentIndex === 0 ? SettingsData.acSuspendTimeout : SettingsData.batterySuspendTimeout;
|
||||||
const index = suspendDropdown.timeoutValues.indexOf(currentTimeout)
|
const index = suspendDropdown.timeoutValues.indexOf(currentTimeout);
|
||||||
suspendDropdown.currentValue = index >= 0 ? suspendDropdown.timeoutOptions[index] : "Never"
|
suspendDropdown.currentValue = index >= 0 ? suspendDropdown.timeoutOptions[index] : "Never";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
const currentTimeout = powerCategory.currentIndex === 0 ? SettingsData.acSuspendTimeout : SettingsData.batterySuspendTimeout
|
const currentTimeout = powerCategory.currentIndex === 0 ? SettingsData.acSuspendTimeout : SettingsData.batterySuspendTimeout;
|
||||||
const index = timeoutValues.indexOf(currentTimeout)
|
const index = timeoutValues.indexOf(currentTimeout);
|
||||||
currentValue = index >= 0 ? timeoutOptions[index] : "Never"
|
currentValue = index >= 0 ? timeoutOptions[index] : "Never";
|
||||||
}
|
}
|
||||||
|
|
||||||
onValueChanged: value => {
|
onValueChanged: value => {
|
||||||
const index = timeoutOptions.indexOf(value)
|
const index = timeoutOptions.indexOf(value);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
const timeout = timeoutValues[index]
|
const timeout = timeoutValues[index];
|
||||||
if (powerCategory.currentIndex === 0) {
|
if (powerCategory.currentIndex === 0) {
|
||||||
SettingsData.set("acSuspendTimeout", timeout)
|
SettingsData.set("acSuspendTimeout", timeout);
|
||||||
} else {
|
} else {
|
||||||
SettingsData.set("batterySuspendTimeout", timeout)
|
SettingsData.set("batterySuspendTimeout", timeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
@@ -293,25 +327,25 @@ Item {
|
|||||||
Connections {
|
Connections {
|
||||||
target: powerCategory
|
target: powerCategory
|
||||||
function onCurrentIndexChanged() {
|
function onCurrentIndexChanged() {
|
||||||
const behavior = powerCategory.currentIndex === 0 ? SettingsData.acSuspendBehavior : SettingsData.batterySuspendBehavior
|
const behavior = powerCategory.currentIndex === 0 ? SettingsData.acSuspendBehavior : SettingsData.batterySuspendBehavior;
|
||||||
suspendBehaviorSelector.currentIndex = behavior
|
suspendBehaviorSelector.currentIndex = behavior;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
const behavior = powerCategory.currentIndex === 0 ? SettingsData.acSuspendBehavior : SettingsData.batterySuspendBehavior
|
const behavior = powerCategory.currentIndex === 0 ? SettingsData.acSuspendBehavior : SettingsData.batterySuspendBehavior;
|
||||||
currentIndex = behavior
|
currentIndex = behavior;
|
||||||
}
|
}
|
||||||
|
|
||||||
onSelectionChanged: (index, selected) => {
|
onSelectionChanged: (index, selected) => {
|
||||||
if (selected) {
|
if (selected) {
|
||||||
if (powerCategory.currentIndex === 0) {
|
if (powerCategory.currentIndex === 0) {
|
||||||
SettingsData.set("acSuspendBehavior", index)
|
SettingsData.set("acSuspendBehavior", index);
|
||||||
} else {
|
} else {
|
||||||
SettingsData.set("batterySuspendBehavior", index)
|
SettingsData.set("batterySuspendBehavior", index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,17 +418,17 @@ Item {
|
|||||||
property var actionValues: ["reboot", "logout", "poweroff", "lock", "suspend", "restart", "hibernate"]
|
property var actionValues: ["reboot", "logout", "poweroff", "lock", "suspend", "restart", "hibernate"]
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
const currentAction = SettingsData.powerMenuDefaultAction || "logout"
|
const currentAction = SettingsData.powerMenuDefaultAction || "logout";
|
||||||
const index = actionValues.indexOf(currentAction)
|
const index = actionValues.indexOf(currentAction);
|
||||||
currentValue = index >= 0 ? options[index] : "Log Out"
|
currentValue = index >= 0 ? options[index] : "Log Out";
|
||||||
}
|
}
|
||||||
|
|
||||||
onValueChanged: value => {
|
onValueChanged: value => {
|
||||||
const index = options.indexOf(value)
|
const index = options.indexOf(value);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
SettingsData.set("powerMenuDefaultAction", actionValues[index])
|
SettingsData.set("powerMenuDefaultAction", actionValues[index]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
@@ -406,14 +440,14 @@ Item {
|
|||||||
text: I18n.tr("Show Reboot")
|
text: I18n.tr("Show Reboot")
|
||||||
checked: SettingsData.powerMenuActions.includes("reboot")
|
checked: SettingsData.powerMenuActions.includes("reboot")
|
||||||
onToggled: checked => {
|
onToggled: checked => {
|
||||||
let actions = [...SettingsData.powerMenuActions]
|
let actions = [...SettingsData.powerMenuActions];
|
||||||
if (checked && !actions.includes("reboot")) {
|
if (checked && !actions.includes("reboot")) {
|
||||||
actions.push("reboot")
|
actions.push("reboot");
|
||||||
} else if (!checked) {
|
} else if (!checked) {
|
||||||
actions = actions.filter(a => a !== "reboot")
|
actions = actions.filter(a => a !== "reboot");
|
||||||
}
|
}
|
||||||
SettingsData.set("powerMenuActions", actions)
|
SettingsData.set("powerMenuActions", actions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
@@ -421,14 +455,14 @@ Item {
|
|||||||
text: I18n.tr("Show Log Out")
|
text: I18n.tr("Show Log Out")
|
||||||
checked: SettingsData.powerMenuActions.includes("logout")
|
checked: SettingsData.powerMenuActions.includes("logout")
|
||||||
onToggled: checked => {
|
onToggled: checked => {
|
||||||
let actions = [...SettingsData.powerMenuActions]
|
let actions = [...SettingsData.powerMenuActions];
|
||||||
if (checked && !actions.includes("logout")) {
|
if (checked && !actions.includes("logout")) {
|
||||||
actions.push("logout")
|
actions.push("logout");
|
||||||
} else if (!checked) {
|
} else if (!checked) {
|
||||||
actions = actions.filter(a => a !== "logout")
|
actions = actions.filter(a => a !== "logout");
|
||||||
}
|
}
|
||||||
SettingsData.set("powerMenuActions", actions)
|
SettingsData.set("powerMenuActions", actions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
@@ -436,14 +470,14 @@ Item {
|
|||||||
text: I18n.tr("Show Power Off")
|
text: I18n.tr("Show Power Off")
|
||||||
checked: SettingsData.powerMenuActions.includes("poweroff")
|
checked: SettingsData.powerMenuActions.includes("poweroff")
|
||||||
onToggled: checked => {
|
onToggled: checked => {
|
||||||
let actions = [...SettingsData.powerMenuActions]
|
let actions = [...SettingsData.powerMenuActions];
|
||||||
if (checked && !actions.includes("poweroff")) {
|
if (checked && !actions.includes("poweroff")) {
|
||||||
actions.push("poweroff")
|
actions.push("poweroff");
|
||||||
} else if (!checked) {
|
} else if (!checked) {
|
||||||
actions = actions.filter(a => a !== "poweroff")
|
actions = actions.filter(a => a !== "poweroff");
|
||||||
}
|
}
|
||||||
SettingsData.set("powerMenuActions", actions)
|
SettingsData.set("powerMenuActions", actions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
@@ -451,14 +485,14 @@ Item {
|
|||||||
text: I18n.tr("Show Lock")
|
text: I18n.tr("Show Lock")
|
||||||
checked: SettingsData.powerMenuActions.includes("lock")
|
checked: SettingsData.powerMenuActions.includes("lock")
|
||||||
onToggled: checked => {
|
onToggled: checked => {
|
||||||
let actions = [...SettingsData.powerMenuActions]
|
let actions = [...SettingsData.powerMenuActions];
|
||||||
if (checked && !actions.includes("lock")) {
|
if (checked && !actions.includes("lock")) {
|
||||||
actions.push("lock")
|
actions.push("lock");
|
||||||
} else if (!checked) {
|
} else if (!checked) {
|
||||||
actions = actions.filter(a => a !== "lock")
|
actions = actions.filter(a => a !== "lock");
|
||||||
}
|
}
|
||||||
SettingsData.set("powerMenuActions", actions)
|
SettingsData.set("powerMenuActions", actions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
@@ -466,14 +500,14 @@ Item {
|
|||||||
text: I18n.tr("Show Suspend")
|
text: I18n.tr("Show Suspend")
|
||||||
checked: SettingsData.powerMenuActions.includes("suspend")
|
checked: SettingsData.powerMenuActions.includes("suspend")
|
||||||
onToggled: checked => {
|
onToggled: checked => {
|
||||||
let actions = [...SettingsData.powerMenuActions]
|
let actions = [...SettingsData.powerMenuActions];
|
||||||
if (checked && !actions.includes("suspend")) {
|
if (checked && !actions.includes("suspend")) {
|
||||||
actions.push("suspend")
|
actions.push("suspend");
|
||||||
} else if (!checked) {
|
} else if (!checked) {
|
||||||
actions = actions.filter(a => a !== "suspend")
|
actions = actions.filter(a => a !== "suspend");
|
||||||
}
|
}
|
||||||
SettingsData.set("powerMenuActions", actions)
|
SettingsData.set("powerMenuActions", actions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
@@ -482,14 +516,14 @@ Item {
|
|||||||
description: I18n.tr("Restart the DankMaterialShell")
|
description: I18n.tr("Restart the DankMaterialShell")
|
||||||
checked: SettingsData.powerMenuActions.includes("restart")
|
checked: SettingsData.powerMenuActions.includes("restart")
|
||||||
onToggled: checked => {
|
onToggled: checked => {
|
||||||
let actions = [...SettingsData.powerMenuActions]
|
let actions = [...SettingsData.powerMenuActions];
|
||||||
if (checked && !actions.includes("restart")) {
|
if (checked && !actions.includes("restart")) {
|
||||||
actions.push("restart")
|
actions.push("restart");
|
||||||
} else if (!checked) {
|
} else if (!checked) {
|
||||||
actions = actions.filter(a => a !== "restart")
|
actions = actions.filter(a => a !== "restart");
|
||||||
}
|
}
|
||||||
SettingsData.set("powerMenuActions", actions)
|
SettingsData.set("powerMenuActions", actions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
@@ -499,14 +533,14 @@ Item {
|
|||||||
checked: SettingsData.powerMenuActions.includes("hibernate")
|
checked: SettingsData.powerMenuActions.includes("hibernate")
|
||||||
visible: SessionService.hibernateSupported
|
visible: SessionService.hibernateSupported
|
||||||
onToggled: checked => {
|
onToggled: checked => {
|
||||||
let actions = [...SettingsData.powerMenuActions]
|
let actions = [...SettingsData.powerMenuActions];
|
||||||
if (checked && !actions.includes("hibernate")) {
|
if (checked && !actions.includes("hibernate")) {
|
||||||
actions.push("hibernate")
|
actions.push("hibernate");
|
||||||
} else if (!checked) {
|
} else if (!checked) {
|
||||||
actions = actions.filter(a => a !== "hibernate")
|
actions = actions.filter(a => a !== "hibernate");
|
||||||
}
|
}
|
||||||
SettingsData.set("powerMenuActions", actions)
|
SettingsData.set("powerMenuActions", actions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -612,12 +646,12 @@ Item {
|
|||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (SettingsData.customPowerActionLock) {
|
if (SettingsData.customPowerActionLock) {
|
||||||
text = SettingsData.customPowerActionLock
|
text = SettingsData.customPowerActionLock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onTextEdited: {
|
onTextEdited: {
|
||||||
SettingsData.set("customPowerActionLock", text.trim())
|
SettingsData.set("customPowerActionLock", text.trim());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -644,12 +678,12 @@ Item {
|
|||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (SettingsData.customPowerActionLogout) {
|
if (SettingsData.customPowerActionLogout) {
|
||||||
text = SettingsData.customPowerActionLogout
|
text = SettingsData.customPowerActionLogout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onTextEdited: {
|
onTextEdited: {
|
||||||
SettingsData.set("customPowerActionLogout", text.trim())
|
SettingsData.set("customPowerActionLogout", text.trim());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -676,12 +710,12 @@ Item {
|
|||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (SettingsData.customPowerActionSuspend) {
|
if (SettingsData.customPowerActionSuspend) {
|
||||||
text = SettingsData.customPowerActionSuspend
|
text = SettingsData.customPowerActionSuspend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onTextEdited: {
|
onTextEdited: {
|
||||||
SettingsData.set("customPowerActionSuspend", text.trim())
|
SettingsData.set("customPowerActionSuspend", text.trim());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -708,12 +742,12 @@ Item {
|
|||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (SettingsData.customPowerActionHibernate) {
|
if (SettingsData.customPowerActionHibernate) {
|
||||||
text = SettingsData.customPowerActionHibernate
|
text = SettingsData.customPowerActionHibernate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onTextEdited: {
|
onTextEdited: {
|
||||||
SettingsData.set("customPowerActionHibernate", text.trim())
|
SettingsData.set("customPowerActionHibernate", text.trim());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -740,12 +774,12 @@ Item {
|
|||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (SettingsData.customPowerActionReboot) {
|
if (SettingsData.customPowerActionReboot) {
|
||||||
text = SettingsData.customPowerActionReboot
|
text = SettingsData.customPowerActionReboot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onTextEdited: {
|
onTextEdited: {
|
||||||
SettingsData.set("customPowerActionReboot", text.trim())
|
SettingsData.set("customPowerActionReboot", text.trim());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -772,12 +806,12 @@ Item {
|
|||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (SettingsData.customPowerActionPowerOff) {
|
if (SettingsData.customPowerActionPowerOff) {
|
||||||
text = SettingsData.customPowerActionPowerOff
|
text = SettingsData.customPowerActionPowerOff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onTextEdited: {
|
onTextEdited: {
|
||||||
SettingsData.set("customPowerActionPowerOff", text.trim())
|
SettingsData.set("customPowerActionPowerOff", text.trim());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
102
quickshell/Modules/Lock/FadeToLockWindow.qml
Normal file
102
quickshell/Modules/Lock/FadeToLockWindow.qml
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import qs.Common
|
||||||
|
|
||||||
|
PanelWindow {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool active: false
|
||||||
|
|
||||||
|
signal fadeCompleted
|
||||||
|
signal fadeCancelled
|
||||||
|
|
||||||
|
visible: active
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
WlrLayershell.namespace: "dms:fade-to-lock"
|
||||||
|
WlrLayershell.layer: WlrLayershell.Overlay
|
||||||
|
WlrLayershell.exclusiveZone: -1
|
||||||
|
WlrLayershell.keyboardFocus: active ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
left: true
|
||||||
|
right: true
|
||||||
|
top: true
|
||||||
|
bottom: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: fadeOverlay
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "black"
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
|
onOpacityChanged: {
|
||||||
|
if (opacity >= 0.99 && root.active) {
|
||||||
|
root.fadeCompleted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SequentialAnimation {
|
||||||
|
id: fadeSeq
|
||||||
|
running: false
|
||||||
|
|
||||||
|
NumberAnimation {
|
||||||
|
target: fadeOverlay
|
||||||
|
property: "opacity"
|
||||||
|
from: 0.0
|
||||||
|
to: 1.0
|
||||||
|
duration: SettingsData.fadeToLockGracePeriod * 1000
|
||||||
|
easing.type: Easing.OutCubic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function startFade() {
|
||||||
|
if (!SettingsData.fadeToLockEnabled)
|
||||||
|
return;
|
||||||
|
active = true;
|
||||||
|
fadeOverlay.opacity = 0.0;
|
||||||
|
fadeSeq.stop();
|
||||||
|
fadeSeq.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelFade() {
|
||||||
|
fadeSeq.stop();
|
||||||
|
fadeOverlay.opacity = 0.0;
|
||||||
|
active = false;
|
||||||
|
fadeCancelled();
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
enabled: root.active
|
||||||
|
onClicked: root.cancelFade()
|
||||||
|
onPressed: root.cancelFade()
|
||||||
|
}
|
||||||
|
|
||||||
|
FocusScope {
|
||||||
|
anchors.fill: parent
|
||||||
|
focus: root.active
|
||||||
|
|
||||||
|
Keys.onPressed: event => {
|
||||||
|
root.cancelFade();
|
||||||
|
event.accepted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (active) {
|
||||||
|
forceActiveFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onActiveChanged: {
|
||||||
|
if (active) {
|
||||||
|
forceActiveFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,23 +15,23 @@ Scope {
|
|||||||
property bool processingExternalEvent: false
|
property bool processingExternalEvent: false
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
IdleService.lockComponent = this
|
IdleService.lockComponent = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
function lock() {
|
function lock() {
|
||||||
if (SettingsData.customPowerActionLock && SettingsData.customPowerActionLock.length > 0) {
|
if (SettingsData.customPowerActionLock && SettingsData.customPowerActionLock.length > 0) {
|
||||||
Quickshell.execDetached(["sh", "-c", SettingsData.customPowerActionLock])
|
Quickshell.execDetached(["sh", "-c", SettingsData.customPowerActionLock]);
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
if (!processingExternalEvent && SettingsData.loginctlLockIntegration && DMSService.isConnected) {
|
if (!processingExternalEvent && SettingsData.loginctlLockIntegration && DMSService.isConnected) {
|
||||||
DMSService.lockSession(response => {
|
DMSService.lockSession(response => {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
console.warn("Lock: Failed to call loginctl.lock:", response.error)
|
console.warn("Lock: Failed to call loginctl.lock:", response.error);
|
||||||
shouldLock = true
|
shouldLock = true;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
} else {
|
} else {
|
||||||
shouldLock = true
|
shouldLock = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,32 +39,32 @@ Scope {
|
|||||||
if (!processingExternalEvent && SettingsData.loginctlLockIntegration && DMSService.isConnected) {
|
if (!processingExternalEvent && SettingsData.loginctlLockIntegration && DMSService.isConnected) {
|
||||||
DMSService.unlockSession(response => {
|
DMSService.unlockSession(response => {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
console.warn("Lock: Failed to call loginctl.unlock:", response.error)
|
console.warn("Lock: Failed to call loginctl.unlock:", response.error);
|
||||||
shouldLock = false
|
shouldLock = false;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
} else {
|
} else {
|
||||||
shouldLock = false
|
shouldLock = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function activate() {
|
function activate() {
|
||||||
lock()
|
lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: SessionService
|
target: SessionService
|
||||||
|
|
||||||
function onSessionLocked() {
|
function onSessionLocked() {
|
||||||
processingExternalEvent = true
|
processingExternalEvent = true;
|
||||||
shouldLock = true
|
shouldLock = true;
|
||||||
processingExternalEvent = false
|
processingExternalEvent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSessionUnlocked() {
|
function onSessionUnlocked() {
|
||||||
processingExternalEvent = true
|
processingExternalEvent = true;
|
||||||
shouldLock = false
|
shouldLock = false;
|
||||||
processingExternalEvent = false
|
processingExternalEvent = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ Scope {
|
|||||||
target: IdleService
|
target: IdleService
|
||||||
|
|
||||||
function onLockRequested() {
|
function onLockRequested() {
|
||||||
lock()
|
lock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,11 +93,11 @@ Scope {
|
|||||||
screenName: lockSurface.screen?.name ?? ""
|
screenName: lockSurface.screen?.name ?? ""
|
||||||
isLocked: shouldLock
|
isLocked: shouldLock
|
||||||
onUnlockRequested: {
|
onUnlockRequested: {
|
||||||
root.unlock()
|
root.unlock();
|
||||||
}
|
}
|
||||||
onPasswordChanged: newPassword => {
|
onPasswordChanged: newPassword => {
|
||||||
root.sharedPasswordBuffer = newPassword
|
root.sharedPasswordBuffer = newPassword;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,21 +113,21 @@ Scope {
|
|||||||
if (!root.processingExternalEvent && SettingsData.loginctlLockIntegration && DMSService.isConnected) {
|
if (!root.processingExternalEvent && SettingsData.loginctlLockIntegration && DMSService.isConnected) {
|
||||||
DMSService.lockSession(response => {
|
DMSService.lockSession(response => {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
console.warn("Lock: Failed to call loginctl.lock:", response.error)
|
console.warn("Lock: Failed to call loginctl.lock:", response.error);
|
||||||
root.shouldLock = true
|
root.shouldLock = true;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
} else {
|
} else {
|
||||||
root.shouldLock = true
|
root.shouldLock = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function demo() {
|
function demo() {
|
||||||
demoWindow.showDemo()
|
demoWindow.showDemo();
|
||||||
}
|
}
|
||||||
|
|
||||||
function isLocked(): bool {
|
function isLocked(): bool {
|
||||||
return sessionLock.locked
|
return sessionLock.locked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import QtCore
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Effects
|
import QtQuick.Effects
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
@@ -30,52 +29,60 @@ Item {
|
|||||||
signal unlockRequested
|
signal unlockRequested
|
||||||
|
|
||||||
function pickRandomFact() {
|
function pickRandomFact() {
|
||||||
randomFact = Facts.getRandomFact()
|
randomFact = Facts.getRandomFact();
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (demoMode) {
|
if (demoMode) {
|
||||||
pickRandomFact()
|
pickRandomFact();
|
||||||
}
|
}
|
||||||
|
|
||||||
WeatherService.addRef()
|
WeatherService.addRef();
|
||||||
UserInfoService.refreshUserInfo()
|
UserInfoService.refreshUserInfo();
|
||||||
|
|
||||||
if (CompositorService.isHyprland) {
|
if (CompositorService.isHyprland) {
|
||||||
updateHyprlandLayout()
|
updateHyprlandLayout();
|
||||||
hyprlandLayoutUpdateTimer.start()
|
hyprlandLayoutUpdateTimer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
lockerReadyArmed = true
|
lockerReadyArmed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
onDemoModeChanged: {
|
onDemoModeChanged: {
|
||||||
if (demoMode) {
|
if (demoMode) {
|
||||||
pickRandomFact()
|
pickRandomFact();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Component.onDestruction: {
|
Component.onDestruction: {
|
||||||
WeatherService.removeRef()
|
WeatherService.removeRef();
|
||||||
if (CompositorService.isHyprland) {
|
if (CompositorService.isHyprland) {
|
||||||
hyprlandLayoutUpdateTimer.stop()
|
hyprlandLayoutUpdateTimer.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendLockerReadyOnce() {
|
function sendLockerReadyOnce() {
|
||||||
if (lockerReadySent) return;
|
if (lockerReadySent)
|
||||||
if (root.unlocking) return;
|
return;
|
||||||
|
if (root.unlocking)
|
||||||
|
return;
|
||||||
lockerReadySent = true;
|
lockerReadySent = true;
|
||||||
if (SessionService.loginctlAvailable && DMSService.apiVersion >= 2) {
|
if (SessionService.loginctlAvailable && DMSService.apiVersion >= 2) {
|
||||||
DMSService.sendRequest("loginctl.lockerReady", null, resp => {
|
DMSService.sendRequest("loginctl.lockerReady", null, resp => {
|
||||||
if (resp?.error) console.warn("lockerReady failed:", resp.error)
|
if (resp?.error)
|
||||||
else console.log("lockerReady sent (afterAnimating/afterRendering)");
|
console.warn("lockerReady failed:", resp.error);
|
||||||
|
else
|
||||||
|
console.log("lockerReady sent (afterAnimating/afterRendering)");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function maybeSend() {
|
function maybeSend() {
|
||||||
if (!lockerReadyArmed) return;
|
if (!lockerReadyArmed)
|
||||||
if (root.unlocking) return;
|
return;
|
||||||
if (!root.visible || root.opacity <= 0) return;
|
if (root.unlocking)
|
||||||
|
return;
|
||||||
|
if (!root.visible || root.opacity <= 0)
|
||||||
|
return;
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
if (root.visible && root.opacity > 0 && !root.unlocking)
|
if (root.visible && root.opacity > 0 && !root.unlocking)
|
||||||
sendLockerReadyOnce();
|
sendLockerReadyOnce();
|
||||||
@@ -86,8 +93,12 @@ Item {
|
|||||||
target: root.Window.window
|
target: root.Window.window
|
||||||
enabled: target !== null
|
enabled: target !== null
|
||||||
|
|
||||||
function onAfterAnimating() { maybeSend(); }
|
function onAfterAnimating() {
|
||||||
function onAfterRendering() { maybeSend(); }
|
maybeSend();
|
||||||
|
}
|
||||||
|
function onAfterRendering() {
|
||||||
|
maybeSend();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onVisibleChanged: maybeSend()
|
onVisibleChanged: maybeSend()
|
||||||
@@ -95,7 +106,7 @@ Item {
|
|||||||
|
|
||||||
function updateHyprlandLayout() {
|
function updateHyprlandLayout() {
|
||||||
if (CompositorService.isHyprland) {
|
if (CompositorService.isHyprland) {
|
||||||
hyprlandLayoutProcess.running = true
|
hyprlandLayoutProcess.running = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,27 +117,27 @@ Item {
|
|||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
onStreamFinished: {
|
onStreamFinished: {
|
||||||
try {
|
try {
|
||||||
const data = JSON.parse(text)
|
const data = JSON.parse(text);
|
||||||
const mainKeyboard = data.keyboards.find(kb => kb.main === true)
|
const mainKeyboard = data.keyboards.find(kb => kb.main === true);
|
||||||
hyprlandKeyboard = mainKeyboard.name
|
hyprlandKeyboard = mainKeyboard.name;
|
||||||
if (mainKeyboard && mainKeyboard.active_keymap) {
|
if (mainKeyboard && mainKeyboard.active_keymap) {
|
||||||
const parts = mainKeyboard.active_keymap.split(" ")
|
const parts = mainKeyboard.active_keymap.split(" ");
|
||||||
if (parts.length > 0) {
|
if (parts.length > 0) {
|
||||||
hyprlandCurrentLayout = parts[0].substring(0, 2).toUpperCase()
|
hyprlandCurrentLayout = parts[0].substring(0, 2).toUpperCase();
|
||||||
} else {
|
} else {
|
||||||
hyprlandCurrentLayout = mainKeyboard.active_keymap.substring(0, 2).toUpperCase()
|
hyprlandCurrentLayout = mainKeyboard.active_keymap.substring(0, 2).toUpperCase();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
hyprlandCurrentLayout = ""
|
hyprlandCurrentLayout = "";
|
||||||
}
|
}
|
||||||
if (mainKeyboard && mainKeyboard.layout_names) {
|
if (mainKeyboard && mainKeyboard.layout_names) {
|
||||||
hyprlandLayoutCount = mainKeyboard.layout_names.length
|
hyprlandLayoutCount = mainKeyboard.layout_names.length;
|
||||||
} else {
|
} else {
|
||||||
hyprlandLayoutCount = 0
|
hyprlandLayoutCount = 0;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
hyprlandCurrentLayout = ""
|
hyprlandCurrentLayout = "";
|
||||||
hyprlandLayoutCount = 0
|
hyprlandLayoutCount = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,8 +154,8 @@ Item {
|
|||||||
Loader {
|
Loader {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: {
|
active: {
|
||||||
var currentWallpaper = SessionData.getMonitorWallpaper(screenName)
|
var currentWallpaper = SessionData.getMonitorWallpaper(screenName);
|
||||||
return !currentWallpaper || (currentWallpaper && currentWallpaper.startsWith("#"))
|
return !currentWallpaper || (currentWallpaper && currentWallpaper.startsWith("#"));
|
||||||
}
|
}
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
|
|
||||||
@@ -158,8 +169,8 @@ Item {
|
|||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
source: {
|
source: {
|
||||||
var currentWallpaper = SessionData.getMonitorWallpaper(screenName)
|
var currentWallpaper = SessionData.getMonitorWallpaper(screenName);
|
||||||
return (currentWallpaper && !currentWallpaper.startsWith("#")) ? currentWallpaper : ""
|
return (currentWallpaper && !currentWallpaper.startsWith("#")) ? currentWallpaper : "";
|
||||||
}
|
}
|
||||||
fillMode: Theme.getFillMode(SettingsData.wallpaperFillMode)
|
fillMode: Theme.getFillMode(SettingsData.wallpaperFillMode)
|
||||||
smooth: true
|
smooth: true
|
||||||
@@ -213,8 +224,8 @@ Item {
|
|||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
property string fullTimeStr: {
|
property string fullTimeStr: {
|
||||||
const format = SettingsData.getEffectiveTimeFormat()
|
const format = SettingsData.getEffectiveTimeFormat();
|
||||||
return systemClock.date.toLocaleTimeString(Qt.locale(), format)
|
return systemClock.date.toLocaleTimeString(Qt.locale(), format);
|
||||||
}
|
}
|
||||||
property var timeParts: fullTimeStr.split(':')
|
property var timeParts: fullTimeStr.split(':')
|
||||||
property string hours: timeParts[0] || ""
|
property string hours: timeParts[0] || ""
|
||||||
@@ -222,8 +233,8 @@ Item {
|
|||||||
property string secondsWithAmPm: timeParts.length > 2 ? timeParts[2] : ""
|
property string secondsWithAmPm: timeParts.length > 2 ? timeParts[2] : ""
|
||||||
property string seconds: secondsWithAmPm.replace(/\s*(AM|PM|am|pm)$/i, '')
|
property string seconds: secondsWithAmPm.replace(/\s*(AM|PM|am|pm)$/i, '')
|
||||||
property string ampm: {
|
property string ampm: {
|
||||||
const match = fullTimeStr.match(/\s*(AM|PM|am|pm)$/i)
|
const match = fullTimeStr.match(/\s*(AM|PM|am|pm)$/i);
|
||||||
return match ? match[0].trim() : ""
|
return match ? match[0].trim() : "";
|
||||||
}
|
}
|
||||||
property bool hasSeconds: timeParts.length > 2
|
property bool hasSeconds: timeParts.length > 2
|
||||||
|
|
||||||
@@ -322,9 +333,9 @@ Item {
|
|||||||
anchors.verticalCenterOffset: -25
|
anchors.verticalCenterOffset: -25
|
||||||
text: {
|
text: {
|
||||||
if (SettingsData.lockDateFormat && SettingsData.lockDateFormat.length > 0) {
|
if (SettingsData.lockDateFormat && SettingsData.lockDateFormat.length > 0) {
|
||||||
return systemClock.date.toLocaleDateString(Qt.locale(), SettingsData.lockDateFormat)
|
return systemClock.date.toLocaleDateString(Qt.locale(), SettingsData.lockDateFormat);
|
||||||
}
|
}
|
||||||
return systemClock.date.toLocaleDateString(Qt.locale(), Locale.LongFormat)
|
return systemClock.date.toLocaleDateString(Qt.locale(), Locale.LongFormat);
|
||||||
}
|
}
|
||||||
font.pixelSize: Theme.fontSizeXLarge
|
font.pixelSize: Theme.fontSizeXLarge
|
||||||
color: "white"
|
color: "white"
|
||||||
@@ -347,14 +358,14 @@ Item {
|
|||||||
Layout.preferredHeight: 60
|
Layout.preferredHeight: 60
|
||||||
imageSource: {
|
imageSource: {
|
||||||
if (PortalService.profileImage === "") {
|
if (PortalService.profileImage === "") {
|
||||||
return ""
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PortalService.profileImage.startsWith("/")) {
|
if (PortalService.profileImage.startsWith("/")) {
|
||||||
return "file://" + PortalService.profileImage
|
return "file://" + PortalService.profileImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PortalService.profileImage
|
return PortalService.profileImage;
|
||||||
}
|
}
|
||||||
fallbackIcon: "person"
|
fallbackIcon: "person"
|
||||||
}
|
}
|
||||||
@@ -414,20 +425,20 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: lockIconContainer.width + Theme.spacingM * 2
|
anchors.leftMargin: lockIconContainer.width + Theme.spacingM * 2
|
||||||
anchors.rightMargin: {
|
anchors.rightMargin: {
|
||||||
let margin = Theme.spacingM
|
let margin = Theme.spacingM;
|
||||||
if (loadingSpinner.visible) {
|
if (loadingSpinner.visible) {
|
||||||
margin += loadingSpinner.width
|
margin += loadingSpinner.width;
|
||||||
}
|
}
|
||||||
if (enterButton.visible) {
|
if (enterButton.visible) {
|
||||||
margin += enterButton.width + 2
|
margin += enterButton.width + 2;
|
||||||
}
|
}
|
||||||
if (virtualKeyboardButton.visible) {
|
if (virtualKeyboardButton.visible) {
|
||||||
margin += virtualKeyboardButton.width
|
margin += virtualKeyboardButton.width;
|
||||||
}
|
}
|
||||||
if (revealButton.visible) {
|
if (revealButton.visible) {
|
||||||
margin += revealButton.width
|
margin += revealButton.width;
|
||||||
}
|
}
|
||||||
return margin
|
return margin;
|
||||||
}
|
}
|
||||||
opacity: 0
|
opacity: 0
|
||||||
focus: true
|
focus: true
|
||||||
@@ -436,36 +447,36 @@ Item {
|
|||||||
echoMode: parent.showPassword ? TextInput.Normal : TextInput.Password
|
echoMode: parent.showPassword ? TextInput.Normal : TextInput.Password
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
if (!demoMode) {
|
if (!demoMode) {
|
||||||
root.passwordBuffer = text
|
root.passwordBuffer = text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
if (!demoMode && !pam.passwd.active) {
|
if (!demoMode && !pam.passwd.active) {
|
||||||
console.log("Enter pressed, starting PAM authentication")
|
console.log("Enter pressed, starting PAM authentication");
|
||||||
pam.passwd.start()
|
pam.passwd.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Keys.onPressed: event => {
|
Keys.onPressed: event => {
|
||||||
if (demoMode) {
|
if (demoMode) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pam.passwd.active) {
|
if (pam.passwd.active) {
|
||||||
console.log("PAM is active, ignoring input")
|
console.log("PAM is active, ignoring input");
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (!demoMode) {
|
if (!demoMode) {
|
||||||
forceActiveFocus()
|
forceActiveFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (visible && !demoMode) {
|
if (visible && !demoMode) {
|
||||||
forceActiveFocus()
|
forceActiveFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,9 +484,9 @@ Item {
|
|||||||
if (!activeFocus && !demoMode && visible && passwordField && !powerMenu.isVisible) {
|
if (!activeFocus && !demoMode && visible && passwordField && !powerMenu.isVisible) {
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
if (passwordField && passwordField.forceActiveFocus) {
|
if (passwordField && passwordField.forceActiveFocus) {
|
||||||
passwordField.forceActiveFocus()
|
passwordField.forceActiveFocus();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -483,9 +494,9 @@ Item {
|
|||||||
if (enabled && !demoMode && visible && passwordField && !powerMenu.isVisible) {
|
if (enabled && !demoMode && visible && passwordField && !powerMenu.isVisible) {
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
if (passwordField && passwordField.forceActiveFocus) {
|
if (passwordField && passwordField.forceActiveFocus) {
|
||||||
passwordField.forceActiveFocus()
|
passwordField.forceActiveFocus();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -506,15 +517,15 @@ Item {
|
|||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: {
|
text: {
|
||||||
if (demoMode) {
|
if (demoMode) {
|
||||||
return ""
|
return "";
|
||||||
}
|
}
|
||||||
if (root.unlocking) {
|
if (root.unlocking) {
|
||||||
return "Unlocking..."
|
return "Unlocking...";
|
||||||
}
|
}
|
||||||
if (pam.passwd.active) {
|
if (pam.passwd.active) {
|
||||||
return "Authenticating..."
|
return "Authenticating...";
|
||||||
}
|
}
|
||||||
return "Password..."
|
return "Password...";
|
||||||
}
|
}
|
||||||
color: root.unlocking ? Theme.primary : (pam.passwd.active ? Theme.primary : Theme.outline)
|
color: root.unlocking ? Theme.primary : (pam.passwd.active ? Theme.primary : Theme.outline)
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
@@ -543,12 +554,12 @@ Item {
|
|||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: {
|
text: {
|
||||||
if (demoMode) {
|
if (demoMode) {
|
||||||
return "••••••••"
|
return "••••••••";
|
||||||
}
|
}
|
||||||
if (parent.showPassword) {
|
if (parent.showPassword) {
|
||||||
return root.passwordBuffer
|
return root.passwordBuffer;
|
||||||
}
|
}
|
||||||
return "•".repeat(root.passwordBuffer.length)
|
return "•".repeat(root.passwordBuffer.length);
|
||||||
}
|
}
|
||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
font.pixelSize: parent.showPassword ? Theme.fontSizeMedium : Theme.fontSizeLarge
|
font.pixelSize: parent.showPassword ? Theme.fontSizeMedium : Theme.fontSizeLarge
|
||||||
@@ -589,9 +600,9 @@ Item {
|
|||||||
enabled: visible
|
enabled: visible
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (keyboardController.isKeyboardActive) {
|
if (keyboardController.isKeyboardActive) {
|
||||||
keyboardController.hide()
|
keyboardController.hide();
|
||||||
} else {
|
} else {
|
||||||
keyboardController.show()
|
keyboardController.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -690,8 +701,8 @@ Item {
|
|||||||
enabled: !demoMode
|
enabled: !demoMode
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (!demoMode) {
|
if (!demoMode) {
|
||||||
console.log("Enter button clicked, starting PAM authentication")
|
console.log("Enter button clicked, starting PAM authentication");
|
||||||
pam.passwd.start()
|
pam.passwd.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -717,15 +728,15 @@ Item {
|
|||||||
Layout.preferredHeight: 20
|
Layout.preferredHeight: 20
|
||||||
text: {
|
text: {
|
||||||
if (root.pamState === "error") {
|
if (root.pamState === "error") {
|
||||||
return "Authentication error - try again"
|
return "Authentication error - try again";
|
||||||
}
|
}
|
||||||
if (root.pamState === "max") {
|
if (root.pamState === "max") {
|
||||||
return "Too many attempts - locked out"
|
return "Too many attempts - locked out";
|
||||||
}
|
}
|
||||||
if (root.pamState === "fail") {
|
if (root.pamState === "fail") {
|
||||||
return "Incorrect password - try again"
|
return "Incorrect password - try again";
|
||||||
}
|
}
|
||||||
return ""
|
return "";
|
||||||
}
|
}
|
||||||
color: Theme.error
|
color: Theme.error
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
@@ -793,11 +804,11 @@ Item {
|
|||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
visible: {
|
visible: {
|
||||||
if (CompositorService.isNiri) {
|
if (CompositorService.isNiri) {
|
||||||
return NiriService.keyboardLayoutNames.length > 1
|
return NiriService.keyboardLayoutNames.length > 1;
|
||||||
} else if (CompositorService.isHyprland) {
|
} else if (CompositorService.isHyprland) {
|
||||||
return hyprlandLayoutCount > 1
|
return hyprlandLayoutCount > 1;
|
||||||
}
|
}
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
@@ -823,17 +834,18 @@ Item {
|
|||||||
StyledText {
|
StyledText {
|
||||||
text: {
|
text: {
|
||||||
if (CompositorService.isNiri) {
|
if (CompositorService.isNiri) {
|
||||||
const layout = NiriService.getCurrentKeyboardLayoutName()
|
const layout = NiriService.getCurrentKeyboardLayoutName();
|
||||||
if (!layout) return ""
|
if (!layout)
|
||||||
const parts = layout.split(" ")
|
return "";
|
||||||
|
const parts = layout.split(" ");
|
||||||
if (parts.length > 0) {
|
if (parts.length > 0) {
|
||||||
return parts[0].substring(0, 2).toUpperCase()
|
return parts[0].substring(0, 2).toUpperCase();
|
||||||
}
|
}
|
||||||
return layout.substring(0, 2).toUpperCase()
|
return layout.substring(0, 2).toUpperCase();
|
||||||
} else if (CompositorService.isHyprland) {
|
} else if (CompositorService.isHyprland) {
|
||||||
return hyprlandCurrentLayout
|
return hyprlandCurrentLayout;
|
||||||
}
|
}
|
||||||
return ""
|
return "";
|
||||||
}
|
}
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
font.weight: Font.Light
|
font.weight: Font.Light
|
||||||
@@ -851,15 +863,10 @@ Item {
|
|||||||
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (CompositorService.isNiri) {
|
if (CompositorService.isNiri) {
|
||||||
NiriService.cycleKeyboardLayout()
|
NiriService.cycleKeyboardLayout();
|
||||||
} else if (CompositorService.isHyprland) {
|
} else if (CompositorService.isHyprland) {
|
||||||
Quickshell.execDetached([
|
Quickshell.execDetached(["hyprctl", "switchxkblayout", hyprlandKeyboard, "next"]);
|
||||||
"hyprctl",
|
updateHyprlandLayout();
|
||||||
"switchxkblayout",
|
|
||||||
hyprlandKeyboard,
|
|
||||||
"next"
|
|
||||||
])
|
|
||||||
updateHyprlandLayout()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -898,7 +905,7 @@ Item {
|
|||||||
interval: 256
|
interval: 256
|
||||||
repeat: true
|
repeat: true
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
CavaService.values = [Math.random() * 40 + 10, Math.random() * 60 + 20, Math.random() * 50 + 15, Math.random() * 35 + 20, Math.random() * 45 + 15, Math.random() * 55 + 25]
|
CavaService.values = [Math.random() * 40 + 10, Math.random() * 60 + 20, Math.random() * 50 + 15, Math.random() * 35 + 20, Math.random() * 45 + 15, Math.random() * 55 + 25];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -914,13 +921,13 @@ Item {
|
|||||||
width: 2
|
width: 2
|
||||||
height: {
|
height: {
|
||||||
if (MprisController.activePlayer?.playbackState === MprisPlaybackState.Playing && CavaService.values.length > index) {
|
if (MprisController.activePlayer?.playbackState === MprisPlaybackState.Playing && CavaService.values.length > index) {
|
||||||
const rawLevel = CavaService.values[index] || 0
|
const rawLevel = CavaService.values[index] || 0;
|
||||||
const scaledLevel = Math.sqrt(Math.min(Math.max(rawLevel, 0), 100) / 100) * 100
|
const scaledLevel = Math.sqrt(Math.min(Math.max(rawLevel, 0), 100) / 100) * 100;
|
||||||
const maxHeight = Theme.iconSize - 2
|
const maxHeight = Theme.iconSize - 2;
|
||||||
const minHeight = 3
|
const minHeight = 3;
|
||||||
return minHeight + (scaledLevel / 100) * (maxHeight - minHeight)
|
return minHeight + (scaledLevel / 100) * (maxHeight - minHeight);
|
||||||
}
|
}
|
||||||
return 3
|
return 3;
|
||||||
}
|
}
|
||||||
radius: 1.5
|
radius: 1.5
|
||||||
color: "white"
|
color: "white"
|
||||||
@@ -940,11 +947,12 @@ Item {
|
|||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: {
|
text: {
|
||||||
const player = MprisController.activePlayer
|
const player = MprisController.activePlayer;
|
||||||
if (!player?.trackTitle) return ""
|
if (!player?.trackTitle)
|
||||||
const title = player.trackTitle
|
return "";
|
||||||
const artist = player.trackArtist || ""
|
const title = player.trackTitle;
|
||||||
return artist ? title + " • " + artist : title
|
const artist = player.trackArtist || "";
|
||||||
|
return artist ? title + " • " + artist : title;
|
||||||
}
|
}
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
color: "white"
|
color: "white"
|
||||||
@@ -1099,15 +1107,15 @@ Item {
|
|||||||
DankIcon {
|
DankIcon {
|
||||||
name: {
|
name: {
|
||||||
if (!AudioService.sink?.audio) {
|
if (!AudioService.sink?.audio) {
|
||||||
return "volume_up"
|
return "volume_up";
|
||||||
}
|
}
|
||||||
if (AudioService.sink.audio.muted || AudioService.sink.audio.volume === 0) {
|
if (AudioService.sink.audio.muted || AudioService.sink.audio.volume === 0) {
|
||||||
return "volume_off"
|
return "volume_off";
|
||||||
}
|
}
|
||||||
if (AudioService.sink.audio.volume * 100 < 33) {
|
if (AudioService.sink.audio.volume * 100 < 33) {
|
||||||
return "volume_down"
|
return "volume_down";
|
||||||
}
|
}
|
||||||
return "volume_up"
|
return "volume_up";
|
||||||
}
|
}
|
||||||
size: Theme.iconSize - 2
|
size: Theme.iconSize - 2
|
||||||
color: (AudioService.sink && AudioService.sink.audio && (AudioService.sink.audio.muted || AudioService.sink.audio.volume === 0)) ? Qt.rgba(255, 255, 255, 0.5) : "white"
|
color: (AudioService.sink && AudioService.sink.audio && (AudioService.sink.audio.muted || AudioService.sink.audio.volume === 0)) ? Qt.rgba(255, 255, 255, 0.5) : "white"
|
||||||
@@ -1133,95 +1141,95 @@ Item {
|
|||||||
name: {
|
name: {
|
||||||
if (BatteryService.isCharging) {
|
if (BatteryService.isCharging) {
|
||||||
if (BatteryService.batteryLevel >= 90) {
|
if (BatteryService.batteryLevel >= 90) {
|
||||||
return "battery_charging_full"
|
return "battery_charging_full";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BatteryService.batteryLevel >= 80) {
|
if (BatteryService.batteryLevel >= 80) {
|
||||||
return "battery_charging_90"
|
return "battery_charging_90";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BatteryService.batteryLevel >= 60) {
|
if (BatteryService.batteryLevel >= 60) {
|
||||||
return "battery_charging_80"
|
return "battery_charging_80";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BatteryService.batteryLevel >= 50) {
|
if (BatteryService.batteryLevel >= 50) {
|
||||||
return "battery_charging_60"
|
return "battery_charging_60";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BatteryService.batteryLevel >= 30) {
|
if (BatteryService.batteryLevel >= 30) {
|
||||||
return "battery_charging_50"
|
return "battery_charging_50";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BatteryService.batteryLevel >= 20) {
|
if (BatteryService.batteryLevel >= 20) {
|
||||||
return "battery_charging_30"
|
return "battery_charging_30";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "battery_charging_20"
|
return "battery_charging_20";
|
||||||
}
|
}
|
||||||
if (BatteryService.isPluggedIn) {
|
if (BatteryService.isPluggedIn) {
|
||||||
if (BatteryService.batteryLevel >= 90) {
|
if (BatteryService.batteryLevel >= 90) {
|
||||||
return "battery_charging_full"
|
return "battery_charging_full";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BatteryService.batteryLevel >= 80) {
|
if (BatteryService.batteryLevel >= 80) {
|
||||||
return "battery_charging_90"
|
return "battery_charging_90";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BatteryService.batteryLevel >= 60) {
|
if (BatteryService.batteryLevel >= 60) {
|
||||||
return "battery_charging_80"
|
return "battery_charging_80";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BatteryService.batteryLevel >= 50) {
|
if (BatteryService.batteryLevel >= 50) {
|
||||||
return "battery_charging_60"
|
return "battery_charging_60";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BatteryService.batteryLevel >= 30) {
|
if (BatteryService.batteryLevel >= 30) {
|
||||||
return "battery_charging_50"
|
return "battery_charging_50";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BatteryService.batteryLevel >= 20) {
|
if (BatteryService.batteryLevel >= 20) {
|
||||||
return "battery_charging_30"
|
return "battery_charging_30";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "battery_charging_20"
|
return "battery_charging_20";
|
||||||
}
|
}
|
||||||
if (BatteryService.batteryLevel >= 95) {
|
if (BatteryService.batteryLevel >= 95) {
|
||||||
return "battery_full"
|
return "battery_full";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BatteryService.batteryLevel >= 85) {
|
if (BatteryService.batteryLevel >= 85) {
|
||||||
return "battery_6_bar"
|
return "battery_6_bar";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BatteryService.batteryLevel >= 70) {
|
if (BatteryService.batteryLevel >= 70) {
|
||||||
return "battery_5_bar"
|
return "battery_5_bar";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BatteryService.batteryLevel >= 55) {
|
if (BatteryService.batteryLevel >= 55) {
|
||||||
return "battery_4_bar"
|
return "battery_4_bar";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BatteryService.batteryLevel >= 40) {
|
if (BatteryService.batteryLevel >= 40) {
|
||||||
return "battery_3_bar"
|
return "battery_3_bar";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BatteryService.batteryLevel >= 25) {
|
if (BatteryService.batteryLevel >= 25) {
|
||||||
return "battery_2_bar"
|
return "battery_2_bar";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "battery_1_bar"
|
return "battery_1_bar";
|
||||||
}
|
}
|
||||||
size: Theme.iconSize
|
size: Theme.iconSize
|
||||||
color: {
|
color: {
|
||||||
if (BatteryService.isLowBattery && !BatteryService.isCharging) {
|
if (BatteryService.isLowBattery && !BatteryService.isCharging) {
|
||||||
return Theme.error
|
return Theme.error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BatteryService.isCharging || BatteryService.isPluggedIn) {
|
if (BatteryService.isCharging || BatteryService.isPluggedIn) {
|
||||||
return Theme.primary
|
return Theme.primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "white"
|
return "white";
|
||||||
}
|
}
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
@@ -1246,9 +1254,9 @@ Item {
|
|||||||
buttonSize: 40
|
buttonSize: 40
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (demoMode) {
|
if (demoMode) {
|
||||||
console.log("Demo: Power Menu")
|
console.log("Demo: Power Menu");
|
||||||
} else {
|
} else {
|
||||||
powerMenu.show()
|
powerMenu.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1272,18 +1280,18 @@ Item {
|
|||||||
id: pam
|
id: pam
|
||||||
lockSecured: !demoMode
|
lockSecured: !demoMode
|
||||||
onUnlockRequested: {
|
onUnlockRequested: {
|
||||||
root.unlocking = true
|
root.unlocking = true;
|
||||||
lockerReadyArmed = false
|
lockerReadyArmed = false;
|
||||||
passwordField.text = ""
|
passwordField.text = "";
|
||||||
root.passwordBuffer = ""
|
root.passwordBuffer = "";
|
||||||
root.unlockRequested()
|
root.unlockRequested();
|
||||||
}
|
}
|
||||||
onStateChanged: {
|
onStateChanged: {
|
||||||
root.pamState = state
|
root.pamState = state;
|
||||||
if (state !== "") {
|
if (state !== "") {
|
||||||
placeholderDelay.restart()
|
placeholderDelay.restart();
|
||||||
passwordField.text = ""
|
passwordField.text = "";
|
||||||
root.passwordBuffer = ""
|
root.passwordBuffer = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1312,7 +1320,7 @@ Item {
|
|||||||
showLogout: true
|
showLogout: true
|
||||||
onClosed: {
|
onClosed: {
|
||||||
if (!demoMode && passwordField && passwordField.forceActiveFocus) {
|
if (!demoMode && passwordField && passwordField.forceActiveFocus) {
|
||||||
Qt.callLater(() => passwordField.forceActiveFocus())
|
Qt.callLater(() => passwordField.forceActiveFocus());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import qs.Common
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: root
|
id: root
|
||||||
@@ -14,7 +12,7 @@ Rectangle {
|
|||||||
required property bool isLocked
|
required property bool isLocked
|
||||||
|
|
||||||
signal passwordChanged(string newPassword)
|
signal passwordChanged(string newPassword)
|
||||||
signal unlockRequested()
|
signal unlockRequested
|
||||||
|
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
@@ -28,14 +26,14 @@ Rectangle {
|
|||||||
onUnlockRequested: root.unlockRequested()
|
onUnlockRequested: root.unlockRequested()
|
||||||
onPasswordBufferChanged: {
|
onPasswordBufferChanged: {
|
||||||
if (root.sharedPasswordBuffer !== passwordBuffer) {
|
if (root.sharedPasswordBuffer !== passwordBuffer) {
|
||||||
root.passwordChanged(passwordBuffer)
|
root.passwordChanged(passwordBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onIsLockedChanged: {
|
onIsLockedChanged: {
|
||||||
if (!isLocked) {
|
if (!isLocked) {
|
||||||
lockContent.unlocking = false
|
lockContent.unlocking = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,26 +4,24 @@ pragma ComponentBehavior: Bound
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import Quickshell.Services.Mpris
|
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Services
|
|
||||||
|
|
||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
readonly property bool idleMonitorAvailable: {
|
readonly property bool idleMonitorAvailable: {
|
||||||
try {
|
try {
|
||||||
return typeof IdleMonitor !== "undefined"
|
return typeof IdleMonitor !== "undefined";
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property bool idleInhibitorAvailable: {
|
readonly property bool idleInhibitorAvailable: {
|
||||||
try {
|
try {
|
||||||
return typeof IdleInhibitor !== "undefined"
|
return typeof IdleInhibitor !== "undefined";
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,32 +42,37 @@ Singleton {
|
|||||||
onSuspendTimeoutChanged: _rearmIdleMonitors()
|
onSuspendTimeoutChanged: _rearmIdleMonitors()
|
||||||
|
|
||||||
function _rearmIdleMonitors() {
|
function _rearmIdleMonitors() {
|
||||||
_enableGate = false
|
_enableGate = false;
|
||||||
Qt.callLater(() => { _enableGate = true })
|
Qt.callLater(() => {
|
||||||
|
_enableGate = true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
signal lockRequested()
|
signal lockRequested
|
||||||
signal requestMonitorOff()
|
signal fadeToLockRequested
|
||||||
signal requestMonitorOn()
|
signal cancelFadeToLock
|
||||||
signal requestSuspend()
|
signal requestMonitorOff
|
||||||
|
signal requestMonitorOn
|
||||||
|
signal requestSuspend
|
||||||
|
|
||||||
property var monitorOffMonitor: null
|
property var monitorOffMonitor: null
|
||||||
property var lockMonitor: null
|
property var lockMonitor: null
|
||||||
property var suspendMonitor: null
|
property var suspendMonitor: null
|
||||||
property var mediaInhibitor: null
|
property var mediaInhibitor: null
|
||||||
|
property var lockComponent: null
|
||||||
|
|
||||||
function wake() {
|
function wake() {
|
||||||
requestMonitorOn()
|
requestMonitorOn();
|
||||||
}
|
}
|
||||||
|
|
||||||
function createMediaInhibitor() {
|
function createMediaInhibitor() {
|
||||||
if (!idleInhibitorAvailable) {
|
if (!idleInhibitorAvailable) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mediaInhibitor) {
|
if (mediaInhibitor) {
|
||||||
mediaInhibitor.destroy()
|
mediaInhibitor.destroy();
|
||||||
mediaInhibitor = null
|
mediaInhibitor = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const inhibitorString = `
|
const inhibitorString = `
|
||||||
@@ -79,23 +82,23 @@ Singleton {
|
|||||||
IdleInhibitor {
|
IdleInhibitor {
|
||||||
active: false
|
active: false
|
||||||
}
|
}
|
||||||
`
|
`;
|
||||||
|
|
||||||
mediaInhibitor = Qt.createQmlObject(inhibitorString, root, "IdleService.MediaInhibitor")
|
mediaInhibitor = Qt.createQmlObject(inhibitorString, root, "IdleService.MediaInhibitor");
|
||||||
mediaInhibitor.active = Qt.binding(() => root.mediaPlaying)
|
mediaInhibitor.active = Qt.binding(() => root.mediaPlaying);
|
||||||
}
|
}
|
||||||
|
|
||||||
function destroyMediaInhibitor() {
|
function destroyMediaInhibitor() {
|
||||||
if (mediaInhibitor) {
|
if (mediaInhibitor) {
|
||||||
mediaInhibitor.destroy()
|
mediaInhibitor.destroy();
|
||||||
mediaInhibitor = null
|
mediaInhibitor = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createIdleMonitors() {
|
function createIdleMonitors() {
|
||||||
if (!idleMonitorAvailable) {
|
if (!idleMonitorAvailable) {
|
||||||
console.info("IdleService: IdleMonitor not available, skipping creation")
|
console.info("IdleService: IdleMonitor not available, skipping creation");
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -108,60 +111,68 @@ Singleton {
|
|||||||
respectInhibitors: true
|
respectInhibitors: true
|
||||||
timeout: 0
|
timeout: 0
|
||||||
}
|
}
|
||||||
`
|
`;
|
||||||
|
|
||||||
monitorOffMonitor = Qt.createQmlObject(qmlString, root, "IdleService.MonitorOffMonitor")
|
monitorOffMonitor = Qt.createQmlObject(qmlString, root, "IdleService.MonitorOffMonitor");
|
||||||
monitorOffMonitor.enabled = Qt.binding(() => root._enableGate && root.enabled && root.idleMonitorAvailable && root.monitorTimeout > 0)
|
monitorOffMonitor.enabled = Qt.binding(() => root._enableGate && root.enabled && root.idleMonitorAvailable && root.monitorTimeout > 0);
|
||||||
monitorOffMonitor.respectInhibitors = Qt.binding(() => root.respectInhibitors)
|
monitorOffMonitor.respectInhibitors = Qt.binding(() => root.respectInhibitors);
|
||||||
monitorOffMonitor.timeout = Qt.binding(() => root.monitorTimeout)
|
monitorOffMonitor.timeout = Qt.binding(() => root.monitorTimeout);
|
||||||
monitorOffMonitor.isIdleChanged.connect(function() {
|
monitorOffMonitor.isIdleChanged.connect(function () {
|
||||||
if (monitorOffMonitor.isIdle) {
|
if (monitorOffMonitor.isIdle) {
|
||||||
root.requestMonitorOff()
|
root.requestMonitorOff();
|
||||||
} else {
|
} else {
|
||||||
root.requestMonitorOn()
|
root.requestMonitorOn();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
lockMonitor = Qt.createQmlObject(qmlString, root, "IdleService.LockMonitor")
|
lockMonitor = Qt.createQmlObject(qmlString, root, "IdleService.LockMonitor");
|
||||||
lockMonitor.enabled = Qt.binding(() => root._enableGate && root.enabled && root.idleMonitorAvailable && root.lockTimeout > 0)
|
lockMonitor.enabled = Qt.binding(() => root._enableGate && root.enabled && root.idleMonitorAvailable && root.lockTimeout > 0);
|
||||||
lockMonitor.respectInhibitors = Qt.binding(() => root.respectInhibitors)
|
lockMonitor.respectInhibitors = Qt.binding(() => root.respectInhibitors);
|
||||||
lockMonitor.timeout = Qt.binding(() => root.lockTimeout)
|
lockMonitor.timeout = Qt.binding(() => root.lockTimeout);
|
||||||
lockMonitor.isIdleChanged.connect(function() {
|
lockMonitor.isIdleChanged.connect(function () {
|
||||||
if (lockMonitor.isIdle) {
|
if (lockMonitor.isIdle) {
|
||||||
root.lockRequested()
|
if (SettingsData.fadeToLockEnabled) {
|
||||||
|
root.fadeToLockRequested();
|
||||||
|
} else {
|
||||||
|
root.lockRequested();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (SettingsData.fadeToLockEnabled) {
|
||||||
|
root.cancelFadeToLock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
suspendMonitor = Qt.createQmlObject(qmlString, root, "IdleService.SuspendMonitor")
|
suspendMonitor = Qt.createQmlObject(qmlString, root, "IdleService.SuspendMonitor");
|
||||||
suspendMonitor.enabled = Qt.binding(() => root._enableGate && root.enabled && root.idleMonitorAvailable && root.suspendTimeout > 0)
|
suspendMonitor.enabled = Qt.binding(() => root._enableGate && root.enabled && root.idleMonitorAvailable && root.suspendTimeout > 0);
|
||||||
suspendMonitor.respectInhibitors = Qt.binding(() => root.respectInhibitors)
|
suspendMonitor.respectInhibitors = Qt.binding(() => root.respectInhibitors);
|
||||||
suspendMonitor.timeout = Qt.binding(() => root.suspendTimeout)
|
suspendMonitor.timeout = Qt.binding(() => root.suspendTimeout);
|
||||||
suspendMonitor.isIdleChanged.connect(function() {
|
suspendMonitor.isIdleChanged.connect(function () {
|
||||||
if (suspendMonitor.isIdle) {
|
if (suspendMonitor.isIdle) {
|
||||||
root.requestSuspend()
|
root.requestSuspend();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
if (SettingsData.preventIdleForMedia) {
|
if (SettingsData.preventIdleForMedia) {
|
||||||
createMediaInhibitor()
|
createMediaInhibitor();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("IdleService: Error creating IdleMonitors:", e)
|
console.warn("IdleService: Error creating IdleMonitors:", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: root
|
target: root
|
||||||
function onRequestMonitorOff() {
|
function onRequestMonitorOff() {
|
||||||
CompositorService.powerOffMonitors()
|
CompositorService.powerOffMonitors();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onRequestMonitorOn() {
|
function onRequestMonitorOn() {
|
||||||
CompositorService.powerOnMonitors()
|
CompositorService.powerOnMonitors();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onRequestSuspend() {
|
function onRequestSuspend() {
|
||||||
SessionService.suspendWithBehavior(root.suspendBehavior)
|
SessionService.suspendWithBehavior(root.suspendBehavior);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +180,7 @@ Singleton {
|
|||||||
target: SessionService
|
target: SessionService
|
||||||
function onPrepareForSleep() {
|
function onPrepareForSleep() {
|
||||||
if (SettingsData.lockBeforeSuspend) {
|
if (SettingsData.lockBeforeSuspend) {
|
||||||
root.lockRequested()
|
root.lockRequested();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,19 +189,19 @@ Singleton {
|
|||||||
target: SettingsData
|
target: SettingsData
|
||||||
function onPreventIdleForMediaChanged() {
|
function onPreventIdleForMediaChanged() {
|
||||||
if (SettingsData.preventIdleForMedia) {
|
if (SettingsData.preventIdleForMedia) {
|
||||||
createMediaInhibitor()
|
createMediaInhibitor();
|
||||||
} else {
|
} else {
|
||||||
destroyMediaInhibitor()
|
destroyMediaInhibitor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (!idleMonitorAvailable) {
|
if (!idleMonitorAvailable) {
|
||||||
console.warn("IdleService: IdleMonitor not available - power management disabled. This requires a newer version of Quickshell.")
|
console.warn("IdleService: IdleMonitor not available - power management disabled. This requires a newer version of Quickshell.");
|
||||||
} else {
|
} else {
|
||||||
console.info("IdleService: Initialized with idle monitoring support")
|
console.info("IdleService: Initialized with idle monitoring support");
|
||||||
createIdleMonitors()
|
createIdleMonitors();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user