mirror of
https://github.com/rad4day/Waybar.git
synced 2023-12-21 10:22:59 +01:00
b50650f63f
The MPD server has a connection_timeout that defaults to 60. If no data is transferred in this timespan, the connection is closed. If the connection is closed while the event listener is listening for events, it will block forever. By timing out the event listening and re-connecting regularly, we prevent this issue. An option "timeout" has been added for users that have a lower server connection_timeout than default. Fixes #277
71 lines
2.0 KiB
C++
71 lines
2.0 KiB
C++
#pragma once
|
|
|
|
#include <fmt/format.h>
|
|
#include <mpd/client.h>
|
|
#include <condition_variable>
|
|
#include <thread>
|
|
#include "ALabel.hpp"
|
|
|
|
namespace waybar::modules {
|
|
|
|
class MPD : public ALabel {
|
|
public:
|
|
MPD(const std::string&, const Json::Value&);
|
|
auto update() -> void;
|
|
|
|
private:
|
|
std::thread periodic_updater();
|
|
std::string getTag(mpd_tag_type type, unsigned idx = 0);
|
|
void setLabel();
|
|
std::string getStateIcon();
|
|
std::string getOptionIcon(std::string optionName, bool activated);
|
|
|
|
std::thread event_listener();
|
|
|
|
// Assumes `connection_lock_` is locked
|
|
void tryConnect();
|
|
// If checking errors on the main connection, make sure to lock it using
|
|
// `connection_lock_` before calling checkErrors
|
|
void checkErrors(mpd_connection* conn);
|
|
|
|
// Assumes `connection_lock_` is locked
|
|
void fetchState();
|
|
void waitForEvent();
|
|
|
|
bool handlePlayPause(GdkEventButton* const&);
|
|
|
|
bool stopped();
|
|
bool playing();
|
|
|
|
const std::string module_name_;
|
|
|
|
using unique_connection = std::unique_ptr<mpd_connection, decltype(&mpd_connection_free)>;
|
|
using unique_status = std::unique_ptr<mpd_status, decltype(&mpd_status_free)>;
|
|
using unique_song = std::unique_ptr<mpd_song, decltype(&mpd_song_free)>;
|
|
|
|
// Not using unique_ptr since we don't manage the pointer
|
|
// (It's either nullptr, or from the config)
|
|
const char* server_;
|
|
const unsigned port_;
|
|
|
|
unsigned timeout_;
|
|
|
|
// We need a mutex here because we can trigger updates from multiple thread:
|
|
// the event based updates, the periodic updates needed for the elapsed time,
|
|
// and the click play/pause feature
|
|
std::mutex connection_lock_;
|
|
unique_connection connection_;
|
|
// The alternate connection will be used to wait for events: since it will
|
|
// be blocking (idle) we can't send commands via this connection
|
|
//
|
|
// No lock since only used in the event listener thread
|
|
unique_connection alternate_connection_;
|
|
|
|
// Protect them using the `connection_lock_`
|
|
unique_status status_;
|
|
mpd_state state_;
|
|
unique_song song_;
|
|
};
|
|
|
|
} // namespace waybar::modules
|