diff --git a/include/ALabel.hpp b/include/ALabel.hpp index 3e3690b10..948289aea 100644 --- a/include/ALabel.hpp +++ b/include/ALabel.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -92,6 +93,7 @@ class ALabel : public AModule { // no collation weight, so two different icons compare equal. std::optional last_label_markup_; std::optional last_tooltip_markup_; + Glib::RefPtr active_tooltip_; }; } // namespace waybar diff --git a/src/ALabel.cpp b/src/ALabel.cpp index 3af6f5a3f..23ee7851a 100644 --- a/src/ALabel.cpp +++ b/src/ALabel.cpp @@ -42,6 +42,26 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st } label_.get_style_context()->add_class(MODULE_CLASS); event_box_.add(label_); + if (tooltipEnabled()) { + // Keep dynamic tooltip contents out of GtkWidget's tooltip-markup property. + // Setting that property queues a display-wide tooltip query, which restarts + // GTK's hover delay when modules update faster than the delay can expire. + label_.set_has_tooltip(true); + label_.signal_query_tooltip().connect( + [this](int, int, bool, const Glib::RefPtr& tooltip) { + if (!last_tooltip_markup_.has_value() || last_tooltip_markup_->empty()) { + active_tooltip_.reset(); + return false; + } + active_tooltip_ = tooltip; + tooltip->set_markup(*last_tooltip_markup_); + return true; + }); + event_box_.signal_leave_notify_event().connect([this](GdkEventCrossing*) { + active_tooltip_.reset(); + return false; + }); + } if (config_["max-length"].isUInt()) { label_.set_max_width_chars(config_["max-length"].asInt()); label_.set_ellipsize(Pango::EllipsizeMode::ELLIPSIZE_END); @@ -162,8 +182,10 @@ bool ALabel::setTooltipMarkup(const Glib::ustring& markup) { return false; } - label_.set_tooltip_markup(markup); last_tooltip_markup_ = markup.raw(); + if (active_tooltip_) { + active_tooltip_->set_markup(markup); + } return true; }