Skip to content

Add show_dividers option to draw a line between items - #68

Open
HoneyHazard wants to merge 2 commits into
tsowell:mainfrom
HoneyHazard:item-dividers
Open

Add show_dividers option to draw a line between items#68
HoneyHazard wants to merge 2 commits into
tsowell:mainfrom
HoneyHazard:item-dividers

Conversation

@HoneyHazard

@HoneyHazard HoneyHazard commented Aug 6, 2026

Copy link
Copy Markdown

⚠️ Full Disclosure: Drafted with AI assistance (Claude); reviewed by me briefly. I am neither a RUST developer nor pipewire expert. If I should stop making these PRs into your wonderful project, please let me know. ⚠️

That being said, I hope these can be helpful and useful additions that users could appreciate.


Item rows already have a gap between them (NodeWidget::spacing()/DeviceWidget::spacing()), but that space is always blank. On a list with many similarly-styled rows it can be hard to tell at a glance where one item ends and the next begins, especially on a low-contrast theme.

Divider lines drawn between items, centered with a blank row on either side

Default theme with --show-dividers on the command line.

Adds show_dividers: bool (default false) plus a new divider theme key and divider char_set glyph:

  • When enabled, draws a one-row line spanning the item's width, styled by theme.divider and built from char_set.divider (a single glyph, repeated to fill the width - same pattern as volume_filled/volume_empty).
  • The divider is centered in the gap between items - one blank row above it, one below - rather than hugging whichever item happens to sit above it. To make room for that, turning show_dividers on reserves one extra row of spacing per item (so fewer items fit on screen at once than with it off); with show_dividers off, spacing - and the whole list's layout - is completely untouched, matching stock wiremix exactly.
  • No divider is drawn after the last visible item, so it never touches the footer/tab bar.
  • Off by default, so it's a no-op for any existing config.
  • Both the Playback/Recording/Output/Input Devices node list (NodeWidget-based) and the Configuration tab's device list (DeviceWidget-based) go through the same object_list.rs render loop, so a single render_divider() helper covers both list kinds.

New config keys (all optional, no-op when unset):

show_dividers = false

[themes.default]
divider = { fg = "DarkGray" }

[char_sets.default]
divider = ""

Also available as --show-dividers/--no-show-dividers on the command line.

Tested:

  • cargo test --release: 148/148 passing, including tests covering the disabled no-op case, the enabled case drawing the glyph centered with a blank row on each side, clipping at the list's bottom edge without panicking, and that show_dividers reserves the extra row of spacing only when it's actually on (confirmed by comparing how many items fit in an identical Rect with it on vs. off)
  • cargo fmt --check / cargo clippy -- -D warnings / cargo doc (matching this repo's CI): all clean
  • Manually verified in tmux with --show-dividers: the divider line renders centered between every pair of adjacent items, with a real terminal-row-count difference from leaving it off (5 items fit per screen without dividers vs. 4 with, at the same terminal size) - and that leaving the option unset reproduces stock behavior exactly, byte-for-byte the same layout as before this PR

Drafted with AI assistance (Claude); reviewed by me before opening. Left as a draft while I finish going through it - not requesting review yet.

Item rows already have a 2-row gap between them (NodeWidget::spacing()/
DeviceWidget::spacing()), but that space is always blank. On a list with
many similarly-styled rows it can be hard to tell at a glance where one
item ends and the next begins, especially at a glance or on a low-contrast
theme.

Adds show_dividers: bool (default false) plus a new divider theme key and
divider char_set glyph. When enabled, draws a one-row line spanning the
item's width in the gap immediately below it, styled by theme.divider and
built from char_set.divider (a single glyph, repeated to fill the width -
same pattern as volume_filled/volume_empty). No divider is drawn after the
last visible item, so it never touches the footer/tab bar.

Since the divider only ever draws into the gap row that already exists
between items, turning it on never changes the list's layout or item
spacing - only what's drawn in space that was already blank. Off by
default, so it's a no-op for any existing config.

Both the Playback/Recording/Output/Input Devices node list
(NodeWidget-based) and the Configuration tab's device list
(DeviceWidget-based) go through the same object_list.rs render loop, so a
single render_divider() helper covers both list kinds.

Tested: cargo test --release (147/147 passing, including 3 new tests
covering the disabled no-op case, the enabled case drawing the glyph
across the full width, and clipping at the list's bottom edge without
panicking). cargo fmt --check, cargo clippy -- -D warnings, and cargo doc
(all matching wiremix's CI) clean. Manually verified in tmux with
--show-dividers that the divider line renders between every pair of
adjacent items without disturbing layout, and that leaving the option
unset reproduces stock behavior exactly.
@HoneyHazard
HoneyHazard marked this pull request as ready for review August 8, 2026 03:49
Dividers previously drew into the first row of the existing 2-row gap
between items, immediately below whichever item sat above - one blank
row below the divider, none above it. Now, whenever show_dividers is
on, one extra row of spacing is reserved per item (2 -> 3) so the
divider can sit on the middle row instead: one blank row above it, one
below, symmetric with respect to both neighboring items.

With show_dividers off (the default), spacing and the whole list's
layout are completely untouched - same row count, same scroll/page
math, same everything as before this change and as stock wiremix.

ObjectList::update()/visible_objects() (and the private visible_count()
they both rely on) now take a show_dividers bool so their scroll/
viewport math can agree with the extra row ObjectListWidget::render()
reserves per item - previously this was implicit and only render() knew
about it.
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.

1 participant