fix(clock): disambiguate DST transitions to stop tooltip crash

Building a zoned_time/zoned_seconds from a local_time throws
ambiguous_local_time during the DST fall-back hour and nonexistent_local_time
across the spring-forward gap. update() runs this every minute with the
tooltip enabled by default and has no try/catch, so Waybar aborts every
minute during a DST transition. Pass choose::earliest at each construction to
resolve deterministically instead of throwing.

Fixes #2615; resolves the recurring DST-crash duplicates #5006, #5018, #5063,
#5096, #3024.
This commit is contained in:
Alex
2026-07-04 03:10:55 +02:00
parent bfe38bd1e2
commit d130ce6a66
+16 -9
View File
@@ -190,8 +190,13 @@ auto waybar::modules::Clock::update() -> void {
if (tooltipEnabled()) {
const year_month_day today{floor<days>(now.get_local_time())};
const auto shiftedDay{today + cldCurrShift_};
// choose::earliest disambiguates the DST fall-back hour (ambiguous local
// time) and skips forward over the spring-forward gap (nonexistent local
// time); without it this constructor throws and aborts Waybar every minute
// during a DST transition. Fixes #2615 (and its many duplicates).
const zoned_time shiftedNow{
tz, local_days(shiftedDay) + (now.get_local_time() - floor<days>(now.get_local_time()))};
tz, local_days(shiftedDay) + (now.get_local_time() - floor<days>(now.get_local_time())),
choose::earliest};
if (tzInTooltip_) tzText_ = getTZtext(now.get_sys_time());
if (cldInTooltip_) cldText_ = get_calendar(today, shiftedDay, tz);
@@ -441,9 +446,11 @@ auto waybar::modules::Clock::get_calendar(const year_month_day& today, const yea
fmt_lib::make_format_args(
(line == 2)
? static_cast<const zoned_seconds&&>(
zoned_seconds{tz, local_days{ymTmp / 1}})
: static_cast<const zoned_seconds&&>(zoned_seconds{
tz, local_days{cldGetWeekForLine(ymTmp, firstdow, line)}})))
zoned_seconds{tz, local_days{ymTmp / 1}, choose::earliest})
: static_cast<const zoned_seconds&&>(
zoned_seconds{tz,
local_days{cldGetWeekForLine(ymTmp, firstdow, line)},
choose::earliest})))
<< ' ';
} else {
os << pads;
@@ -482,11 +489,11 @@ auto waybar::modules::Clock::get_calendar(const year_month_day& today, const yea
<< fmt_lib::vformat(
m_locale_, fmtMap_[4],
fmt_lib::make_format_args(
(line == 2) ? static_cast<const zoned_seconds&&>(
zoned_seconds{tz, local_days{ymTmp / 1}})
: static_cast<const zoned_seconds&&>(
zoned_seconds{tz, local_days{cldGetWeekForLine(
ymTmp, firstdow, line)}})));
(line == 2) ? static_cast<const zoned_seconds&&>(zoned_seconds{
tz, local_days{ymTmp / 1}, choose::earliest})
: static_cast<const zoned_seconds&&>(zoned_seconds{
tz, local_days{cldGetWeekForLine(ymTmp, firstdow, line)},
choose::earliest})));
else
os << pads;
}