Skip to content

fix(mpd): truncate before sanitization and improve tooltip UX#5064

Open
Siriusuna wants to merge 3 commits into
Alexays:masterfrom
Siriusuna:fix/mpd-markup-truncation
Open

fix(mpd): truncate before sanitization and improve tooltip UX#5064
Siriusuna wants to merge 3 commits into
Alexays:masterfrom
Siriusuna:fix/mpd-markup-truncation

Conversation

@Siriusuna
Copy link
Copy Markdown

@Siriusuna Siriusuna commented May 21, 2026

Context

This PR addresses two related issues involving visual string truncation and XML/HTML markup escaping in the mpd and mpris modules, preventing GTK/Pango markup parsing failures.

  1. MPD Module Entity Fragmentation: Currently, the MPD module runs sanitize_string on raw tags before performing truncation. This introduces a bug where XML entities (such as &) are truncated mid-sequence (e.g., into &am). When passed to the Pango parser via set_markup(), this triggers parsing errors, rendering the labels blank.
  2. MPRIS Module Raw Tooltip Crash: In the MPRIS module, raw track metadata was formatted directly into the tooltip template. If a track's title, artist, or album contained characters like & or <, passing the raw text to set_tooltip_markup() triggered GTK/Pango parsing warnings (e.g., "Entity did not end with a semicolon") and failed to render the tooltip entirely.

Changes

  • Shared UTF-8 Truncation Utility: Extracted the visual-width-aware truncation helper functions (utf8_truncate, utf8_width) from mpris.cpp into a common string utility under waybar::util (include/util/utf8_string.hpp and src/util/utf8_string.cpp) to enable clean code reuse.
  • Fixed MPRIS Tooltip Escaping: Wrapped track metadata fields (artist, title, and album) used in the MPRIS tooltip in Glib::Markup::escape_text before formatting, ensuring Pango-compliant strings are always delivered to the GTK tooltip markup.
  • Fixed MPD Truncation Order: Refactored the MPD module to perform visual-width-aware truncation on raw tags before running sanitize_string. This guarantees that truncation never cuts inside an escaped HTML/XML entity.
  • Added Modular Helpers in MPD: Added helper methods (getArtistStr, getAlbumArtistStr, getAlbumStr, getTitleStr) inside the MPD class to keep setLabel() clean and modular, matching the architectural style of the MPRIS module.
  • Added Custom Ellipsis Option to MPD: Introduced support for the ellipsis configuration option in the MPD module (consistent with MPRIS).
  • Improved MPD Tooltip UX: Decoupled the tooltip metadata from the main label's truncated text. The tooltip now displays complete, un-truncated metadata (properly escaped) to improve user experience.

Verification

  • Successfully compiled and ran the local test suite.
  • Tested locally with various configuration options on both modules (e.g., different "title-len", "ellipsis" or keep them unset) and render contents containing markup characters verifying that:
    • Main labels truncate correctly based on visual width (handling CJK and Emoji characters smoothly).
    • Tooltips display complete, un-truncated metadata safely without triggering GTK/Pango errors.

Siriusuna added 3 commits May 22, 2026 02:52
Move the UTF-8 visual-width measurement and truncation helper functions
from the mpris module to a common utility
(include/util/utf8_string.hpp and src/util/utf8_string.cpp).

This decouples string truncation and width measurement
from the mpris module, allowing other modules (like mpd) to reuse.
The helper function `utf8_truncate` (formerly `truncate` in mpris)
and `utf8_width` is exported under the `waybar::util` namespace,
while the low-level `measure_and_truncate` (formerly `utf8_truncate`)
is encapsulated in an anonymous namespace in src/util/utf8_string.cpp
to avoid unnecessary API exposure.

No functional changes were made to the mpris module's behavior.
Fix an issue where the mpris module's tooltip failed to render
when track metadata contained unescaped XML/HTML markup characters.

This occurred because
the mpris module formatted raw strings into the tooltip template
before passing the final string directly to `set_tooltip_markup()`,
triggering GTK/Pango parsing warnings and rendering failures.

Resolve this by wrapping tooltip metadata fields
in `Glib::Markup::escape_text` before formatting,
ensuring Pango-compliant strings are always delivered to the GTK
tooltip markup.
Fix an issue in the MPD module where text failed to render
when raw tags containing markup characters were truncated
mid-sequence after sanitization,
resulting in fragmented XML entities (such as `&amp;` cut into `&am`).

Resolve this by shifting the order of operations to
truncate the raw strings *before* running `sanitize_string`.
To keep `setLabel` decoupled and clean,
we introduce helper methods (`getArtistStr`, `getAlbumArtistStr`,
`getAlbumStr`, `getTitleStr`) inside the `MPD` class,
matching the architectural style of MPRIS.

Additionally:
- Introduce support for the customizable `ellipsis` config option
  (defaulting to `…`).
- Switch the truncation logic of the MPD module to be
  visual-width-aware using the newly extracted
  `waybar::util::utf8_truncate`.
- Decouple the tooltip text from the main label's truncated text.
  The tooltip now displays un-truncated, complete metadata
  (properly escaped), providing a significantly better user
  experience.
Copilot AI review requested due to automatic review settings May 21, 2026 19:21
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR centralizes UTF‑8 display-width measurement and truncation logic into a shared utility and updates media modules to use it, while also hardening MPRIS tooltip text handling.

Changes:

  • Added waybar::util::utf8_width / waybar::util::utf8_truncate helpers and wired them into the build.
  • Replaced duplicated UTF‑8 truncate/width logic in MPRIS with the shared utility.
  • Refactored MPD label/tooltip string construction to use helper getters and UTF‑8-aware truncation; added tooltip escaping for some MPRIS fields.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/util/utf8_string.cpp Implements shared UTF‑8 width + truncation logic.
include/util/utf8_string.hpp Declares the new UTF‑8 string utility API.
meson.build Adds the new utility source file to the build.
src/modules/mpris/mpris.cpp Removes local UTF‑8 helpers; uses shared utility; escapes tooltip text for select fields.
src/modules/mpd/mpd.cpp Uses shared UTF‑8 truncation and new getters for artist/album/title strings.
include/modules/mpd/mpd.hpp Adds ellipsis_ and new string getter declarations.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/util/utf8_string.cpp
Comment thread src/util/utf8_string.cpp
Comment thread src/modules/mpd/mpd.cpp
Comment thread src/modules/mpris/mpris.cpp
@Siriusuna
Copy link
Copy Markdown
Author

It seems like my copilot auto review is somehow enabled. Sorry about the noises.😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants