From ece86c96d70a83f31e9e864caf24f76e7e4c4fb5 Mon Sep 17 00:00:00 2001 From: Sergey Mishin Date: Tue, 5 Oct 2021 09:46:52 +0000 Subject: [PATCH] Feature Clock: show list of time in other timezones in a tooltip Introducing new tooltip placeholder: {timezoned_time_list}. It will be replaced with the list of times in different time zones. I've found it useful to hover the mouse pointer on time and see time in all my timezones at once. Current timezone excluding from the list, so if you will scroll over the time module and change the active timezone, this timezone will be excluded from the list and the previous active zone will be added. --- include/modules/clock.hpp | 3 +++ man/waybar-clock.5.scd | 1 + src/modules/clock.cpp | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 34 insertions(+), 2 deletions(-) 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;