The tooltip selection block redundantly reassigned tooltip_format to
config_["tooltip-format"], overwriting the state-specific format (and
emptying it when no global tooltip-format was set). A lone
tooltip-format-<state> therefore produced an empty tooltip.
Consolidate the tooltip handling into a single block that prefers
tooltip-format-<state>, falls back to the global tooltip-format, then to
the computed default tooltip, reusing the existing format arg store.
The zero-on-mute display_value = min_ assignment was nested inside the
!previously_muted transition branch, so subsequent updates while still
muted re-displayed the real volume. Apply it on every update as long as
the target is muted, keeping the CSS class add/remove on transitions only.
std::setfill is templated on the fill char type, which must match the
Glib::ustring FormatStream's char type. That type is wchar_t with
libstdc++/glibmm but char with libc++, so no fixed literal (' ' or L' ')
compiles everywhere. The stream's default fill is already a space, so
drop std::setfill entirely; std::setw/std::left/std::right are
char-type-agnostic and keep the exact padding behavior.
Reporting a full battery on AC as 'Plugged' is now opt-in via the
'full-at-plugged' config option (default false), so existing format-full /
tooltip-format-full setups keep working. Also documents the option.
Only stretch buttons and ellipsize titles when the new boolean 'expand'
option is enabled and the bar is horizontal. Restores the previous
content-based sizing as the default and avoids truncating every title
to an ellipsis on vertical bars.
Store the retry timeout connection in a Host member and disconnect it in
~Host, so a Host destroyed within the retry window no longer invokes the
timeout callback on freed memory. Cap the retries (MAX_RETRIES) so a
watcher that never reappears no longer spins forever every 200ms; reset
the counter on success and when the watcher name vanishes.
Replace the getSocket1JsonReply("reload") call in onSpecialWorkspaceActivated
with the module's normal local refresh path: the state update to
m_activeSpecialWorkspaceName is picked up by the update() render (triggered by
the dp.emit() already issued at the end of onEvent), which re-evaluates active
state, icons and CSS classes. This avoids reloading the entire Hyprland config
on every special workspace activation while keeping the special-active icon and
CSS improvements.