From e16cce646b01aca6d4a3e64cee9811c5eeea1d2e Mon Sep 17 00:00:00 2001 From: Alexis Date: Fri, 10 Aug 2018 16:26:46 +0200 Subject: [PATCH] feat: add custom module to allow execution of external script --- include/factory.hpp | 1 + include/modules/custom.hpp | 24 ++++++++++++++++++ resources/config | 6 ++++- resources/style.css | 7 +++++- src/factory.cpp | 2 ++ src/modules/cpu.cpp | 1 - src/modules/custom.cpp | 50 ++++++++++++++++++++++++++++++++++++++ src/modules/network.cpp | 2 -- src/modules/pulseaudio.cpp | 2 -- 9 files changed, 88 insertions(+), 7 deletions(-) create mode 100644 include/modules/custom.hpp create mode 100644 src/modules/custom.cpp diff --git a/include/factory.hpp b/include/factory.hpp index 4ef56aae..3e459968 100644 --- a/include/factory.hpp +++ b/include/factory.hpp @@ -8,6 +8,7 @@ #include "modules/cpu.hpp" #include "modules/network.hpp" #include "modules/pulseaudio.hpp" +#include "modules/custom.hpp" namespace waybar { diff --git a/include/modules/custom.hpp b/include/modules/custom.hpp new file mode 100644 index 00000000..03c2b021 --- /dev/null +++ b/include/modules/custom.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include +#include +#include +#include +#include "util/chrono.hpp" +#include "IModule.hpp" + +namespace waybar::modules { + + class Custom : public IModule { + public: + Custom(std::string name, Json::Value config); + auto update() -> void; + operator Gtk::Widget &(); + private: + Gtk::Label _label; + waybar::util::SleeperThread _thread; + const std::string _name; + Json::Value _config; + }; + +} diff --git a/resources/config b/resources/config index 2bdc8738..ec17cf72 100644 --- a/resources/config +++ b/resources/config @@ -1,5 +1,5 @@ { - "modules-left": ["workspaces"], + "modules-left": ["workspaces", "custom/spotify"], "modules-right": ["pulseaudio", "network", "cpu", "memory", "battery", "clock"], "cpu": { "format": "{}% " @@ -17,5 +17,9 @@ "pulseaudio": { "format": "{}% ", "format-muted": "" + }, + "custom/spotify": { + "format": " {}", + "exec": "$HOME/.bin/mediaplayer.sh" } } diff --git a/resources/style.css b/resources/style.css index 6c5a412f..9457c8b6 100644 --- a/resources/style.css +++ b/resources/style.css @@ -23,7 +23,7 @@ window { border-bottom: 3px solid white; } -.clock, .battery, .cpu, .memory, .network, .pulseaudio { +.clock, .battery, .cpu, .memory, .network, .pulseaudio, .custom-spotify { padding: 0 10px; margin: 0 5px; } @@ -64,3 +64,8 @@ window { background: #90b1b1; color: #2a5c45; } + +.custom-spotify { + background: #66cc99; + color: #2a5c45; +} diff --git a/src/factory.cpp b/src/factory.cpp index 54589c5a..a5a034ff 100644 --- a/src/factory.cpp +++ b/src/factory.cpp @@ -20,5 +20,7 @@ waybar::IModule &waybar::Factory::makeModule(std::string name) return *new waybar::modules::Network(_config[name]); if (name == "pulseaudio") return *new waybar::modules::Pulseaudio(_config[name]); + if (!name.compare(0, 7, "custom/") && name.size() > 7) + return *new waybar::modules::Custom(name.substr(7), _config[name]); throw std::runtime_error("Unknown module: " + name); } diff --git a/src/modules/cpu.cpp b/src/modules/cpu.cpp index b953a4f7..6678c0ca 100644 --- a/src/modules/cpu.cpp +++ b/src/modules/cpu.cpp @@ -1,5 +1,4 @@ #include "modules/cpu.hpp" -#include waybar::modules::Cpu::Cpu(Json::Value config) : _config(config) diff --git a/src/modules/custom.cpp b/src/modules/custom.cpp new file mode 100644 index 00000000..693e2200 --- /dev/null +++ b/src/modules/custom.cpp @@ -0,0 +1,50 @@ +#include "modules/custom.hpp" +#include + +waybar::modules::Custom::Custom(std::string name, Json::Value config) + : _name(name), _config(config) +{ + _label.get_style_context()->add_class("custom-" + name); + if (!_config["exec"]) { + std::cerr << name + " has no exec path." << std::endl; + return; + } + _thread = [this] { + update(); + int interval = _config["interval"] ? _config["inveral"].asInt() : 30; + _thread.sleep_for(chrono::seconds(interval)); + }; +}; + +auto waybar::modules::Custom::update() -> void +{ + std::array buffer; + std::string output; + std::shared_ptr fp(popen(_config["exec"].asCString(), "r"), pclose); + if (!fp) { + std::cerr << _name + " can't exec " + _config["exec"].asString() << std::endl; + return; + } + while (!feof(fp.get())) { + if (fgets(buffer.data(), 128, fp.get()) != nullptr) + output += buffer.data(); + } + + // Remove last newline + if (!output.empty() && output[output.length()-1] == '\n') { + output.erase(output.length()-1); + } + + // Hide label if output is empty + if (output.empty()) + _label.hide(); + else { + auto format = _config["format"] ? _config["format"].asString() : "{}"; + _label.set_text(fmt::format(format, output)); + _label.show(); + } +} + +waybar::modules::Custom::operator Gtk::Widget &() { + return _label; +} diff --git a/src/modules/network.cpp b/src/modules/network.cpp index 6be39975..ad8d5e73 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -1,7 +1,5 @@ #include "modules/network.hpp" -#include - waybar::modules::Network::Network(Json::Value config) : _config(config), _ifid(if_nametoindex(config["interface"].asString().c_str())) { diff --git a/src/modules/pulseaudio.cpp b/src/modules/pulseaudio.cpp index 09524990..1b196cc5 100644 --- a/src/modules/pulseaudio.cpp +++ b/src/modules/pulseaudio.cpp @@ -1,7 +1,5 @@ #include "modules/pulseaudio.hpp" -#include - waybar::modules::Pulseaudio::Pulseaudio(Json::Value config) : _config(config), _mainloop(nullptr), _mainloop_api(nullptr), _context(nullptr), _sinkIdx(0), _volume(0), _muted(false)