Skip to content

Commit

Permalink
Merge pull request #3255 from LukashonakV/ISSUE#2240
Browse files Browse the repository at this point in the history
Fix Clock. Tooltip calendar text overflows(#2240)
  • Loading branch information
Alexays authored May 28, 2024
2 parents af79451 + b288fdf commit d4413f5
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 34 deletions.
8 changes: 5 additions & 3 deletions include/modules/clock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ class Clock final : public ALabel {
auto doAction(const std::string&) -> void override;

private:
const std::locale locale_;
const std::locale m_locale_;
// tooltip
const std::string tlpFmt_;
std::string tlpText_{""}; // tooltip text to print
const std::string m_tlpFmt_;
std::string m_tlpText_{""}; // tooltip text to print
const Glib::RefPtr<Gtk::Label> m_tooltip_; // tooltip as a separate Gtk::Label
bool query_tlp_cb(int, int, bool, const Glib::RefPtr<Gtk::Tooltip>& tooltip);
// Calendar
const bool cldInTooltip_; // calendar in tooltip
/*
Expand Down
74 changes: 43 additions & 31 deletions src/modules/clock.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "modules/clock.hpp"

#include <gtkmm/tooltip.h>
#include <spdlog/spdlog.h>

#include <chrono>
Expand All @@ -18,13 +19,14 @@ namespace fmt_lib = waybar::util::date::format;

waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config)
: ALabel(config, "clock", id, "{:%H:%M}", 60, false, false, true),
locale_{std::locale(config_["locale"].isString() ? config_["locale"].asString() : "")},
tlpFmt_{(config_["tooltip-format"].isString()) ? config_["tooltip-format"].asString() : ""},
cldInTooltip_{tlpFmt_.find("{" + kCldPlaceholder + "}") != std::string::npos},
tzInTooltip_{tlpFmt_.find("{" + kTZPlaceholder + "}") != std::string::npos},
m_locale_{std::locale(config_["locale"].isString() ? config_["locale"].asString() : "")},
m_tlpFmt_{(config_["tooltip-format"].isString()) ? config_["tooltip-format"].asString() : ""},
m_tooltip_{new Gtk::Label()},
cldInTooltip_{m_tlpFmt_.find("{" + kCldPlaceholder + "}") != std::string::npos},
tzInTooltip_{m_tlpFmt_.find("{" + kTZPlaceholder + "}") != std::string::npos},
tzCurrIdx_{0},
ordInTooltip_{tlpFmt_.find("{" + kOrdPlaceholder + "}") != std::string::npos} {
tlpText_ = tlpFmt_;
ordInTooltip_{m_tlpFmt_.find("{" + kOrdPlaceholder + "}") != std::string::npos} {
m_tlpText_ = m_tlpFmt_;

if (config_["timezones"].isArray() && !config_["timezones"].empty()) {
for (const auto& zone_name : config_["timezones"]) {
Expand Down Expand Up @@ -124,17 +126,26 @@ waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config)
}
}

label_.set_has_tooltip(true);
label_.signal_query_tooltip().connect(sigc::mem_fun(*this, &Clock::query_tlp_cb));

thread_ = [this] {
dp.emit();
thread_.sleep_for(interval_ - system_clock::now().time_since_epoch() % interval_);
};
}

bool waybar::modules::Clock::query_tlp_cb(int, int, bool,
const Glib::RefPtr<Gtk::Tooltip>& tooltip) {
tooltip->set_custom(*m_tooltip_.get());
return true;
}

auto waybar::modules::Clock::update() -> void {
const auto* tz = tzList_[tzCurrIdx_] != nullptr ? tzList_[tzCurrIdx_] : local_zone();
const zoned_time now{tz, floor<seconds>(system_clock::now())};

label_.set_markup(fmt_lib::vformat(locale_, format_, fmt_lib::make_format_args(now)));
label_.set_markup(fmt_lib::vformat(m_locale_, format_, fmt_lib::make_format_args(now)));

if (tooltipEnabled()) {
const year_month_day today{floor<days>(now.get_local_time())};
Expand All @@ -147,18 +158,19 @@ auto waybar::modules::Clock::update() -> void {
if (ordInTooltip_) ordText_ = get_ordinal_date(shiftedDay);
if (tzInTooltip_ || cldInTooltip_ || ordInTooltip_) {
// std::vformat doesn't support named arguments.
tlpText_ = std::regex_replace(tlpFmt_, std::regex("\\{" + kTZPlaceholder + "\\}"), tzText_);
tlpText_ =
std::regex_replace(tlpText_, std::regex("\\{" + kCldPlaceholder + "\\}"), cldText_);
tlpText_ =
std::regex_replace(tlpText_, std::regex("\\{" + kOrdPlaceholder + "\\}"), ordText_);
m_tlpText_ =
std::regex_replace(m_tlpFmt_, std::regex("\\{" + kTZPlaceholder + "\\}"), tzText_);
m_tlpText_ =
std::regex_replace(m_tlpText_, std::regex("\\{" + kCldPlaceholder + "\\}"), cldText_);
m_tlpText_ =
std::regex_replace(m_tlpText_, std::regex("\\{" + kOrdPlaceholder + "\\}"), ordText_);
} else {
tlpText_ = tlpFmt_;
m_tlpText_ = m_tlpFmt_;
}

tlpText_ = fmt_lib::vformat(locale_, tlpText_, fmt_lib::make_format_args(shiftedNow));

label_.set_tooltip_markup(tlpText_);
m_tlpText_ = fmt_lib::vformat(m_locale_, m_tlpText_, fmt_lib::make_format_args(shiftedNow));
m_tooltip_->set_markup(m_tlpText_);
label_.trigger_tooltip_query();
}

ALabel::update();
Expand All @@ -172,7 +184,7 @@ auto waybar::modules::Clock::getTZtext(sys_seconds now) -> std::string {
if (static_cast<int>(tz_idx) == tzCurrIdx_) continue;
const auto* tz = tzList_[tz_idx] != nullptr ? tzList_[tz_idx] : local_zone();
auto zt{zoned_time{tz, now}};
os << fmt_lib::vformat(locale_, format_, fmt_lib::make_format_args(zt)) << '\n';
os << fmt_lib::vformat(m_locale_, format_, fmt_lib::make_format_args(zt)) << '\n';
}

return os.str();
Expand All @@ -190,13 +202,13 @@ auto cldGetWeekForLine(const year_month& ym, const weekday& firstdow, const unsi
}

auto getCalendarLine(const year_month_day& currDate, const year_month ym, const unsigned line,
const weekday& firstdow, const std::locale* const locale_) -> std::string {
const weekday& firstdow, const std::locale* const m_locale_) -> std::string {
std::ostringstream os;

switch (line) {
// Print month and year title
case 0: {
os << date::format(*locale_, "{:L%B %Y}", ym);
os << date::format(*m_locale_, "{:L%B %Y}", ym);
break;
}
// Print weekday names title
Expand All @@ -206,7 +218,7 @@ auto getCalendarLine(const year_month_day& currDate, const year_month ym, const
Glib::ustring::size_type wdLen{0};
int clen{0};
do {
wdStr = date::format(*locale_, "{:L%a}", wd);
wdStr = date::format(*m_locale_, "{:L%a}", wd);
clen = ustring_clen(wdStr);
wdLen = wdStr.length();
while (clen > 2) {
Expand All @@ -229,15 +241,15 @@ auto getCalendarLine(const year_month_day& currDate, const year_month ym, const
os << std::string((wd - firstdow).count() * 3, ' ');

if (currDate != ym / d)
os << date::format(*locale_, "{:L%e}", d);
os << date::format(*m_locale_, "{:L%e}", d);
else
os << "{today}";

while (++wd != firstdow) {
++d;

if (currDate != ym / d)
os << date::format(*locale_, " {:L%e}", d);
os << date::format(*m_locale_, " {:L%e}", d);
else
os << " {today}";
}
Expand All @@ -252,13 +264,13 @@ auto getCalendarLine(const year_month_day& currDate, const year_month ym, const
auto wd{firstdow};

if (currDate != ym / d)
os << date::format(*locale_, "{:L%e}", d);
os << date::format(*m_locale_, "{:L%e}", d);
else
os << "{today}";

while (++wd != firstdow && ++d <= dlast) {
if (currDate != ym / d)
os << date::format(*locale_, " {:L%e}", d);
os << date::format(*m_locale_, " {:L%e}", d);
else
os << " {today}";
}
Expand Down Expand Up @@ -328,7 +340,7 @@ auto waybar::modules::Clock::get_calendar(const year_month_day& today, const yea
if (line > 1) {
if (line < ml[(unsigned)ymTmp.month() - 1u]) {
os << fmt_lib::vformat(
locale_, fmtMap_[4],
m_locale_, fmtMap_[4],
fmt_lib::make_format_args(
(line == 2)
? static_cast<const date::zoned_seconds&&>(
Expand All @@ -344,15 +356,15 @@ auto waybar::modules::Clock::get_calendar(const year_month_day& today, const yea
os << Glib::ustring::format((cldWPos_ != WS::LEFT || line == 0) ? std::left : std::right,
std::setfill(L' '),
std::setw(cldMonColLen_ + ((line < 2) ? cldWnLen_ : 0)),
getCalendarLine(today, ymTmp, line, firstdow, &locale_));
getCalendarLine(today, ymTmp, line, firstdow, &m_locale_));

// Week numbers on the right
if (cldWPos_ == WS::RIGHT && line > 0) {
if (line > 1) {
if (line < ml[(unsigned)ymTmp.month() - 1u])
os << ' '
<< fmt_lib::vformat(
locale_, fmtMap_[4],
m_locale_, fmtMap_[4],
fmt_lib::make_format_args(
(line == 2) ? static_cast<const date::zoned_seconds&&>(
zoned_seconds{tz, local_days{ymTmp / 1}})
Expand All @@ -368,7 +380,7 @@ auto waybar::modules::Clock::get_calendar(const year_month_day& today, const yea
// Apply user's formats
if (line < 2)
tmp << fmt_lib::vformat(
locale_, fmtMap_[line],
m_locale_, fmtMap_[line],
fmt_lib::make_format_args(static_cast<const std::string_view&&>(os.str())));
else
tmp << os.str();
Expand All @@ -380,10 +392,10 @@ auto waybar::modules::Clock::get_calendar(const year_month_day& today, const yea
}

os << std::regex_replace(
fmt_lib::vformat(locale_, fmtMap_[2],
fmt_lib::vformat(m_locale_, fmtMap_[2],
fmt_lib::make_format_args(static_cast<const std::string_view&&>(tmp.str()))),
std::regex("\\{today\\}"),
fmt_lib::vformat(locale_, fmtMap_[3],
fmt_lib::vformat(m_locale_, fmtMap_[3],
fmt_lib::make_format_args(
static_cast<const std::string_view&&>(date::format("{:L%e}", d)))));

Expand Down Expand Up @@ -450,7 +462,7 @@ using deleting_unique_ptr = std::unique_ptr<T, deleter_from_fn<fn>>;
auto waybar::modules::Clock::first_day_of_week() -> weekday {
#ifdef HAVE_LANGINFO_1STDAY
deleting_unique_ptr<std::remove_pointer<locale_t>::type, freelocale> posix_locale{
newlocale(LC_ALL, locale_.name().c_str(), nullptr)};
newlocale(LC_ALL, m_locale_.name().c_str(), nullptr)};
if (posix_locale) {
const auto i{(int)((std::intptr_t)nl_langinfo_l(_NL_TIME_WEEK_1STDAY, posix_locale.get()))};
const weekday wd{year_month_day{year(i / 10000) / month(i / 100 % 100) / day(i % 100)}};
Expand Down

0 comments on commit d4413f5

Please sign in to comment.