aurora3f48e66
aurora: auto power profile on AC/battery
+73 −14
5 files changed
- M .config/quickshell/aurora/Battery.qml +31 −3
- M .config/quickshell/aurora/SetPower.qml +20 −4
- M .config/quickshell/aurora/Settings.qml +7 −1
- M .config/quickshell/aurora/SysPage.qml +14 −6
- M .config/quickshell/aurora/Theme.qml +1 −0
| @@ -20,7 +20,7 @@ Singleton { | |||
| 20 | 20 | readonly property bool ready: path !== "" | |
| 21 | 21 | // UPower reports 0% for a moment at startup: no decisions before this | |
| 22 | 22 | property bool started: false | |
| 23 | − | Timer { interval: 4000; running: true; onTriggered: { root.started = true; root.evaluate(); root.checkLow() } } | |
| 23 | + | Timer { interval: 4000; running: true; onTriggered: { root.started = true; root.evaluate(); root.checkLow(); root.applyAuto() } } | |
| 24 | 24 | ||
| 25 | 25 | readonly property var bat: UPower.displayDevice | |
| 26 | 26 | readonly property bool hasBat: bat !== null && bat.isPresent | |
| @@ -48,7 +48,7 @@ Singleton { | |||
| 48 | 48 | } | |
| 49 | 49 | ||
| 50 | 50 | onPctChanged: checkLow() | |
| 51 | − | onOnAcChanged: checkLow() | |
| 51 | + | onOnAcChanged: { checkLow(); applyAuto() } | |
| 52 | 52 | Connections { | |
| 53 | 53 | target: Settings | |
| 54 | 54 | function onChargeModeChanged() { root.evaluate() } | |
| @@ -101,7 +101,35 @@ Singleton { | |||
| 101 | 101 | command: ["busctl", "--system", "status", "org.freedesktop.UPower.PowerProfiles"] | |
| 102 | 102 | running: true | |
| 103 | 103 | stdout: StdioCollector {} | |
| 104 | − | onExited: code => root.hasProfiles = code === 0 | |
| 104 | + | onExited: code => { root.hasProfiles = code === 0; root.applyAuto() } | |
| 105 | + | } | |
| 106 | + | ||
| 107 | + | // ---- power profile: saver | balanced | performance (set in ppd, which remembers it), or auto = | |
| 108 | + | // Settings.powerAc / powerBat, switched when the power source changes | |
| 109 | + | readonly property string profile: Settings.powerAuto ? "auto" : nameOf(PowerProfiles.profile) | |
| 110 | + | function nameOf(p) { | |
| 111 | + | return p === PowerProfile.PowerSaver ? "saver" : p === PowerProfile.Performance ? "performance" : "balanced" | |
| 112 | + | } | |
| 113 | + | function profileOf(name) { | |
| 114 | + | if (name === "saver") return PowerProfile.PowerSaver | |
| 115 | + | if (name === "performance" && PowerProfiles.hasPerformanceProfile) return PowerProfile.Performance | |
| 116 | + | return PowerProfile.Balanced | |
| 117 | + | } | |
| 118 | + | function setProfile(name) { | |
| 119 | + | Settings.powerAuto = name === "auto" | |
| 120 | + | if (name === "auto") applyAuto() | |
| 121 | + | else PowerProfiles.profile = profileOf(name) | |
| 122 | + | } | |
| 123 | + | function applyAuto() { | |
| 124 | + | if (!started || !hasProfiles || !Settings.powerAuto) return | |
| 125 | + | var p = profileOf(onAc ? Settings.powerAc : Settings.powerBat) | |
| 126 | + | if (PowerProfiles.profile !== p) PowerProfiles.profile = p | |
| 127 | + | } | |
| 128 | + | Connections { | |
| 129 | + | target: Settings | |
| 130 | + | function onPowerAutoChanged() { root.applyAuto() } | |
| 131 | + | function onPowerAcChanged() { root.applyAuto() } | |
| 132 | + | function onPowerBatChanged() { root.applyAuto() } | |
| 105 | 133 | } | |
| 106 | 134 | ||
| 107 | 135 | // ---- low battery: one warning per level per discharge, then the critical action after 60s | |
| @@ -10,6 +10,9 @@ Flickable { | |||
| 10 | 10 | contentHeight: col.implicitHeight | |
| 11 | 11 | boundsBehavior: Flickable.StopAtBounds | |
| 12 | 12 | ||
| 13 | + | readonly property var profiles: [{ value: "saver", label: "saver" }, { value: "balanced", label: "balanced" }] | |
| 14 | + | .concat(PowerProfiles.hasPerformanceProfile ? [{ value: "performance", label: "performance" }] : []) | |
| 15 | + | ||
| 13 | 16 | // seconds -> "2m 30s" / "never" | |
| 14 | 17 | function dur(s) { | |
| 15 | 18 | if (s <= 0) return "never" | |
| @@ -105,10 +108,23 @@ Flickable { | |||
| 105 | 108 | Layout.topMargin: 6 | |
| 106 | 109 | visible: Battery.hasProfiles | |
| 107 | 110 | label: "power profile" | |
| 108 | − | options: [{ value: PowerProfile.PowerSaver, label: "saver" }, { value: PowerProfile.Balanced, label: "balanced" }] | |
| 109 | − | .concat(PowerProfiles.hasPerformanceProfile ? [{ value: PowerProfile.Performance, label: "performance" }] : []) | |
| 110 | − | value: PowerProfiles.profile | |
| 111 | − | onPicked: v => PowerProfiles.profile = v | |
| 111 | + | options: flick.profiles.concat(Battery.hasBat ? [{ value: "auto", label: "auto" }] : []) | |
| 112 | + | value: Battery.profile | |
| 113 | + | onPicked: v => Battery.setProfile(v) | |
| 114 | + | } | |
| 115 | + | Choice { | |
| 116 | + | visible: Battery.hasProfiles && Settings.powerAuto | |
| 117 | + | label: "on AC" | |
| 118 | + | options: flick.profiles | |
| 119 | + | value: Settings.powerAc | |
| 120 | + | onPicked: v => Settings.powerAc = v | |
| 121 | + | } | |
| 122 | + | Choice { | |
| 123 | + | visible: Battery.hasProfiles && Settings.powerAuto | |
| 124 | + | label: "on battery" | |
| 125 | + | options: flick.profiles | |
| 126 | + | value: Settings.powerBat | |
| 127 | + | onPicked: v => Settings.powerBat = v | |
| 112 | 128 | } | |
| 113 | 129 | GpuSwitch { Layout.topMargin: 6 } | |
| 114 | 130 | ||
| @@ -17,7 +17,7 @@ Singleton { | |||
| 17 | 17 | notifSound: true, notifVolume: 0.7, | |
| 18 | 18 | idleDim: 150, idleOff: 330, idleLock: 600, idleSuspend: 0, charTone: 0, portalAutoOpen: true, | |
| 19 | 19 | chargeMode: "off", batLow: 15, batCritical: 5, batCriticalAction: "none", | |
| 20 | − | privacyIndicators: true | |
| 20 | + | privacyIndicators: true, powerAuto: false, powerAc: "balanced", powerBat: "saver" | |
| 21 | 21 | }) | |
| 22 | 22 | ||
| 23 | 23 | property alias fontSize: a.fontSize | |
| @@ -47,6 +47,9 @@ Singleton { | |||
| 47 | 47 | property alias batCritical: a.batCritical | |
| 48 | 48 | property alias batCriticalAction: a.batCriticalAction | |
| 49 | 49 | property alias privacyIndicators: a.privacyIndicators | |
| 50 | + | property alias powerAuto: a.powerAuto | |
| 51 | + | property alias powerAc: a.powerAc | |
| 52 | + | property alias powerBat: a.powerBat | |
| 50 | 53 | ||
| 51 | 54 | function reset() { | |
| 52 | 55 | for (var k in defaults) a[k] = defaults[k] | |
| @@ -98,6 +101,9 @@ Singleton { | |||
| 98 | 101 | property int batCritical: 5 | |
| 99 | 102 | property string batCriticalAction: "none" // none | suspend | poweroff | |
| 100 | 103 | property bool privacyIndicators: true // mic/camera/screen-share icons in the bar (Privacy.qml) | |
| 104 | + | property bool powerAuto: false // power profile follows AC/battery (Battery.qml), off = whatever ppd has | |
| 105 | + | property string powerAc: "balanced" // saver | balanced | performance | |
| 106 | + | property string powerBat: "saver" | |
| 101 | 107 | } | |
| 102 | 108 | } | |
| 103 | 109 | // first run: create the file once the directory exists | |
| @@ -146,23 +146,31 @@ Flickable { | |||
| 146 | 146 | Layout.fillWidth: true | |
| 147 | 147 | icon: Theme.iLeaf | |
| 148 | 148 | label: "saver" | |
| 149 | − | active: PowerProfiles.profile === PowerProfile.PowerSaver | |
| 150 | − | onClicked: PowerProfiles.profile = PowerProfile.PowerSaver | |
| 149 | + | active: Battery.profile === "saver" | |
| 150 | + | onClicked: Battery.setProfile("saver") | |
| 151 | 151 | } | |
| 152 | 152 | IconBtn { | |
| 153 | 153 | Layout.fillWidth: true | |
| 154 | 154 | icon: Theme.iBalance | |
| 155 | 155 | label: "balanced" | |
| 156 | − | active: PowerProfiles.profile === PowerProfile.Balanced | |
| 157 | − | onClicked: PowerProfiles.profile = PowerProfile.Balanced | |
| 156 | + | active: Battery.profile === "balanced" | |
| 157 | + | onClicked: Battery.setProfile("balanced") | |
| 158 | 158 | } | |
| 159 | 159 | IconBtn { | |
| 160 | 160 | Layout.fillWidth: true | |
| 161 | 161 | visible: PowerProfiles.hasPerformanceProfile | |
| 162 | 162 | icon: Theme.iSpeed | |
| 163 | 163 | label: "perf" | |
| 164 | − | active: PowerProfiles.profile === PowerProfile.Performance | |
| 165 | − | onClicked: PowerProfiles.profile = PowerProfile.Performance | |
| 164 | + | active: Battery.profile === "performance" | |
| 165 | + | onClicked: Battery.setProfile("performance") | |
| 166 | + | } | |
| 167 | + | IconBtn { | |
| 168 | + | Layout.fillWidth: true | |
| 169 | + | visible: Battery.hasBat | |
| 170 | + | icon: Theme.iAuto | |
| 171 | + | label: "auto" | |
| 172 | + | active: Battery.profile === "auto" | |
| 173 | + | onClicked: Battery.setProfile("auto") | |
| 166 | 174 | } | |
| 167 | 175 | } | |
| 168 | 176 | } | |
| @@ -151,6 +151,7 @@ Singleton { | |||
| 151 | 151 | readonly property string iLeaf: cp(0xF032A) | |
| 152 | 152 | readonly property string iBalance: cp(0xF05D1) | |
| 153 | 153 | readonly property string iSpeed: cp(0xF04C5) | |
| 154 | + | readonly property string iAuto: cp(0xF006A) // autorenew | |
| 154 | 155 | readonly property string iCal: cp(0xF00ED) | |
| 155 | 156 | readonly property string iClock: cp(0xF0954) | |
| 156 | 157 | readonly property string iArch: cp(0xF08C7) | |