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()) {
|
if (tooltipEnabled()) {
|
||||||
const year_month_day today{floor<days>(now.get_local_time())};
|
const year_month_day today{floor<days>(now.get_local_time())};
|
||||||
const auto shiftedDay{today + cldCurrShift_};
|
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{
|
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 (tzInTooltip_) tzText_ = getTZtext(now.get_sys_time());
|
||||||
if (cldInTooltip_) cldText_ = get_calendar(today, shiftedDay, tz);
|
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(
|
fmt_lib::make_format_args(
|
||||||
(line == 2)
|
(line == 2)
|
||||||
? static_cast<const zoned_seconds&&>(
|
? static_cast<const zoned_seconds&&>(
|
||||||
zoned_seconds{tz, local_days{ymTmp / 1}})
|
zoned_seconds{tz, local_days{ymTmp / 1}, choose::earliest})
|
||||||
: static_cast<const zoned_seconds&&>(zoned_seconds{
|
: static_cast<const zoned_seconds&&>(
|
||||||
tz, local_days{cldGetWeekForLine(ymTmp, firstdow, line)}})))
|
zoned_seconds{tz,
|
||||||
|
local_days{cldGetWeekForLine(ymTmp, firstdow, line)},
|
||||||
|
choose::earliest})))
|
||||||
<< ' ';
|
<< ' ';
|
||||||
} else {
|
} else {
|
||||||
os << pads;
|
os << pads;
|
||||||
@@ -482,11 +489,11 @@ auto waybar::modules::Clock::get_calendar(const year_month_day& today, const yea
|
|||||||
<< fmt_lib::vformat(
|
<< fmt_lib::vformat(
|
||||||
m_locale_, fmtMap_[4],
|
m_locale_, fmtMap_[4],
|
||||||
fmt_lib::make_format_args(
|
fmt_lib::make_format_args(
|
||||||
(line == 2) ? static_cast<const zoned_seconds&&>(
|
(line == 2) ? static_cast<const zoned_seconds&&>(zoned_seconds{
|
||||||
zoned_seconds{tz, local_days{ymTmp / 1}})
|
tz, local_days{ymTmp / 1}, choose::earliest})
|
||||||
: static_cast<const zoned_seconds&&>(
|
: static_cast<const zoned_seconds&&>(zoned_seconds{
|
||||||
zoned_seconds{tz, local_days{cldGetWeekForLine(
|
tz, local_days{cldGetWeekForLine(ymTmp, firstdow, line)},
|
||||||
ymTmp, firstdow, line)}})));
|
choose::earliest})));
|
||||||
else
|
else
|
||||||
os << pads;
|
os << pads;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user