diff --git a/Common/SessionData.qml b/Common/SessionData.qml index b945ed63..03349296 100644 --- a/Common/SessionData.qml +++ b/Common/SessionData.qml @@ -45,6 +45,18 @@ Singleton { property string wallpaperCyclingTime: "06:00" // HH:mm format property string lastBrightnessDevice: "" + // Power management settings - AC Power + property int acMonitorTimeout: 0 // Never + property int acLockTimeout: 0 // Never + property int acSuspendTimeout: 0 // Never + property int acHibernateTimeout: 0 // Never + + // Power management settings - Battery + property int batteryMonitorTimeout: 0 // Never + property int batteryLockTimeout: 0 // Never + property int batterySuspendTimeout: 0 // Never + property int batteryHibernateTimeout: 0 // Never + Component.onCompleted: { loadSettings() } @@ -98,6 +110,15 @@ Singleton { wallpaperCyclingInterval = settings.wallpaperCyclingInterval !== undefined ? settings.wallpaperCyclingInterval : 300 wallpaperCyclingTime = settings.wallpaperCyclingTime !== undefined ? settings.wallpaperCyclingTime : "06:00" lastBrightnessDevice = settings.lastBrightnessDevice !== undefined ? settings.lastBrightnessDevice : "" + + acMonitorTimeout = settings.acMonitorTimeout !== undefined ? settings.acMonitorTimeout : 0 + acLockTimeout = settings.acLockTimeout !== undefined ? settings.acLockTimeout : 0 + acSuspendTimeout = settings.acSuspendTimeout !== undefined ? settings.acSuspendTimeout : 0 + acHibernateTimeout = settings.acHibernateTimeout !== undefined ? settings.acHibernateTimeout : 0 + batteryMonitorTimeout = settings.batteryMonitorTimeout !== undefined ? settings.batteryMonitorTimeout : 0 + batteryLockTimeout = settings.batteryLockTimeout !== undefined ? settings.batteryLockTimeout : 0 + batterySuspendTimeout = settings.batterySuspendTimeout !== undefined ? settings.batterySuspendTimeout : 0 + batteryHibernateTimeout = settings.batteryHibernateTimeout !== undefined ? settings.batteryHibernateTimeout : 0 // Generate system themes but don't override user's theme choice if (typeof Theme !== "undefined") { @@ -138,7 +159,15 @@ Singleton { "wallpaperCyclingMode": wallpaperCyclingMode, "wallpaperCyclingInterval": wallpaperCyclingInterval, "wallpaperCyclingTime": wallpaperCyclingTime, - "lastBrightnessDevice": lastBrightnessDevice + "lastBrightnessDevice": lastBrightnessDevice, + "acMonitorTimeout": acMonitorTimeout, + "acLockTimeout": acLockTimeout, + "acSuspendTimeout": acSuspendTimeout, + "acHibernateTimeout": acHibernateTimeout, + "batteryMonitorTimeout": batteryMonitorTimeout, + "batteryLockTimeout": batteryLockTimeout, + "batterySuspendTimeout": batterySuspendTimeout, + "batteryHibernateTimeout": batteryHibernateTimeout }, null, 2)) } @@ -380,6 +409,46 @@ Singleton { saveSettings() } + function setAcMonitorTimeout(timeout) { + acMonitorTimeout = timeout + saveSettings() + } + + function setAcLockTimeout(timeout) { + acLockTimeout = timeout + saveSettings() + } + + function setAcSuspendTimeout(timeout) { + acSuspendTimeout = timeout + saveSettings() + } + + function setBatteryMonitorTimeout(timeout) { + batteryMonitorTimeout = timeout + saveSettings() + } + + function setBatteryLockTimeout(timeout) { + batteryLockTimeout = timeout + saveSettings() + } + + function setBatterySuspendTimeout(timeout) { + batterySuspendTimeout = timeout + saveSettings() + } + + function setAcHibernateTimeout(timeout) { + acHibernateTimeout = timeout + saveSettings() + } + + function setBatteryHibernateTimeout(timeout) { + batteryHibernateTimeout = timeout + saveSettings() + } + FileView { id: settingsFile diff --git a/Modals/Settings/PowerSettings.qml b/Modals/Settings/PowerSettings.qml new file mode 100644 index 00000000..b7d21410 --- /dev/null +++ b/Modals/Settings/PowerSettings.qml @@ -0,0 +1,237 @@ +import QtQuick +import qs.Common +import qs.Services +import qs.Widgets + +Item { + id: powerTab + + DankFlickable { + anchors.fill: parent + anchors.topMargin: Theme.spacingL + clip: true + contentHeight: mainColumn.height + contentWidth: width + + Column { + id: mainColumn + width: parent.width + spacing: Theme.spacingXL + + StyledText { + text: "Battery not detected - only AC power settings available" + font.pixelSize: Theme.fontSizeMedium + color: Theme.surfaceVariantText + visible: !BatteryService.batteryAvailable + } + + StyledRect { + width: parent.width + height: timeoutSection.implicitHeight + Theme.spacingL * 2 + radius: Theme.cornerRadius + color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3) + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2) + border.width: 1 + + Column { + id: timeoutSection + anchors.fill: parent + anchors.margins: Theme.spacingL + spacing: Theme.spacingM + + Row { + width: parent.width + spacing: Theme.spacingM + + DankIcon { + name: "schedule" + size: Theme.iconSize + color: Theme.primary + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: "Idle Settings" + font.pixelSize: Theme.fontSizeLarge + font.weight: Font.Medium + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + Item { + width: Math.max(0, parent.width - parent.children[0].width - parent.children[1].width - powerCategory.width - Theme.spacingM * 3) + height: parent.height + } + + DankButtonGroup { + id: powerCategory + anchors.verticalCenter: parent.verticalCenter + visible: BatteryService.batteryAvailable + model: ["AC Power", "Battery"] + currentIndex: 0 + selectionMode: "single" + } + } + + DankDropdown { + 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 timeoutValues: [0, 60, 120, 180, 300, 600, 900, 1200, 1800, 3600, 5400, 7200, 10800] + + width: parent.width + text: "Automatically lock after" + options: timeoutOptions + + Connections { + target: powerCategory + function onCurrentIndexChanged() { + const currentTimeout = powerCategory.currentIndex === 0 ? SessionData.acLockTimeout : SessionData.batteryLockTimeout + const index = lockDropdown.timeoutValues.indexOf(currentTimeout) + lockDropdown.currentValue = index >= 0 ? lockDropdown.timeoutOptions[index] : "Never" + } + } + + Component.onCompleted: { + const currentTimeout = powerCategory.currentIndex === 0 ? SessionData.acLockTimeout : SessionData.batteryLockTimeout + const index = timeoutValues.indexOf(currentTimeout) + currentValue = index >= 0 ? timeoutOptions[index] : "Never" + } + + onValueChanged: value => { + const index = timeoutOptions.indexOf(value) + if (index >= 0) { + const timeout = timeoutValues[index] + if (powerCategory.currentIndex === 0) { + SessionData.setAcLockTimeout(timeout) + } else { + SessionData.setBatteryLockTimeout(timeout) + } + } + } + } + + DankDropdown { + id: monitorDropdown + 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 timeoutValues: [0, 60, 120, 180, 300, 600, 900, 1200, 1800, 3600, 5400, 7200, 10800] + + width: parent.width + text: "Turn off monitors after" + options: timeoutOptions + + Connections { + target: powerCategory + function onCurrentIndexChanged() { + const currentTimeout = powerCategory.currentIndex === 0 ? SessionData.acMonitorTimeout : SessionData.batteryMonitorTimeout + const index = monitorDropdown.timeoutValues.indexOf(currentTimeout) + monitorDropdown.currentValue = index >= 0 ? monitorDropdown.timeoutOptions[index] : "Never" + } + } + + Component.onCompleted: { + const currentTimeout = powerCategory.currentIndex === 0 ? SessionData.acMonitorTimeout : SessionData.batteryMonitorTimeout + const index = timeoutValues.indexOf(currentTimeout) + currentValue = index >= 0 ? timeoutOptions[index] : "Never" + } + + onValueChanged: value => { + const index = timeoutOptions.indexOf(value) + if (index >= 0) { + const timeout = timeoutValues[index] + if (powerCategory.currentIndex === 0) { + SessionData.setAcMonitorTimeout(timeout) + } else { + SessionData.setBatteryMonitorTimeout(timeout) + } + } + } + } + + DankDropdown { + id: suspendDropdown + 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 timeoutValues: [0, 60, 120, 180, 300, 600, 900, 1200, 1800, 3600, 5400, 7200, 10800] + + width: parent.width + text: "Suspend system after" + options: timeoutOptions + + Connections { + target: powerCategory + function onCurrentIndexChanged() { + const currentTimeout = powerCategory.currentIndex === 0 ? SessionData.acSuspendTimeout : SessionData.batterySuspendTimeout + const index = suspendDropdown.timeoutValues.indexOf(currentTimeout) + suspendDropdown.currentValue = index >= 0 ? suspendDropdown.timeoutOptions[index] : "Never" + } + } + + Component.onCompleted: { + const currentTimeout = powerCategory.currentIndex === 0 ? SessionData.acSuspendTimeout : SessionData.batterySuspendTimeout + const index = timeoutValues.indexOf(currentTimeout) + currentValue = index >= 0 ? timeoutOptions[index] : "Never" + } + + onValueChanged: value => { + const index = timeoutOptions.indexOf(value) + if (index >= 0) { + const timeout = timeoutValues[index] + if (powerCategory.currentIndex === 0) { + SessionData.setAcSuspendTimeout(timeout) + } else { + SessionData.setBatterySuspendTimeout(timeout) + } + } + } + } + + DankDropdown { + id: hibernateDropdown + 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 timeoutValues: [0, 60, 120, 180, 300, 600, 900, 1200, 1800, 3600, 5400, 7200, 10800] + + width: parent.width + text: "Hibernate system after" + description: "Requires swap space or a hibernation file" + options: timeoutOptions + + Connections { + target: powerCategory + function onCurrentIndexChanged() { + const currentTimeout = powerCategory.currentIndex === 0 ? SessionData.acHibernateTimeout : SessionData.batteryHibernateTimeout + const index = hibernateDropdown.timeoutValues.indexOf(currentTimeout) + hibernateDropdown.currentValue = index >= 0 ? hibernateDropdown.timeoutOptions[index] : "Never" + } + } + + Component.onCompleted: { + const currentTimeout = powerCategory.currentIndex === 0 ? SessionData.acHibernateTimeout : SessionData.batteryHibernateTimeout + const index = timeoutValues.indexOf(currentTimeout) + currentValue = index >= 0 ? timeoutOptions[index] : "Never" + } + + onValueChanged: value => { + const index = timeoutOptions.indexOf(value) + if (index >= 0) { + const timeout = timeoutValues[index] + if (powerCategory.currentIndex === 0) { + SessionData.setAcHibernateTimeout(timeout) + } else { + SessionData.setBatteryHibernateTimeout(timeout) + } + } + } + } + + StyledText { + text: "Idle monitoring not supported - requires newer Quickshell version" + font.pixelSize: Theme.fontSizeSmall + color: Theme.error + anchors.horizontalCenter: parent.horizontalCenter + visible: !IdleService.idleMonitorAvailable + } + } + } + + } + } +} \ No newline at end of file diff --git a/Modals/Settings/SettingsContent.qml b/Modals/Settings/SettingsContent.qml index 886dccea..df4371a4 100644 --- a/Modals/Settings/SettingsContent.qml +++ b/Modals/Settings/SettingsContent.qml @@ -141,13 +141,26 @@ Item { } Loader { - id: aboutLoader + id: powerLoader anchors.fill: parent active: root.currentIndex === 9 visible: active asynchronous: true + sourceComponent: PowerSettings { + } + + } + + Loader { + id: aboutLoader + + anchors.fill: parent + active: root.currentIndex === 10 + visible: active + asynchronous: true + sourceComponent: AboutTab { } diff --git a/Modals/Settings/SettingsSidebar.qml b/Modals/Settings/SettingsSidebar.qml index 6b7660c6..3e39e053 100644 --- a/Modals/Settings/SettingsSidebar.qml +++ b/Modals/Settings/SettingsSidebar.qml @@ -35,6 +35,9 @@ Rectangle { }, { "text": "Theme & Colors", "icon": "palette" + }, { + "text": "Power", + "icon": "power_settings_new" }, { "text": "About", "icon": "info" diff --git a/Modules/Lock/Lock.qml b/Modules/Lock/Lock.qml index dbfd1684..ab515ed6 100644 --- a/Modules/Lock/Lock.qml +++ b/Modules/Lock/Lock.qml @@ -18,6 +18,14 @@ Item { getSessionPath.running = true } + Connections { + target: IdleService + function onLockRequested() { + console.log("Lock: Received lock request from IdleService") + activate() + } + } + Process { id: getSessionPath command: ["gdbus", "call", "--system", "--dest", "org.freedesktop.login1", "--object-path", "/org/freedesktop/login1", "--method", "org.freedesktop.login1.Manager.GetSession", sid] diff --git a/README.md b/README.md index 0171161a..a17e36f0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # DankMaterialShell (dms) +*Replace your Waybars, Fuzzels, Swayidles, and Swaylocks with a single Dank shell*