Skip to content

sandwichfarm/deckbar

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Deckbar

Module-based Waybar custom modules for controlling media players. The default player module is feishin, and Deckbar also ships modules for popular Linux players that expose the standard MPRIS surface through playerctl.

This is not a Feishin plugin or a direct Feishin API integration. It is a Waybar/playerctl control surface with player modules for detection, visibility, metadata, controls, labels, and generated Waybar snippets.

Requirements

  • Linux desktop session with Waybar
  • python3 3.11 or newer
  • playerctl
  • A supported MPRIS media player

The selected player must appear as an MPRIS player:

playerctl -l

Quick Start

./install.sh
deckbar doctor
deckbar generate waybar
deckbar generate css

The default install copies package files to ~/.local/share/deckbar, installs ~/.local/bin/deckbar, removes old playerctl-waybar and feishin-waybar wrappers/package files if present, and writes ~/.config/deckbar/config.toml if it does not already exist.

To patch the active Waybar config and style files with backups:

./install.sh --apply-waybar

The apply command updates ~/.config/waybar/config.jsonc and ~/.config/waybar/style.css between deckbar marker blocks. Existing files are backed up with .deckbar.<timestamp>.bak suffixes before edits.

Commands

deckbar doctor
deckbar modules
deckbar status track
deckbar status play_pause
deckbar action play-pause
deckbar action stop
deckbar action next
deckbar action previous
deckbar action shuffle
deckbar action loop
deckbar generate waybar
deckbar generate css

status commands print Waybar JSON. action commands dispatch through the selected player module.

Configuration

Primary config path:

~/.config/deckbar/config.toml

Override the path for testing:

DECKBAR_CONFIG=/path/to/config.toml deckbar status track

Important fields and sections:

  • module: selected player module. Default: feishin.
  • player: optional MPRIS player name override. If omitted, the selected module uses its documented default player name.
  • unavailable_mode: set to hidden to hide modules when the selected player is closed, or status to show an unavailable status label.
  • [visible]: show or hide track, previous, play_pause, stop, next, shuffle, and loop.
  • [labels]: change icons/text labels.
  • [colors]: change generated CSS colors.
  • [waybar]: set realtime signal and module insertion position.

See examples/config.toml.

Player Modules

The module system separates player-specific behavior from core Waybar rendering.

The core handles:

  • CLI routing
  • Waybar JSON rendering
  • generated Waybar config and CSS
  • install/apply helpers
  • shared labels, colors, visibility, and intervals

Player modules handle:

  • availability detection
  • metadata/status lookup
  • playback actions
  • shuffle and loop semantics
  • module-specific diagnostics
  • generated module names and CSS class prefixes

Bundled modules:

Module Player Default MPRIS name Notes
feishin Feishin Feishin Default module. Existing custom/feishin-* generated names remain stable.
spotify Spotify desktop client spotify Some packages expose limited shuffle or loop behavior.
vlc VLC vlc Works for local music and mixed media playback when VLC exposes MPRIS.
rhythmbox Rhythmbox rhythmbox GNOME-oriented local library player.
strawberry Strawberry strawberry Strawberry documents MPRIS2 support.
audacious Audacious audacious MPRIS behavior depends on the Audacious MPRIS plugin/support in the installed build.
tauon Tauon Music Box tauon Tauon documents playerctl/MPRIS remote control on Linux.
mpv mpv mpv Requires an MPRIS plugin such as mpv-mpris; plain mpv does not expose MPRIS by default.

To use another bundled module:

module = "spotify"

If playerctl -l reports a different name, keep the module and override the target player:

module = "spotify"
player = "spotifyd"

Then verify:

deckbar modules
deckbar doctor
deckbar generate waybar
deckbar generate css

Writing a Player Module

Most local Linux players should add one file under src/deckbar/modules/ and subclass LocalMprisModule from src/deckbar/modules/base.py. Use a custom PlayerModule implementation only when the player cannot honestly fit the local MPRIS/playerctl behavior.

For a simple local MPRIS player:

  1. Add src/deckbar/modules/<module_id>.py.
  2. In that file, add a class that calls LocalMprisModule.__init__ with:
    • id: stable config value used by module = "...".
    • display_name: human-readable name shown by diagnostics.
    • backend_name: normally local-mpris-playerctl.
    • class_prefix: prefix for generated Waybar names and CSS classes.
    • mpris_player: default value expected from playerctl -l.
  3. Add a create_module() function that returns one instance of that class. Deckbar discovers bundled module files at startup and builds the in-memory registry from these factories.
  4. Keep generated names stable. class_prefix = "example" creates custom/example-track, custom/example-play, #custom-example-track, and classes like example-play-pause.
  5. Add or update tests for discovery, default player selection, generated Waybar names, generated CSS selectors, hidden unavailable output, and any player-specific behavior.
  6. Document the module in this README, including default MPRIS name, prerequisites, and caveats.

Discovery is deterministic and limited to bundled files inside deckbar.modules; it is not a third-party plugin loader. Support files such as base.py and discovery.py are skipped. Override is_present, track, playback_status, shuffle_status, loop_status, do_action, or capabilities only when the player differs from normal MPRIS/playerctl semantics. Do not add player-specific branches to the core Waybar renderer unless the module interface is missing a hook.

Waybar Integration

The generated modules use one custom module per clickable control. This is intentional: Waybar binds click handlers to modules, not substrings inside a single label.

Add the generated custom/feishin-* module names to one of your Waybar module arrays, then add the generated module definitions at top level and append the generated CSS.

deckbar generate waybar
deckbar generate css

After clicking a control, the generated handlers send SIGRTMIN+9 to Waybar so all player modules refresh together.

Migration Notes

v0.4 renames the project to Deckbar.

  • The old playerctl-waybar and feishin-waybar commands are removed by ./install.sh.
  • The old internal Python package paths playerctl_waybar and feishin_waybar are gone.
  • Use ~/.config/deckbar/config.toml.
  • Existing custom/feishin-* Waybar module names remain stable for the Feishin module.

Troubleshooting

If Feishin is closed and unavailable_mode = "hidden", the status commands return valid Waybar JSON with empty text. To show an unavailable label instead:

unavailable_mode = "status"

If the widget says Feishin is unavailable or stays hidden while Feishin is open:

deckbar doctor
deckbar modules
playerctl -l
playerctl -p Feishin status

If Feishin is running but listed under a different player name, update:

player = "YourPlayerName"

If Waybar does not show Pango-colored artist/title text, make sure the generated module definitions include:

"escape": false

Development

PYTHONPATH=src python3 -m deckbar.cli doctor
PYTHONPATH=src python3 -m unittest discover -s tests -v

About

A waybar widget to control MPRIS via playerctl

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors