1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-08-01 19:18:28 -04:00

feat(power): lower refresh rate on battery (#2428)

* feat(power): lower refresh rate on battery (#1203)

Add a Power & Sleep setting that lowers eligible displays to 60 Hz on battery and restores their previous mode on AC power.

Skip displays without an available 60 Hz mode, displays with a single refresh-rate option, current modes at or below 60 Hz, and VRR-enabled outputs.
Apply niri changes at runtime through output commands and use wlr-output-management as fallback.

* fix(quickshell): debounce display refresh sync

* chore: regenerate settings_search_index.json for pre-commit CI fix

* fix: translator context is missing for lowerDisplayRefreshRateOnBattery

* fix: activeDisplayProfileModes is missing from SettingsSpec

* feat: added guard to syncRefreshRates function

* refactor(display): move refresh sync listeners to display service

* fix(display): publish active profile modes after config write

* feat(display): persist previous refresh modes

* fix(display): route refresh mode writes through compositor backends

* fix(display): detect preferred niri refresh modes

* some small cleanups

---------

Co-authored-by: bbedward <bbedward@gmail.com>
This commit is contained in:
Artem Timofeev
2026-07-17 15:41:08 +02:00
committed by GitHub
parent 95e1d6b72e
commit adbbd9b112
6 changed files with 677 additions and 1 deletions
+24
View File
@@ -758,6 +758,7 @@ Singleton {
property int batteryLowNotificationType: 0
property int batteryCriticalNotificationType: 1
property bool batteryAutoPowerSaver: false
property bool lowerDisplayRefreshRateOnBattery: false
property bool showBatteryPercent: true
property bool showBatteryPercentOnlyOnBattery: false
property bool showBatteryTime: false
@@ -971,6 +972,8 @@ Singleton {
property var hyprlandOutputSettings: ({})
property var displayProfiles: ({})
property var activeDisplayProfile: ({})
property var activeDisplayProfileModes: ({})
property var displayPreviousRefreshModes: ({})
property bool displayProfileAutoSelect: false
property bool displayShowDisconnected: false
property bool displaySnapToEdge: true
@@ -3558,6 +3561,27 @@ Singleton {
saveSettings();
}
function setActiveDisplayProfileModes(compositor, modes) {
if (JSON.stringify(activeDisplayProfileModes[compositor] || {}) === JSON.stringify(modes || {}))
return;
const updated = JSON.parse(JSON.stringify(activeDisplayProfileModes));
updated[compositor] = modes;
activeDisplayProfileModes = updated;
saveSettings();
}
function setDisplayPreviousRefreshModes(compositor, modes) {
if (JSON.stringify(displayPreviousRefreshModes[compositor] || {}) === JSON.stringify(modes || {}))
return;
const updated = JSON.parse(JSON.stringify(displayPreviousRefreshModes));
if (Object.keys(modes || {}).length > 0)
updated[compositor] = modes;
else
delete updated[compositor];
displayPreviousRefreshModes = updated;
saveSettings();
}
ListModel {
id: leftWidgetsModel
}
@@ -346,6 +346,7 @@ var SPEC = {
batteryLowNotificationType: { def: 0 },
batteryCriticalNotificationType: { def: 1 },
batteryAutoPowerSaver: { def: false },
lowerDisplayRefreshRateOnBattery: { def: false },
lockBeforeSuspend: { def: false },
loginctlLockIntegration: { def: true },
fadeToLockEnabled: { def: true },
@@ -530,6 +531,8 @@ var SPEC = {
hyprlandOutputSettings: { def: {} },
displayProfiles: { def: {} },
activeDisplayProfile: { def: {} },
activeDisplayProfileModes: { def: {} },
displayPreviousRefreshModes: { def: {} },
displayProfileAutoSelect: { def: false },
displayShowDisconnected: { def: false },
displaySnapToEdge: { def: true },