feat(display): night-dim backlight window for screensaver

- DisplaySettings: nightDimEnabled/startHour/endHour/duty
  (default 22:00-07:00 at duty 20), persisted in display.properties
- Display settings page: Night dim switch + Dim from/until hour
  dropdowns + Dim brightness slider
- DisplayIdle: screensaver runs at the dimmed level when the local
  hour is inside the window (wrap-around aware); falls back to the
  regular duty when time is unknown (year < 2025)
This commit is contained in:
Adolfo Reyna
2026-09-12 08:17:45 -04:00
parent 87c82f5314
commit 85da419a98
4 changed files with 225 additions and 2 deletions
@@ -61,6 +61,34 @@ static bool hasDisplayWithBacklight() {
return result;
}
/**
* Effective backlight duty for the screensaver: the dimmed night level when
* night dim is enabled and the local hour is inside the configured window,
* otherwise the regular duty. A start == end window covers the whole day.
*/
static uint8_t screensaverBacklightDuty(const settings::display::DisplaySettings& displaySettings) {
if (!displaySettings.nightDimEnabled) {
return displaySettings.backlightDuty;
}
const std::time_t now = std::time(nullptr);
std::tm local_time {};
if (localtime_r(&now, &local_time) == nullptr || local_time.tm_year < 125) {
return displaySettings.backlightDuty;
}
const uint8_t hour = static_cast<uint8_t>(local_time.tm_hour);
const uint8_t start = displaySettings.nightDimStartHour;
const uint8_t end = displaySettings.nightDimEndHour;
bool in_window;
if (start == end) {
in_window = true;
} else if (start < end) {
in_window = hour >= start && hour < end;
} else {
in_window = hour >= start || hour < end;
}
return in_window ? displaySettings.nightDimDuty : displaySettings.backlightDuty;
}
void DisplayIdleService::stopScreensaver() {
if (!lvgl_try_lock(100)) {
// Lock failed - keep flag set to retry on next tick
@@ -142,6 +170,8 @@ void DisplayIdleService::activateScreensaver() {
if (screensaver) {
screensaver->start(screensaverOverlay, screenW, screenH);
}
setBacklightBrightness(screensaverBacklightDuty(cachedDisplaySettings));
}
void DisplayIdleService::updateScreensaver() {
@@ -301,7 +331,7 @@ void DisplayIdleService::startMcpScreensaver() {
screensaverActiveCounter = 0;
backlightOff = false;
setBacklightBrightness(cachedDisplaySettings.backlightDuty == 0
? 255 : cachedDisplaySettings.backlightDuty);
? 255 : screensaverBacklightDuty(cachedDisplaySettings));
lv_coord_t screenW = lv_display_get_horizontal_resolution(nullptr);
lv_coord_t screenH = lv_display_get_vertical_resolution(nullptr);