Skip to content

Commit

Permalink
Add mpris module
Browse files Browse the repository at this point in the history
Uses libplayerctl to use the MPRIS dbus protocol to query, listen and
control media players.

Signed-off-by: Robert Günzler <r@gnzler.io>
  • Loading branch information
robertgzr committed Dec 13, 2022
1 parent b5c686c commit ac9ebfc
Show file tree
Hide file tree
Showing 8 changed files with 447 additions and 1 deletion.
3 changes: 3 additions & 0 deletions include/factory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
#ifdef HAVE_DBUSMENU
#include "modules/sni/tray.hpp"
#endif
#ifdef HAVE_MPRIS
#include "modules/mpris/mpris.hpp"
#endif
#ifdef HAVE_LIBNL
#include "modules/network.hpp"
#endif
Expand Down
54 changes: 54 additions & 0 deletions include/modules/mpris/mpris.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#pragma once

#include <iostream>
#include <string>

#include "gtkmm/box.h"
#include "gtkmm/label.h"

extern "C" {
#include <playerctl/playerctl.h>
}

#include "ALabel.hpp"
#include "util/sleeper_thread.hpp"

namespace waybar::modules::mpris {

class Mpris : public AModule {
public:
Mpris(const std::string&, const Json::Value&);
~Mpris();
auto update() -> void;
bool handleToggle(GdkEventButton* const&);

private:
const std::string DEFAULT_FORMAT = "{player} ({status}): {dynamic}";

static void nameAppeared_cb(PlayerctlPlayerManager*, PlayerctlPlayerName*, gpointer);
static void playerVanished_cb(PlayerctlPlayerManager*, PlayerctlPlayer*, gpointer);
static void playerPlay_cb(PlayerctlPlayer*, gpointer);
static void playerPause_cb(PlayerctlPlayer*, gpointer);
static void playerStop_cb(PlayerctlPlayer*, gpointer);
static void playerMetadata_cb(PlayerctlPlayer*, GVariant*, gpointer);
PlayerctlPlayer* get_top_player(PlayerctlPlayerManager*);
std::string getIcon(const std::string &);

Gtk::Box box_;
Gtk::Label label_;

// config
std::string format = DEFAULT_FORMAT;
std::string format_playing = "";
std::string format_paused = "";
std::string format_stopped = "";
std::chrono::seconds interval = std::chrono::seconds(180);

PlayerctlPlayerManager *manager;
std::string lastStatus;
std::string lastPlayer;

util::SleeperThread thread_;
};

} // namespace waybar::modules::mpris
84 changes: 84 additions & 0 deletions man/waybar-mpris.5.scd
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
waybar-upower(5)

# NAME

waybar - MPRIS module

# DESCRIPTION

The *mpris* module displays currently playing media via libplayerctl.++

# CONFIGURATION

*interval*: ++
typeof: integer ++
Refresh MPRIS information on a timer

*format*: ++
typeof: string ++
default: {player} ({status}) {dynamic} ++
The text format.

*format-[status]*: ++
typeof: string ++
The status-specific text format.

*format-icons*: ++
typeof: map[string]string
Allows setting "{status-icon}" and "{player-icon}"

*on-click*: ++
typeof: string ++
default: play-pause ++
Overwrite default action toggles

*on-middle-click*: ++
typeof: string ++
default: previous track ++
Overwrite default action toggles

*on-right-click*: ++
typeof: string ++
default: next track ++
Overwrite default action toggles

# FORMAT REPLACEMENTS

*{player}*: The name of the current media player

*{status}*: The current status (playing, paused, stopped)

*{artist}*: The artist of the current track

*{album}*: The album title of the current track

*{title}*: The title of the current track

*{dynamic}*: Dynamically concatenates "{artist} - {album} - {title}", based++
on if the values are populated by the player

*{player-icon}*: Chooses an icon from "format-icons" based on "{player}"

*{status-icon}*: Chooses an icon from "format-icons" based on "{status}"

# EXAMPLES

```
"mpris": {
"format": "{player_icon} {dynamic}",
"format-paused": "{status_icon} <i>{dynamic}</i>",
"format-icons": {
"default": "♫",
"paused": "⏸",
"playing": "⏵",
"stopped": "⏹",
}
}
```

