mpd-qt6
Garnetune
A desktop MPD client written in Crystal using Qt6 shard.
Screenshots

Features
- Playback controls with progress seeking, shuffle/repeat, volume control, and current song metadata.
- Album art support, including a full-size cover preview and optional blurred cover background in the playback header.
- Queue management with multi-select, drag-and-drop reordering, keyboard playback, row removal, and context menu actions.
- Library browser grouped by artist, album, and song, with natural album/year and disc/track sorting.
- Library search by artist, album, title, and file path, plus genre filtering from MPD's database tags.
- Drag artists, albums, songs, or stored playlist tracks into the queue, including insertion at the drop position.
- Saved playlist management: browse MPD playlists, preview songs, save the current queue, rename/delete playlists, append playlists to the queue, or replace the queue with a playlist.
- Configurable MPD connection and optional Last.fm scrobbling.
- MPD output management for enabling or disabling configured audio outputs.
- Linux desktop integration through MPRISv2 for media keys, desktop media widgets, metadata, position, volume, shuffle/repeat, and cover art.
- System tray support with close-to-tray behavior, restore/show toggle, and playback actions.
- Persistent UI preferences for layout, expanded mode, menu visibility, blurred cover background, window size, and splitter sizes.
Requirements
- Crystal >= 1.19.1
- Qt6 Widgets development packages
- Arch:
pacman -S qt6-base - Ubuntu:
apt-get install qt6-base-dev - macOS:
brew install qt
- Arch:
- A running MPD server
Installation
git clone https://github.com/mamantoha/mpd-qt6
cd mpd-qt6
shards install
shards build --release -Dpreview_mt
./bin/garnetune
Dependencies
| Shard | Purpose |
|---|---|
| djberg96/crystal-qt6 | Qt6 bindings for Crystal |
| mamantoha/crystal_mpd | MPD protocol client |
Platform support
Tested on Linux and macOS with Qt6. Windows are untested.
Architecture notes
src/mpd_ui/app.crowns the mainAppclass and acts mostly as the composition root: it loads settings, creates the Qt application/window, wires views/controllers/adapters together, starts MPD, and runs the Qt event loop- Domain/service objects keep non-Qt behavior isolated:
song.crandplayback_state.crwrap MPD song metadata and current playback statecover_art_service.crfetches MPD cover art and handles the disk cover cachelibrary_index.crhandles database filtering, artist/album/song grouping, album sorting by year, and song sorting by disc/trackbackground_task.crcentralizes short worker-thread jobs and Qt-main-thread callbacks
- View classes under
src/mpd_ui/views/own Qt widget construction and rendering:application_menu.crbuilds the main menu/actions and menu shortcutsapp_layout_view.crarranges the player header, library/queue splitter, and compact spacerplayer_header_view.crowns the playback header widgets, controls, volume popup, cover click handling, and progress tooltipqueue_view.crowns the queueQTreeView, model rendering, context menu, shortcuts, selection helpers, drop filter, and row indicatorslibrary_view.crowns the database browser tree, search panel, genre filter, custom item delegate, context menu, drag filter, and selected URI collectionplaylists_view.crowns the saved playlist browser, playlist context menu, song preview, and playlist-song drag source
- Controller classes under
src/mpd_ui/controllers/keep state transitions and queue calculations away from Qt widget setup:player_controller.crreads MPD status/current-song/playlist snapshots and converts them intoPlaybackStatetransitionsqueue_controller.crtracks queue positions/ids and plans multi-row reorders
- App glue modules under
src/mpd_ui/app/connect views/controllers/services to MPD commands and UI state:player.crhandles playback refresh, progress, volume, cover rendering, blurred header background, and current-song UI updatesqueue.crwiresQueueView/QueueControllerto MPD queue commands and database-to-queue dropsdatabase.crwiresLibraryView/LibraryIndexto MPD database loading, searching, genre filtering, and add-to-queue behaviorplaylists.crwiresPlaylistsViewto MPD saved playlist commandsmpris.crconnects Qt/MPD callbacks to the app-specific MPRIS adapterlastfm.crfeeds playback snapshots into the app-specific Last.fm adapteroutputs.crloads MPD audio outputs and applies output enable/disable commands from the UIwindow_events.crhandles main-window close/show/hide/resize policy, including close-to-tray when a tray icon exists and expanded-window size trackingtray.crhandles only system tray integration: tray icon/menu setup, tray activation, tray messages, tray state, and tray tooltip updatesabout_dialog.crandsettings_dialog.crkeep dialogs isolated from the main UI setup
src/mpd_ui/adapters/contains app-specific integration adapters:mpris_adapter.crownsMPRIS::Service, callback registration, playback-state mapping, current MPRIS song/artwork state, and position sync throttlinglastfm_adapter.crowns Last.fm client/scrobbler construction and playback sync
src/ext/mpriscontains a small Crystal MPRIS/DBus implementation kept separate from Qt-specific app codesrc/ext/lastfmcontains the Last.fm API client, request signing, scrobble timing, and retry cache- One MPD client handles commands and status reads
- A separate callback-enabled MPD listener pushes live updates from the server
EventBridgemarshals callback-thread updates safely onto the Qt main threadSettingswrapsQSettingspersistence for connection details, UI visibility preferences, layout size, and splitter state- The UI uses Qt Widgets directly, including
QMainWindow, menus/actions, push buttons, sliders, splitters, tree views, standard item models, custom item delegates, event filters, shortcuts, and graphics effects
License
MIT
Repository
mpd-qt6
Owner
Statistic
- 2
- 0
- 0
- 0
- 2
- about 6 hours ago
- April 16, 2026
License
MIT License
Links
Synced at
Wed, 27 May 2026 11:41:04 GMT
Languages