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:
+16
-9
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user