refactor(script): Merge back script handling
This commit is contained in:
parent
946843ff59
commit
f4e8051e9e
@ -1,18 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "modules/script.hpp"
|
|
||||||
|
|
||||||
POLYBAR_NS
|
|
||||||
|
|
||||||
namespace modules {
|
|
||||||
class cmdscript_module : virtual public script_module {
|
|
||||||
public:
|
|
||||||
explicit cmdscript_module(const bar_settings&, string);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void process();
|
|
||||||
chrono::duration<double> sleep_duration();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
POLYBAR_NS_END
|
|
@ -130,7 +130,7 @@ namespace modules {
|
|||||||
protected:
|
protected:
|
||||||
void broadcast();
|
void broadcast();
|
||||||
void idle();
|
void idle();
|
||||||
void sleep(chrono::duration<double> sleep_duration);
|
void sleep(chrono::duration<double> duration);
|
||||||
void wakeup();
|
void wakeup();
|
||||||
string get_format() const;
|
string get_format() const;
|
||||||
string get_output();
|
string get_output();
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include "modules/backlight.hpp"
|
#include "modules/backlight.hpp"
|
||||||
#include "modules/battery.hpp"
|
#include "modules/battery.hpp"
|
||||||
#include "modules/bspwm.hpp"
|
#include "modules/bspwm.hpp"
|
||||||
#include "modules/cmdscript.hpp"
|
|
||||||
#include "modules/counter.hpp"
|
#include "modules/counter.hpp"
|
||||||
#include "modules/cpu.hpp"
|
#include "modules/cpu.hpp"
|
||||||
#include "modules/date.hpp"
|
#include "modules/date.hpp"
|
||||||
@ -18,7 +17,6 @@
|
|||||||
#if DEBUG
|
#if DEBUG
|
||||||
#include "modules/systray.hpp"
|
#include "modules/systray.hpp"
|
||||||
#endif
|
#endif
|
||||||
#include "modules/tailscript.hpp"
|
|
||||||
#include "modules/temperature.hpp"
|
#include "modules/temperature.hpp"
|
||||||
#include "modules/text.hpp"
|
#include "modules/text.hpp"
|
||||||
#include "modules/xbacklight.hpp"
|
#include "modules/xbacklight.hpp"
|
||||||
@ -95,11 +93,7 @@ namespace {
|
|||||||
} else if (name == "custom/text") {
|
} else if (name == "custom/text") {
|
||||||
return new text_module(bar, move(module_name));
|
return new text_module(bar, move(module_name));
|
||||||
} else if (name == "custom/script") {
|
} else if (name == "custom/script") {
|
||||||
if (config::make().get<bool>("module/" + module_name, "tail", false)) {
|
return new script_module(bar, move(module_name));
|
||||||
return new tailscript_module(bar, move(module_name));
|
|
||||||
} else {
|
|
||||||
return new cmdscript_module(bar, move(module_name));
|
|
||||||
}
|
|
||||||
} else if (name == "custom/menu") {
|
} else if (name == "custom/menu") {
|
||||||
return new menu_module(bar, move(module_name));
|
return new menu_module(bar, move(module_name));
|
||||||
} else if (name == "custom/ipc") {
|
} else if (name == "custom/ipc") {
|
||||||
|
@ -10,21 +10,23 @@ namespace modules {
|
|||||||
class script_module : public module<script_module> {
|
class script_module : public module<script_module> {
|
||||||
public:
|
public:
|
||||||
explicit script_module(const bar_settings&, string);
|
explicit script_module(const bar_settings&, string);
|
||||||
virtual ~script_module() {}
|
~script_module() {}
|
||||||
|
|
||||||
virtual void start();
|
void start();
|
||||||
virtual void stop();
|
void stop();
|
||||||
|
|
||||||
string get_output();
|
string get_output();
|
||||||
bool build(builder* builder, const string& tag) const;
|
bool build(builder* builder, const string& tag) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void process() = 0;
|
chrono::duration<double> process(const mutex_wrapper<function<chrono::duration<double>()>>& handler) const;
|
||||||
virtual chrono::duration<double> sleep_duration() = 0;
|
bool check_condition();
|
||||||
|
|
||||||
static constexpr const char* TAG_OUTPUT{"<output>"};
|
private:
|
||||||
static constexpr const char* TAG_LABEL{"<label>"};
|
static constexpr const char* TAG_LABEL{"<label>"};
|
||||||
|
|
||||||
|
mutex_wrapper<function<chrono::duration<double>()>> m_handler;
|
||||||
|
|
||||||
unique_ptr<command> m_command;
|
unique_ptr<command> m_command;
|
||||||
|
|
||||||
string m_exec;
|
string m_exec;
|
||||||
@ -38,11 +40,6 @@ namespace modules {
|
|||||||
string m_prev;
|
string m_prev;
|
||||||
int m_counter{0};
|
int m_counter{0};
|
||||||
|
|
||||||
// @deprecated
|
|
||||||
size_t m_maxlen{0};
|
|
||||||
// @deprecated
|
|
||||||
bool m_ellipsis{true};
|
|
||||||
|
|
||||||
bool m_stopping{false};
|
bool m_stopping{false};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "modules/script.hpp"
|
|
||||||
|
|
||||||
POLYBAR_NS
|
|
||||||
|
|
||||||
namespace modules {
|
|
||||||
class tailscript_module : virtual public script_module {
|
|
||||||
public:
|
|
||||||
explicit tailscript_module(const bar_settings&, string);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void process();
|
|
||||||
chrono::duration<double> sleep_duration();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
POLYBAR_NS_END
|
|
@ -29,8 +29,6 @@ namespace modules {
|
|||||||
string contents() { \
|
string contents() { \
|
||||||
return ""; \
|
return ""; \
|
||||||
} \
|
} \
|
||||||
void set_update_cb(callback<>&&) {} \
|
|
||||||
void set_stop_cb(callback<>&&) {} \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if not ENABLE_I3
|
#if not ENABLE_I3
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
#include "modules/cmdscript.hpp"
|
|
||||||
#include "drawtypes/label.hpp"
|
|
||||||
|
|
||||||
#include "modules/meta/base.inl"
|
|
||||||
|
|
||||||
POLYBAR_NS
|
|
||||||
|
|
||||||
namespace modules {
|
|
||||||
cmdscript_module::cmdscript_module(const bar_settings& bar, string name_) : script_module(bar, move(name_)) {
|
|
||||||
m_interval = m_conf.get<decltype(m_interval)>(name(), "interval", 5s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cmdscript_module::process() {
|
|
||||||
try {
|
|
||||||
auto exec = string_util::replace_all(m_exec, "%counter%", to_string(++m_counter));
|
|
||||||
m_log.info("%s: Invoking shell command: \"%s\"", name(), exec);
|
|
||||||
m_command = command_util::make_command(exec);
|
|
||||||
m_command->exec(true);
|
|
||||||
} catch (const exception& err) {
|
|
||||||
m_log.err("%s: %s", name(), err.what());
|
|
||||||
throw module_error("Failed to execute command, stopping module...");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((m_output = m_command->readline()) != m_prev) {
|
|
||||||
broadcast();
|
|
||||||
m_prev = m_output;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
chrono::duration<double> cmdscript_module::sleep_duration() {
|
|
||||||
return std::max(m_command->get_exit_status() == 0 ? m_interval : 1s, m_interval);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
POLYBAR_NS_END
|
|
@ -8,54 +8,101 @@ POLYBAR_NS
|
|||||||
namespace modules {
|
namespace modules {
|
||||||
template class module<script_module>;
|
template class module<script_module>;
|
||||||
|
|
||||||
script_module::script_module(const bar_settings& bar, string name_) : module<script_module>(bar, move(name_)) {
|
/**
|
||||||
|
* Construct script module by loading configuration values
|
||||||
|
* and setting up formatting objects
|
||||||
|
*/
|
||||||
|
script_module::script_module(const bar_settings& bar, string name_)
|
||||||
|
: module<script_module>(bar, move(name_)), m_handler([&]() -> function<chrono::duration<double>()> {
|
||||||
|
// Handler for continuous tail commands {{{
|
||||||
|
|
||||||
|
if (m_conf.get(name(), "tail", false)) {
|
||||||
|
return [&] {
|
||||||
|
if (!m_command || !m_command->is_running()) {
|
||||||
|
string exec{string_util::replace_all(m_exec, "%counter%", to_string(++m_counter))};
|
||||||
|
m_log.info("%s: Invoking shell command: \"%s\"", name(), exec);
|
||||||
|
m_command = command_util::make_command(exec);
|
||||||
|
|
||||||
|
try {
|
||||||
|
m_command->exec(false);
|
||||||
|
} catch (const exception& err) {
|
||||||
|
m_log.err("%s: %s", name(), err.what());
|
||||||
|
throw module_error("Failed to execute command, stopping module...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (io_util::poll(m_command->get_stdout(PIPE_READ), POLLIN, 0)) {
|
||||||
|
if ((m_output = m_command->readline()) != m_prev) {
|
||||||
|
m_prev = m_output;
|
||||||
|
broadcast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_command && !m_command->is_running()) {
|
||||||
|
return std::max(m_command->get_exit_status() == 0 ? m_interval : 1s, m_interval);
|
||||||
|
} else {
|
||||||
|
return m_interval;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// Handler for basic shell commands {{{
|
||||||
|
|
||||||
|
return [&] {
|
||||||
|
try {
|
||||||
|
auto exec = string_util::replace_all(m_exec, "%counter%", to_string(++m_counter));
|
||||||
|
m_log.info("%s: Invoking shell command: \"%s\"", name(), exec);
|
||||||
|
m_command = command_util::make_command(exec);
|
||||||
|
m_command->exec(true);
|
||||||
|
} catch (const exception& err) {
|
||||||
|
m_log.err("%s: %s", name(), err.what());
|
||||||
|
throw module_error("Failed to execute command, stopping module...");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((m_output = m_command->readline()) != m_prev) {
|
||||||
|
broadcast();
|
||||||
|
m_prev = m_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::max(m_command->get_exit_status() == 0 ? m_interval : 1s, m_interval);
|
||||||
|
};
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
}()) {
|
||||||
|
// Load configuration values
|
||||||
m_exec = m_conf.get(name(), "exec", m_exec);
|
m_exec = m_conf.get(name(), "exec", m_exec);
|
||||||
m_exec_if = m_conf.get(name(), "exec-if", m_exec_if);
|
m_exec_if = m_conf.get(name(), "exec-if", m_exec_if);
|
||||||
m_maxlen = m_conf.get(name(), "maxlen", m_maxlen);
|
|
||||||
m_ellipsis = m_conf.get(name(), "ellipsis", m_ellipsis);
|
|
||||||
m_interval = m_conf.get<decltype(m_interval)>(name(), "interval", 5s);
|
m_interval = m_conf.get<decltype(m_interval)>(name(), "interval", 5s);
|
||||||
|
|
||||||
m_conf.warn_deprecated(
|
// Load configured click handlers
|
||||||
name(), "maxlen", "\"format = <label>\" and \"label = %output:0:" + to_string(m_maxlen) + "%\"");
|
|
||||||
|
|
||||||
m_actions[mousebtn::LEFT] = m_conf.get(name(), "click-left", ""s);
|
m_actions[mousebtn::LEFT] = m_conf.get(name(), "click-left", ""s);
|
||||||
m_actions[mousebtn::MIDDLE] = m_conf.get(name(), "click-middle", ""s);
|
m_actions[mousebtn::MIDDLE] = m_conf.get(name(), "click-middle", ""s);
|
||||||
m_actions[mousebtn::RIGHT] = m_conf.get(name(), "click-right", ""s);
|
m_actions[mousebtn::RIGHT] = m_conf.get(name(), "click-right", ""s);
|
||||||
m_actions[mousebtn::SCROLL_UP] = m_conf.get(name(), "scroll-up", ""s);
|
m_actions[mousebtn::SCROLL_UP] = m_conf.get(name(), "scroll-up", ""s);
|
||||||
m_actions[mousebtn::SCROLL_DOWN] = m_conf.get(name(), "scroll-down", ""s);
|
m_actions[mousebtn::SCROLL_DOWN] = m_conf.get(name(), "scroll-down", ""s);
|
||||||
|
|
||||||
m_formatter->add(DEFAULT_FORMAT, TAG_LABEL, {TAG_OUTPUT, TAG_LABEL});
|
// Setup formatting
|
||||||
|
m_formatter->add(DEFAULT_FORMAT, TAG_LABEL, {TAG_LABEL});
|
||||||
if (m_formatter->has(TAG_LABEL)) {
|
if (m_formatter->has(TAG_LABEL)) {
|
||||||
m_label = load_optional_label(m_conf, name(), "label", "%output%");
|
m_label = load_optional_label(m_conf, name(), "label", "%output%");
|
||||||
} else if (m_formatter->has(TAG_OUTPUT)) {
|
|
||||||
m_log.warn("%s: The format tag <output> is deprecated, use <label> instead", name());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the module worker
|
||||||
|
*/
|
||||||
void script_module::start() {
|
void script_module::start() {
|
||||||
m_mainthread = thread([this] {
|
m_mainthread = thread([&] {
|
||||||
try {
|
try {
|
||||||
while (running() && !m_stopping) {
|
while (running() && !m_stopping) {
|
||||||
std::unique_lock<mutex> guard(m_updatelock);
|
if (check_condition()) {
|
||||||
|
sleep(process(m_handler));
|
||||||
// Execute the condition command if specified
|
} else if (m_interval > 1s) {
|
||||||
if (!m_exec_if.empty() && command_util::make_command(m_exec_if)->exec(true) != 0) {
|
|
||||||
if (!m_output.empty()) {
|
|
||||||
broadcast();
|
|
||||||
m_output.clear();
|
|
||||||
m_prev.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_interval >= 1s) {
|
|
||||||
sleep(m_interval);
|
sleep(m_interval);
|
||||||
} else {
|
} else {
|
||||||
sleep(1s);
|
sleep(1s);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
this->process();
|
|
||||||
this->sleep(this->sleep_duration());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (const exception& err) {
|
} catch (const exception& err) {
|
||||||
halt(err.what());
|
halt(err.what());
|
||||||
@ -63,22 +110,50 @@ namespace modules {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop the module worker by terminating any running commands
|
||||||
|
*/
|
||||||
void script_module::stop() {
|
void script_module::stop() {
|
||||||
std::lock_guard<mutex> guard(m_updatelock, std::adopt_lock);
|
std::lock_guard<decltype(m_handler)> guard(m_handler);
|
||||||
|
|
||||||
m_stopping = true;
|
m_stopping = true;
|
||||||
this->wakeup();
|
wakeup();
|
||||||
|
|
||||||
if (m_command) {
|
if (m_command && m_command->is_running()) {
|
||||||
if (m_command->is_running()) {
|
|
||||||
m_log.warn("%s: Stopping shell command", name());
|
m_log.warn("%s: Stopping shell command", name());
|
||||||
}
|
|
||||||
m_command->terminate();
|
m_command->terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
this->module::stop();
|
m_command.reset();
|
||||||
|
module::stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if defined condition is met
|
||||||
|
*/
|
||||||
|
bool script_module::check_condition() {
|
||||||
|
if (m_exec_if.empty()) {
|
||||||
|
return true;
|
||||||
|
} else if (command_util::make_command(m_exec_if)->exec(true) == 0) {
|
||||||
|
return true;
|
||||||
|
} else if (!m_output.empty()) {
|
||||||
|
broadcast();
|
||||||
|
m_output.clear();
|
||||||
|
m_prev.clear();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process mutex wrapped script handler
|
||||||
|
*/
|
||||||
|
chrono::duration<double> script_module::process(const decltype(m_handler) & handler) const {
|
||||||
|
std::lock_guard<decltype(handler)> guard(handler);
|
||||||
|
return handler();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate module output
|
||||||
|
*/
|
||||||
string script_module::get_output() {
|
string script_module::get_output() {
|
||||||
if (m_output.empty()) {
|
if (m_output.empty()) {
|
||||||
return "";
|
return "";
|
||||||
@ -89,30 +164,24 @@ namespace modules {
|
|||||||
m_label->replace_token("%output%", m_output);
|
m_label->replace_token("%output%", m_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_maxlen > 0 && m_output.length() > m_maxlen) {
|
string cnt{to_string(m_counter)};
|
||||||
m_output.erase(m_maxlen);
|
|
||||||
m_output += m_ellipsis ? "..." : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
auto counter_str = to_string(m_counter);
|
|
||||||
string output{module::get_output()};
|
string output{module::get_output()};
|
||||||
|
|
||||||
if (!m_actions[mousebtn::LEFT].empty()) {
|
if (!m_actions[mousebtn::LEFT].empty()) {
|
||||||
m_builder->cmd(mousebtn::LEFT, string_util::replace_all(m_actions[mousebtn::LEFT], "%counter%", counter_str));
|
m_builder->cmd(mousebtn::LEFT, string_util::replace_all(m_actions[mousebtn::LEFT], "%counter%", cnt));
|
||||||
}
|
}
|
||||||
if (!m_actions[mousebtn::MIDDLE].empty()) {
|
if (!m_actions[mousebtn::MIDDLE].empty()) {
|
||||||
m_builder->cmd(mousebtn::MIDDLE, string_util::replace_all(m_actions[mousebtn::MIDDLE], "%counter%", counter_str));
|
m_builder->cmd(mousebtn::MIDDLE, string_util::replace_all(m_actions[mousebtn::MIDDLE], "%counter%", cnt));
|
||||||
}
|
}
|
||||||
if (!m_actions[mousebtn::RIGHT].empty()) {
|
if (!m_actions[mousebtn::RIGHT].empty()) {
|
||||||
m_builder->cmd(mousebtn::RIGHT, string_util::replace_all(m_actions[mousebtn::RIGHT], "%counter%", counter_str));
|
m_builder->cmd(mousebtn::RIGHT, string_util::replace_all(m_actions[mousebtn::RIGHT], "%counter%", cnt));
|
||||||
}
|
}
|
||||||
if (!m_actions[mousebtn::SCROLL_UP].empty()) {
|
if (!m_actions[mousebtn::SCROLL_UP].empty()) {
|
||||||
m_builder->cmd(
|
m_builder->cmd(mousebtn::SCROLL_UP, string_util::replace_all(m_actions[mousebtn::SCROLL_UP], "%counter%", cnt));
|
||||||
mousebtn::SCROLL_UP, string_util::replace_all(m_actions[mousebtn::SCROLL_UP], "%counter%", counter_str));
|
|
||||||
}
|
}
|
||||||
if (!m_actions[mousebtn::SCROLL_DOWN].empty()) {
|
if (!m_actions[mousebtn::SCROLL_DOWN].empty()) {
|
||||||
m_builder->cmd(
|
m_builder->cmd(
|
||||||
mousebtn::SCROLL_DOWN, string_util::replace_all(m_actions[mousebtn::SCROLL_DOWN], "%counter%", counter_str));
|
mousebtn::SCROLL_DOWN, string_util::replace_all(m_actions[mousebtn::SCROLL_DOWN], "%counter%", cnt));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_builder->append(output);
|
m_builder->append(output);
|
||||||
@ -120,10 +189,11 @@ namespace modules {
|
|||||||
return m_builder->flush();
|
return m_builder->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output format tags
|
||||||
|
*/
|
||||||
bool script_module::build(builder* builder, const string& tag) const {
|
bool script_module::build(builder* builder, const string& tag) const {
|
||||||
if (tag == TAG_OUTPUT) {
|
if (tag == TAG_LABEL) {
|
||||||
builder->node(m_output);
|
|
||||||
} else if (tag == TAG_LABEL) {
|
|
||||||
builder->node(m_label);
|
builder->node(m_label);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
#include "modules/tailscript.hpp"
|
|
||||||
#include "drawtypes/label.hpp"
|
|
||||||
|
|
||||||
#include "modules/meta/base.inl"
|
|
||||||
|
|
||||||
POLYBAR_NS
|
|
||||||
|
|
||||||
namespace modules {
|
|
||||||
tailscript_module::tailscript_module(const bar_settings& bar, string name_) : script_module(bar, move(name_)) {
|
|
||||||
m_interval = m_conf.get<decltype(m_interval)>(name(), "interval", 0s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tailscript_module::process() {
|
|
||||||
if (!m_command || !m_command->is_running()) {
|
|
||||||
string exec{string_util::replace_all(m_exec, "%counter%", to_string(++m_counter))};
|
|
||||||
m_log.info("%s: Invoking shell command: \"%s\"", name(), exec);
|
|
||||||
m_command = command_util::make_command(exec);
|
|
||||||
|
|
||||||
try {
|
|
||||||
m_command->exec(false);
|
|
||||||
} catch (const exception& err) {
|
|
||||||
m_log.err("%s: %s", name(), err.what());
|
|
||||||
throw module_error("Failed to execute command, stopping module...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (io_util::poll(m_command->get_stdout(PIPE_READ), POLLIN, 0)) {
|
|
||||||
if ((m_output = m_command->readline()) != m_prev) {
|
|
||||||
m_prev = m_output;
|
|
||||||
broadcast();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
chrono::duration<double> tailscript_module::sleep_duration() {
|
|
||||||
if (m_command && !m_command->is_running()) {
|
|
||||||
return std::max(m_command->get_exit_status() == 0 ? m_interval : 1s, m_interval);
|
|
||||||
} else {
|
|
||||||
return m_interval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
POLYBAR_NS_END
|
|
Loading…
Reference in New Issue
Block a user