diff --git a/include/ALabel.hpp b/include/ALabel.hpp index 948289aea..2e94b5bcd 100644 --- a/include/ALabel.hpp +++ b/include/ALabel.hpp @@ -88,6 +88,8 @@ class ALabel : public AModule { static void handleGtkMenuEvent(GtkMenuItem* menuitem, gpointer data); private: + bool pointerOverModule() const; + // Raw UTF-8 bytes, not Glib::ustring: ustring::operator== collates with // g_utf8_collate(), which gives private-use codepoints (nerd-font icons) // no collation weight, so two different icons compare equal. diff --git a/src/ALabel.cpp b/src/ALabel.cpp index 23ee7851a..975e595e0 100644 --- a/src/ALabel.cpp +++ b/src/ALabel.cpp @@ -177,6 +177,19 @@ bool ALabel::setLabelMarkup(const Glib::ustring& markup) { return true; } +bool ALabel::pointerOverModule() const { + auto gdk_window = event_box_.get_window(); + if (!gdk_window || !event_box_.get_mapped()) { + return false; + } + int x = 0; + int y = 0; + Gdk::ModifierType mask; + gdk_window->get_device_position(gdk_window->get_display()->get_default_seat()->get_pointer(), x, + y, mask); + return x >= 0 && y >= 0 && x < gdk_window->get_width() && y < gdk_window->get_height(); +} + bool ALabel::setTooltipMarkup(const Glib::ustring& markup) { if (last_tooltip_markup_ == markup.raw()) { return false; @@ -184,7 +197,13 @@ bool ALabel::setTooltipMarkup(const Glib::ustring& markup) { last_tooltip_markup_ = markup.raw(); if (active_tooltip_) { - active_tooltip_->set_markup(markup); + // leave-notify is not always delivered when the pointer moves between + // adjacent modules, so active_tooltip_ may belong to another module. + if (pointerOverModule()) { + active_tooltip_->set_markup(markup); + } else { + active_tooltip_.reset(); + } } return true; }