diff --git a/include/modules/custom.hpp b/include/modules/custom.hpp index 4bd5fdbd..6d987b26 100644 --- a/include/modules/custom.hpp +++ b/include/modules/custom.hpp @@ -1,6 +1,8 @@ #pragma once #include +#include +#include #include "util/chrono.hpp" #include "ALabel.hpp" @@ -8,10 +10,10 @@ namespace waybar::modules { class Custom : public ALabel { public: - Custom(const std::string&, Json::Value); + Custom(std::string, Json::Value); auto update() -> void; private: - const std::string& name_; + std::string name_; waybar::util::SleeperThread thread_; }; diff --git a/resources/config b/resources/config index a9e107bc..03e028b3 100644 --- a/resources/config +++ b/resources/config @@ -46,6 +46,7 @@ "custom/spotify": { "format": " {}", "max-length": 40, - "exec": "$HOME/.bin/mediaplayer.sh" + "exec": "$HOME/.bin/mediaplayer.sh", + "exec-if": "pgrep spotify" } } diff --git a/src/modules/custom.cpp b/src/modules/custom.cpp index a76a88df..e192f808 100644 --- a/src/modules/custom.cpp +++ b/src/modules/custom.cpp @@ -1,15 +1,37 @@ #include "modules/custom.hpp" -#include -waybar::modules::Custom::Custom(const std::string &name, Json::Value config) - : ALabel(std::move(config)), name_(name) +waybar::modules::Custom::Custom(std::string name, Json::Value config) + : ALabel(std::move(config)), name_(std::move(name)) { if (!config_["exec"]) { throw std::runtime_error(name_ + " has no exec path."); } uint32_t interval = config_["interval"] ? config_["inveral"].asUInt() : 30; thread_ = [this, interval] { - Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Custom::update)); + bool can_update = true; + if (config_["exec-if"]) { + auto pid = fork(); + int res = 0; + if (pid == 0) { + std::istringstream iss(config_["exec-if"].asString()); + std::vector av; + for (std::string s; iss >> s;) { + // Need to copy otherwise values are the same + char *str = new char[s.size() + 1]; + memcpy(str, s.c_str(), s.size() + 1); + av.push_back(str); + } + av.push_back(0); + execvp(av.front(), av.data()); + _exit(127); + } else if (pid > 0 && waitpid(pid, &res, 0) != -1 + && WEXITSTATUS(res) != 0) { + can_update = false; + } + } + if (can_update) { + Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Custom::update)); + } thread_.sleep_for(chrono::seconds(interval)); }; }