fix(label): compare markup cache by raw bytes, not collation

2190871a (perf(label): skip redundant markup updates) caches the last
label/tooltip markup as Glib::ustring and skips set_markup() when the
new markup compares equal. Glib::ustring::operator== goes through
g_utf8_collate(), and under the UTF-8 locale GTK sets at startup,
Unicode private-use codepoints carry no collation weight. All nerd-font
icons live in the PUA, so two labels that differ only in their icon
glyph collate as equal and the visual update is silently dropped.

idle_inhibitor is the visible victim (#5169): clicking toggles the
state class (highlight changes) but the {icon} glyph never switches
between the activated/deactivated icons, while plain-text icons like
"YES"/"NO" work. Any ALabel module whose consecutive updates differ
only by a PUA glyph is affected. The module only started routing
through this cache when db4941ef migrated it onto the shared
setLabelMarkup()/setTooltipMarkup() helpers, which is why it broke in
the latest batch of refactors.

Store the cache as raw UTF-8 bytes (std::string via ustring::raw())
and compare those instead, so the skip only triggers on byte-identical
markup. Reproduced and verified under a nested niri session: before the
fix RTMIN+n toggled the state class but left the sleep glyph unchanged;
after it the glyph flips as expected, and byte-identical updates are
still skipped.
This commit is contained in:
Austin Horstman
2026-07-05 01:18:53 -05:00
parent 57c1ac789f
commit a51bddab9e
2 changed files with 9 additions and 6 deletions
+5 -2
View File
@@ -87,8 +87,11 @@ class ALabel : public AModule {
static void handleGtkMenuEvent(GtkMenuItem* menuitem, gpointer data);
private:
std::optional<Glib::ustring> last_label_markup_;
std::optional<Glib::ustring> last_tooltip_markup_;
// 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.
std::optional<std::string> last_label_markup_;
std::optional<std::string> last_tooltip_markup_;
};
} // namespace waybar