# STYLE

- *#mpris*
- *#mpris.[status]*
- *#mpris.[player]*
1 change: 1 addition & 0 deletions man/waybar.5.scd.in
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ A module group is defined by specifying a module named "group/some-group-name".
- *waybar-keyboard-state(5)*
- *waybar-memory(5)*
- *waybar-mpd(5)*
- *waybar-mpris(5)*
- *waybar-network(5)*
- *waybar-pulseaudio(5)*
- *waybar-river-mode(5)*
Expand Down
12 changes: 11 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,10 @@ wayland_cursor = dependency('wayland-cursor')
wayland_protos = dependency('wayland-protocols')
gtkmm = dependency('gtkmm-3.0', version : ['>=3.22.0'])
dbusmenu_gtk = dependency('dbusmenu-gtk3-0.4', required: get_option('dbusmenu-gtk'))
giounix = dependency('gio-unix-2.0', required: (get_option('dbusmenu-gtk').enabled() or get_option('logind').enabled() or get_option('upower_glib').enabled()))
giounix = dependency('gio-unix-2.0', required: (get_option('dbusmenu-gtk').enabled() or
get_option('logind').enabled() or
get_option('upower_glib').enabled() or
get_option('mpris').enabled()))
jsoncpp = dependency('jsoncpp', version : ['>=1.9.2'], fallback : ['jsoncpp', 'jsoncpp_dep'])
sigcpp = dependency('sigc++-2.0')
libinotify = dependency('libinotify', required: false)
Expand All @@ -95,6 +98,7 @@ libinput = dependency('libinput', required: get_option('libinput'))
libnl = dependency('libnl-3.0', required: get_option('libnl'))
libnlgen = dependency('libnl-genl-3.0', required: get_option('libnl'))
upower_glib = dependency('upower-glib', required: get_option('upower_glib'))
playerctl = dependency('playerctl', version : ['>=2.0.0'], required: get_option('mpris'))
libpulse = dependency('libpulse', required: get_option('pulseaudio'))
libudev = dependency('libudev', required: get_option('libudev'))
libevdev = dependency('libevdev', required: get_option('libevdev'))
Expand Down Expand Up @@ -238,6 +242,11 @@ if (upower_glib.found() and giounix.found() and not get_option('logind').disable
src_files += 'src/modules/upower/upower_tooltip.cpp'
endif

if (playerctl.found() and giounix.found() and not get_option('logind').disabled())
add_project_arguments('-DHAVE_MPRIS', language: 'cpp')
src_files += 'src/modules/mpris/mpris.cpp'
endif

if libpulse.found()
add_project_arguments('-DHAVE_LIBPULSE', language: 'cpp')
src_files += 'src/modules/pulseaudio.cpp'
Expand Down Expand Up @@ -334,6 +343,7 @@ executable(
libnl,
libnlgen,
upower_glib,
playerctl,
libpulse,
libjack,
libwireplumber,
Expand Down
1 change: 1 addition & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ option('libudev', type: 'feature', value: 'auto', description: 'Enable libudev s
option('libevdev', type: 'feature', value: 'auto', description: 'Enable libevdev support for evdev related features')
option('pulseaudio', type: 'feature', value: 'auto', description: 'Enable support for pulseaudio')
option('upower_glib', type: 'feature', value: 'auto', description: 'Enable support for upower')
option('mpris', type: 'feature', value: 'auto', description: 'Enable support for mpris')
option('systemd', type: 'feature', value: 'auto', description: 'Install systemd user service unit')
option('dbusmenu-gtk', type: 'feature', value: 'auto', description: 'Enable support for tray')
option('man-pages', type: 'feature', value: 'auto', description: 'Generate and install man pages')
Expand Down
5 changes: 5 additions & 0 deletions src/factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name) const {
return new waybar::modules::upower::UPower(id, config_[name]);
}
#endif
#ifdef HAVE_MPRIS
if (ref == "mpris") {
return new waybar::modules::mpris::Mpris(id, config_[name]);
}
#endif
#ifdef HAVE_SWAY
if (ref == "sway/mode") {
return new waybar::modules::sway::Mode(id, config_[name]);
Expand Down

0 comments on commit ac9ebfc

Please sign in to comment.