feat(custom): exec-if

pull/29/head
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
#include <fmt/format.h>
#include <iostream>
#include <sys/wait.h>
#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_;
};

View File

@ -46,6 +46,7 @@
"custom/spotify": {
"format": " {}",
"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 <iostream>
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<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));
};
}