feat(custom): exec-if

This commit is contained in:
Alexis 2018-08-18 17:27:40 +02:00
parent 38ede5b3d5
commit b794ca63d1
3 changed files with 32 additions and 7 deletions

View File

@ -1,6 +1,8 @@
#pragma once #pragma once
#include <fmt/format.h> #include <fmt/format.h>
#include <iostream>
#include <sys/wait.h>
#include "util/chrono.hpp" #include "util/chrono.hpp"
#include "ALabel.hpp" #include "ALabel.hpp"
@ -8,10 +10,10 @@ namespace waybar::modules {
class Custom : public ALabel { class Custom : public ALabel {
public: public:
Custom(const std::string&, Json::Value); Custom(std::string, Json::Value);
auto update() -> void; auto update() -> void;
private: private:
const std::string& name_; std::string name_;
waybar::util::SleeperThread thread_; waybar::util::SleeperThread thread_;
}; };

View File

@ -46,6 +46,7 @@
"custom/spotify": { "custom/spotify": {
"format": " {}", "format": " {}",
"max-length": 40, "max-length": 40,
"exec": "$HOME/.bin/mediaplayer.sh" "exec": "$HOME/.bin/mediaplayer.sh",
"exec-if": "pgrep spotify"
} }
} }

View File

@ -1,15 +1,37 @@
#include "modules/custom.hpp" #include "modules/custom.hpp"
#include <iostream>
waybar::modules::Custom::Custom(const std::string &name, Json::Value config) waybar::modules::Custom::Custom(std::string name, Json::Value config)
: ALabel(std::move(config)), name_(name) : ALabel(std::move(config)), name_(std::move(name))
{ {
if (!config_["exec"]) { if (!config_["exec"]) {
throw std::runtime_error(name_ + " has no exec path."); throw std::runtime_error(name_ + " has no exec path.");
} }
uint32_t interval = config_["interval"] ? config_["inveral"].asUInt() : 30; uint32_t interval = config_["interval"] ? config_["inveral"].asUInt() : 30;
thread_ = [this, interval] { 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<char*> 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)); thread_.sleep_for(chrono::seconds(interval));
}; };
} }