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.
This commit is contained in:
Sergey Mishin 2021-10-05 09:46:52 +00:00
parent 9e8a71c4ef
commit ece86c96d7
No known key found for this signature in database
GPG Key ID: BFFA09D74430117B
3 changed files with 34 additions and 2 deletions

View File

@ -18,6 +18,7 @@ struct waybar_time {
}; };
const std::string kCalendarPlaceholder = "calendar"; const std::string kCalendarPlaceholder = "calendar";
const std::string KTimezonedTimeListPlaceholder = "timezoned_time_list";
class Clock : public ALabel { class Clock : public ALabel {
public: public:
@ -33,6 +34,7 @@ class Clock : public ALabel {
date::year_month_day cached_calendar_ymd_ = date::January/1/0; date::year_month_day cached_calendar_ymd_ = date::January/1/0;
std::string cached_calendar_text_; std::string cached_calendar_text_;
bool is_calendar_in_tooltip_; bool is_calendar_in_tooltip_;
bool is_timezoned_list_in_tooltip_;
bool handleScroll(GdkEventScroll* e); bool handleScroll(GdkEventScroll* e);
@ -41,6 +43,7 @@ class Clock : public ALabel {
auto first_day_of_week() -> date::weekday; auto first_day_of_week() -> date::weekday;
const date::time_zone* current_timezone(); const date::time_zone* current_timezone();
bool is_timezone_fixed(); bool is_timezone_fixed();
auto timezones_text(std::chrono::_V2::system_clock::time_point *now) -> std::string;
}; };
} // namespace waybar::modules } // namespace waybar::modules

View File

@ -91,6 +91,7 @@ View all valid format options in *strftime(3)*.
# FORMAT REPLACEMENTS # FORMAT REPLACEMENTS
*{calendar}*: Current month calendar *{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 # EXAMPLES

View File

@ -16,7 +16,8 @@ using waybar::modules::waybar_time;
waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config) waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config)
: ALabel(config, "clock", id, "{:%H:%M}", 60, false, false, true), : ALabel(config, "clock", id, "{:%H:%M}", 60, false, false, true),
current_time_zone_idx_(0), 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()) { if (config_["timezones"].isArray() && !config_["timezones"].empty()) {
for (const auto& zone_name: config_["timezones"]) { 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) { if (trimmed_format.find("{" + kCalendarPlaceholder + "}") != std::string::npos) {
is_calendar_in_tooltip_ = true; is_calendar_in_tooltip_ = true;
} }
if (trimmed_format.find("{" + KTimezonedTimeListPlaceholder + "}") != std::string::npos) {
is_timezoned_list_in_tooltip_ = true;
}
} }
if (config_["locale"].isString()) { if (config_["locale"].isString()) {
@ -101,11 +105,15 @@ auto waybar::modules::Clock::update() -> void {
if (tooltipEnabled()) { if (tooltipEnabled()) {
if (config_["tooltip-format"].isString()) { if (config_["tooltip-format"].isString()) {
std::string calendar_lines = ""; std::string calendar_lines = "";
std::string timezoned_time_lines = "";
if (is_calendar_in_tooltip_) { if (is_calendar_in_tooltip_) {
calendar_lines = calendar_text(wtime); calendar_lines = calendar_text(wtime);
} }
if (is_timezoned_list_in_tooltip_) {
timezoned_time_lines = timezones_text(&now);
}
auto tooltip_format = config_["tooltip-format"].asString(); 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"; 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<int>(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<std::chrono::seconds>(*now))};
os << fmt::format(format_, wtime) << "\n";
}
return os.str();
}
#ifdef HAVE_LANGINFO_1STDAY #ifdef HAVE_LANGINFO_1STDAY
template <auto fn> template <auto fn>
using deleter_from_fn = std::integral_constant<decltype(fn), fn>; using deleter_from_fn = std::integral_constant<decltype(fn), fn>;