diff --git a/include/modules/clock.hpp b/include/modules/clock.hpp index 9f950192..1f262e91 100644 --- a/include/modules/clock.hpp +++ b/include/modules/clock.hpp @@ -18,6 +18,7 @@ struct waybar_time { }; const std::string kCalendarPlaceholder = "calendar"; +const std::string KTimezonedTimeListPlaceholder = "timezoned_time_list"; class Clock : public ALabel { public: @@ -33,6 +34,7 @@ class Clock : public ALabel { date::year_month_day cached_calendar_ymd_ = date::January/1/0; std::string cached_calendar_text_; bool is_calendar_in_tooltip_; + bool is_timezoned_list_in_tooltip_; bool handleScroll(GdkEventScroll* e); @@ -41,6 +43,7 @@ class Clock : public ALabel { auto first_day_of_week() -> date::weekday; const date::time_zone* current_timezone(); bool is_timezone_fixed(); + auto timezones_text(std::chrono::_V2::system_clock::time_point *now) -> std::string; }; } // namespace waybar::modules diff --git a/man/waybar-clock.5.scd b/man/waybar-clock.5.scd index 2c901d2d..a8fc1877 100644 --- a/man/waybar-clock.5.scd +++ b/man/waybar-clock.5.scd @@ -91,6 +91,7 @@ View all valid format options in *strftime(3)*. # FORMAT REPLACEMENTS *{calendar}*: Current month calendar +*{timezoned_time_list}*: List of time in the rest timezones, if more than one timezone is set in the config # EXAMPLES diff --git a/src/modules/clock.cpp b/src/modules/clock.cpp index 7e7d7420..be8f2e25 100644 --- a/src/modules/clock.cpp +++ b/src/modules/clock.cpp @@ -16,7 +16,8 @@ using waybar::modules::waybar_time; waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config) : ALabel(config, "clock", id, "{:%H:%M}", 60, false, false, true), current_time_zone_idx_(0), - is_calendar_in_tooltip_(false) + is_calendar_in_tooltip_(false), + is_timezoned_list_in_tooltip_(false) { if (config_["timezones"].isArray() && !config_["timezones"].empty()) { for (const auto& zone_name: config_["timezones"]) { @@ -57,6 +58,9 @@ waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config) if (trimmed_format.find("{" + kCalendarPlaceholder + "}") != std::string::npos) { is_calendar_in_tooltip_ = true; } + if (trimmed_format.find("{" + KTimezonedTimeListPlaceholder + "}") != std::string::npos) { + is_timezoned_list_in_tooltip_ = true; + } } if (config_["locale"].isString()) { @@ -101,11 +105,15 @@ auto waybar::modules::Clock::update() -> void { if (tooltipEnabled()) { if (config_["tooltip-format"].isString()) { std::string calendar_lines = ""; + std::string timezoned_time_lines = ""; if (is_calendar_in_tooltip_) { calendar_lines = calendar_text(wtime); } + if (is_timezoned_list_in_tooltip_) { + timezoned_time_lines = timezones_text(&now); + } auto tooltip_format = config_["tooltip-format"].asString(); - text = fmt::format(tooltip_format, wtime, fmt::arg(kCalendarPlaceholder.c_str(), calendar_lines)); + text = fmt::format(tooltip_format, wtime, fmt::arg(kCalendarPlaceholder.c_str(), calendar_lines), fmt::arg(KTimezonedTimeListPlaceholder.c_str(), timezoned_time_lines)); } } @@ -204,6 +212,26 @@ auto waybar::modules::Clock::weekdays_header(const date::weekday& first_dow, std os << "\n"; } +auto waybar::modules::Clock::timezones_text(std::chrono::_V2::system_clock::time_point *now) -> std::string { + if (time_zones_.size() == 1) { + return ""; + } + std::stringstream os; + waybar_time wtime; + for (size_t time_zone_idx = 0; time_zone_idx < time_zones_.size(); ++time_zone_idx) { + if (static_cast(time_zone_idx) == current_time_zone_idx_) { + continue; + } + const date::time_zone* timezone = time_zones_[time_zone_idx]; + if (!timezone) { + timezone = date::current_zone(); + } + wtime = {locale_, date::make_zoned(timezone, date::floor(*now))}; + os << fmt::format(format_, wtime) << "\n"; + } + return os.str(); +} + #ifdef HAVE_LANGINFO_1STDAY template using deleter_from_fn = std::integral_constant;