From f0e459cc7342ae1523bde3bec8fb505196f2ad07 Mon Sep 17 00:00:00 2001 From: Lemmy Date: Sun, 10 May 2026 18:11:53 -0400 Subject: [PATCH] fix(nightlight): make weather location a real mode and clarify the UI --- assets/translations/en.json | 10 ++--- example.toml | 6 +-- src/config/config_types.h | 4 +- src/shell/settings/settings_registry.cpp | 49 ++++++++++++++++-------- src/system/gamma_service.cpp | 43 ++++++++++++++------- src/system/gamma_service.h | 7 ++++ 6 files changed, 79 insertions(+), 40 deletions(-) diff --git a/assets/translations/en.json b/assets/translations/en.json index 85a7a03b9..f4b7b0663 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -1585,23 +1585,23 @@ }, "use-weather-location": { "label": "Use Weather Location", - "description": "Use weather service location for sunrise/sunset" + "description": "Use weather service location for sunrise/sunset instead of a manual schedule" }, "night-light-start-time": { "label": "Start Time", - "description": "Night light start time in HH:MM" + "description": "Manual night light start time in HH:MM when weather location is off" }, "night-light-stop-time": { "label": "Stop Time", - "description": "Night light stop time in HH:MM" + "description": "Manual night light stop time in HH:MM when weather location is off" }, "latitude": { "label": "Latitude", - "description": "Manual sunrise/sunset latitude when fixed times are unset" + "description": "Manual sunrise/sunset latitude when weather location is off and fixed times are unset" }, "longitude": { "label": "Longitude", - "description": "Manual sunrise/sunset longitude when fixed times are unset" + "description": "Manual sunrise/sunset longitude when weather location is off and fixed times are unset" }, "day-temperature": { "label": "Day Temperature", diff --git a/example.toml b/example.toml index e668442e0..a4db087dd 100644 --- a/example.toml +++ b/example.toml @@ -142,12 +142,12 @@ enable_ddcutil = false [nightlight] enabled = false force = false -use_weather_location = true +use_weather_location = true # use weather coordinates instead of manual schedule/location temperature_day = 6500 # Kelvin temperature_night = 4000 # Kelvin -# start_time = "20:30" # HH:MM — explicit schedule takes priority over geolocation +# start_time = "20:30" # HH:MM — used when use_weather_location = false # stop_time = "07:30" -# latitude = 52.5200 +# latitude = 52.5200 # fallback when use_weather_location = false and start/stop are unset # longitude = 13.4050 # ── Idle ────────────────────────────────────────────────────────────────────── diff --git a/src/config/config_types.h b/src/config/config_types.h index c5a81ea43..a6117d606 100644 --- a/src/config/config_types.h +++ b/src/config/config_types.h @@ -497,8 +497,8 @@ struct NightLightConfig { bool enabled = false; bool force = false; - bool useWeatherLocation = true; // use WeatherService coordinates when start/stop and explicit lat/long are not set - std::string startTime; // HH:MM sunset (night start), overrides location mode when paired with stop_time + bool useWeatherLocation = true; // use WeatherService coordinates instead of manual schedule/location + std::string startTime; // HH:MM sunset (night start), used when use_weather_location is false std::string stopTime; // HH:MM sunrise (day start) std::optional latitude; std::optional longitude; diff --git a/src/shell/settings/settings_registry.cpp b/src/shell/settings/settings_registry.cpp index a62982814..afc734d06 100644 --- a/src/shell/settings/settings_registry.cpp +++ b/src/shell/settings/settings_registry.cpp @@ -693,22 +693,39 @@ namespace settings { tr("settings.schema.services.use-weather-location.description"), {"nightlight", "use_weather_location"}, ToggleSetting{cfg.nightlight.useWeatherLocation}, "location")); - entries.push_back( - makeEntry("services", "night-light", tr("settings.schema.services.night-light-start-time.label"), - tr("settings.schema.services.night-light-start-time.description"), {"nightlight", "start_time"}, - TextSetting{cfg.nightlight.startTime, "20:30"}, "time schedule sunset")); - entries.push_back(makeEntry("services", "night-light", tr("settings.schema.services.night-light-stop-time.label"), - tr("settings.schema.services.night-light-stop-time.description"), - {"nightlight", "stop_time"}, TextSetting{cfg.nightlight.stopTime, "07:30"}, - "time schedule sunrise")); - entries.push_back(makeEntry("services", "night-light", tr("settings.schema.services.latitude.label"), - tr("settings.schema.services.latitude.description"), {"nightlight", "latitude"}, - OptionalNumberSetting{cfg.nightlight.latitude, -90.0, 90.0, "52.5200"}, - "coordinate location sunrise sunset", true)); - entries.push_back(makeEntry("services", "night-light", tr("settings.schema.services.longitude.label"), - tr("settings.schema.services.longitude.description"), {"nightlight", "longitude"}, - OptionalNumberSetting{cfg.nightlight.longitude, -180.0, 180.0, "13.4050"}, - "coordinate location sunrise sunset", true)); + const SettingVisibility weatherLocationOff{{"nightlight", "use_weather_location"}, {"false"}}; + { + auto e = + makeEntry("services", "night-light", tr("settings.schema.services.night-light-start-time.label"), + tr("settings.schema.services.night-light-start-time.description"), {"nightlight", "start_time"}, + TextSetting{cfg.nightlight.startTime, "20:30"}, "time schedule sunset"); + e.visibleWhen = weatherLocationOff; + entries.push_back(std::move(e)); + } + { + auto e = + makeEntry("services", "night-light", tr("settings.schema.services.night-light-stop-time.label"), + tr("settings.schema.services.night-light-stop-time.description"), {"nightlight", "stop_time"}, + TextSetting{cfg.nightlight.stopTime, "07:30"}, "time schedule sunrise"); + e.visibleWhen = weatherLocationOff; + entries.push_back(std::move(e)); + } + { + auto e = makeEntry("services", "night-light", tr("settings.schema.services.latitude.label"), + tr("settings.schema.services.latitude.description"), {"nightlight", "latitude"}, + OptionalNumberSetting{cfg.nightlight.latitude, -90.0, 90.0, "52.5200"}, + "coordinate location sunrise sunset", true); + e.visibleWhen = weatherLocationOff; + entries.push_back(std::move(e)); + } + { + auto e = makeEntry("services", "night-light", tr("settings.schema.services.longitude.label"), + tr("settings.schema.services.longitude.description"), {"nightlight", "longitude"}, + OptionalNumberSetting{cfg.nightlight.longitude, -180.0, 180.0, "13.4050"}, + "coordinate location sunrise sunset", true); + e.visibleWhen = weatherLocationOff; + entries.push_back(std::move(e)); + } // Both sliders span the same range; the day > night invariant is enforced at commit time // via SliderSetting::linkedCommit, which pushes the other temperature when needed. const float tempMin = static_cast(NightLightConfig::kTemperatureMin); diff --git a/src/system/gamma_service.cpp b/src/system/gamma_service.cpp index 0f82ef052..a9d96a7b9 100644 --- a/src/system/gamma_service.cpp +++ b/src/system/gamma_service.cpp @@ -122,8 +122,23 @@ bool GammaService::effectiveForce() const { return m_config.force; } +GammaService::GeoCoordinates GammaService::scheduleCoordinates() const { + if (m_config.useWeatherLocation) { + return GeoCoordinates{.latitude = m_weatherLatitude, .longitude = m_weatherLongitude}; + } + + if (m_config.latitude.has_value() || m_config.longitude.has_value()) { + if (m_config.latitude.has_value() && m_config.longitude.has_value()) { + return GeoCoordinates{.latitude = m_config.latitude, .longitude = m_config.longitude}; + } + return GeoCoordinates{}; + } + + return GeoCoordinates{}; +} + bool GammaService::isManualMode() const { - return !effectiveForce() && normalizedClock(m_config.startTime).has_value() && + return !effectiveForce() && !m_config.useWeatherLocation && normalizedClock(m_config.startTime).has_value() && normalizedClock(m_config.stopTime).has_value(); } @@ -256,13 +271,12 @@ GammaService::SolarTimes GammaService::computeSolarTimes(double lat, double lon) } bool GammaService::isGeoNightPhase() const { - const auto lat = m_config.latitude.has_value() ? m_config.latitude : m_weatherLatitude; - const auto lon = m_config.longitude.has_value() ? m_config.longitude : m_weatherLongitude; - if (!lat.has_value() || !lon.has_value()) { + const auto coords = scheduleCoordinates(); + if (!coords.latitude.has_value() || !coords.longitude.has_value()) { return false; } - const auto times = computeSolarTimes(*lat, *lon); + const auto times = computeSolarTimes(*coords.latitude, *coords.longitude); if (times.sunriseMinutes == 0 && times.sunsetMinutes == 0) { return true; } @@ -285,13 +299,12 @@ bool GammaService::isGeoNightPhase() const { } std::chrono::milliseconds GammaService::msUntilNextGeoBoundary() const { - const auto lat = m_config.latitude.has_value() ? m_config.latitude : m_weatherLatitude; - const auto lon = m_config.longitude.has_value() ? m_config.longitude : m_weatherLongitude; - if (!lat.has_value() || !lon.has_value()) { + const auto coords = scheduleCoordinates(); + if (!coords.latitude.has_value() || !coords.longitude.has_value()) { return std::chrono::milliseconds(3600000); } - const auto times = computeSolarTimes(*lat, *lon); + const auto times = computeSolarTimes(*coords.latitude, *coords.longitude); if (times.sunriseMinutes == 0 && (times.sunsetMinutes == 0 || times.sunsetMinutes == 1440)) { return std::chrono::milliseconds(3600000); } @@ -565,13 +578,15 @@ int GammaService::targetTemperature() const { } // Geo mode — need coordinates. - const auto lat = m_config.latitude.has_value() ? m_config.latitude : m_weatherLatitude; - const auto lon = m_config.longitude.has_value() ? m_config.longitude : m_weatherLongitude; - if (!lat.has_value() || !lon.has_value()) { - if (m_config.latitude.has_value() || m_config.longitude.has_value()) { + const auto coords = scheduleCoordinates(); + if (!coords.latitude.has_value() || !coords.longitude.has_value()) { + if (!m_config.useWeatherLocation && (m_config.latitude.has_value() || m_config.longitude.has_value())) { kLog.warn("need both latitude and longitude when overriding location mode"); + } else if (!m_config.useWeatherLocation) { + kLog.warn("no schedule: set start_time/stop_time or latitude/longitude, or enable weather location"); } else { - kLog.warn("no schedule: set start_time/stop_time or latitude/longitude, or enable weather"); + kLog.warn("no schedule: set start_time/stop_time, disable weather location and set latitude/longitude, or enable " + "weather"); } return -1; } diff --git a/src/system/gamma_service.h b/src/system/gamma_service.h index 287c26e83..59de33b29 100644 --- a/src/system/gamma_service.h +++ b/src/system/gamma_service.h @@ -49,6 +49,13 @@ private: [[nodiscard]] bool effectiveConfiguredEnabled() const; [[nodiscard]] bool effectiveEnabled() const; [[nodiscard]] bool effectiveForce() const; + + struct GeoCoordinates { + std::optional latitude; + std::optional longitude; + }; + [[nodiscard]] GeoCoordinates scheduleCoordinates() const; + [[nodiscard]] bool isManualMode() const; [[nodiscard]] bool isManualNightPhase() const; [[nodiscard]] std::chrono::milliseconds msUntilNextManualBoundary() const;