mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
fix(nightlight): make weather location a real mode and clarify the UI
This commit is contained in:
@@ -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",
|
||||
|
||||
+3
-3
@@ -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 ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -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<double> latitude;
|
||||
std::optional<double> longitude;
|
||||
|
||||
@@ -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<float>(NightLightConfig::kTemperatureMin);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -49,6 +49,13 @@ private:
|
||||
[[nodiscard]] bool effectiveConfiguredEnabled() const;
|
||||
[[nodiscard]] bool effectiveEnabled() const;
|
||||
[[nodiscard]] bool effectiveForce() const;
|
||||
|
||||
struct GeoCoordinates {
|
||||
std::optional<double> latitude;
|
||||
std::optional<double> longitude;
|
||||
};
|
||||
[[nodiscard]] GeoCoordinates scheduleCoordinates() const;
|
||||
|
||||
[[nodiscard]] bool isManualMode() const;
|
||||
[[nodiscard]] bool isManualNightPhase() const;
|
||||
[[nodiscard]] std::chrono::milliseconds msUntilNextManualBoundary() const;
|
||||
|
||||
Reference in New Issue
Block a user