From 8e46e54cb3fbcfcb109de4bdd9ed236ed816c5fb Mon Sep 17 00:00:00 2001 From: Nolan Prochnau Date: Sun, 27 Dec 2020 10:05:26 -0500 Subject: [PATCH] feat: Module Visibility (#2320) Modules can now also be shown and hidden using ipc commands: $ polybar-msg [-p PID] cmd hide.mymodule # Hides module mymodule $ polybar-msg [-p PID] cmd show.mymodule # Shows module mymodule $ polybar-msg [-p PID] cmd toggle.mymodule # Toggles visibility of mymodule * Hopefully implement visibility checking * Implement hide command * Implement `show` and `toggle` commands * Refactor and add some logging * Run style checks and update CHANGELOG * Get around unused parameter warnings * Change `set_visible` to return nothing * Make errors more informative Co-authored-by: Patrick Ziegler * Update bar when changing module visibility - Called in the module to maintain dependence on the signal emitter - Update CHANGELOG to make changes more verbose * wrong var * Update include/modules/unsupported.hpp Co-authored-by: Patrick Ziegler Co-authored-by: Patrick Ziegler --- CHANGELOG.md | 3 +++ config/config.cmake | 2 ++ include/components/controller.hpp | 2 ++ include/modules/meta/base.hpp | 7 +++++++ include/modules/meta/base.inl | 12 ++++++++++++ include/modules/unsupported.hpp | 4 ++++ src/components/controller.cpp | 31 ++++++++++++++++++++++++++++++- 7 files changed, 60 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df02656d..1be199b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([`#316`](https://github.com/polybar/polybar/issues/316)) - Added .ini extension check to the default config search. ([`#2323`](https://github.com/polybar/polybar/issues/2323)) +- IPC commands to change visibility of modules + (`hide.`, `show.`, and `toggle.`) + ([`#2108`](https://github.com/polybar/polybar/issues/2108)) ### Changed - Slight changes to the value ranges the different ramp levels are responsible diff --git a/config/config.cmake b/config/config.cmake index 004bbdbe..ce999856 100644 --- a/config/config.cmake +++ b/config/config.cmake @@ -77,6 +77,8 @@ tray-padding = 2 cursor-click = pointer cursor-scroll = ns-resize +enable-ipc = true + [module/xwindow] type = internal/xwindow label = %title:0:30:...% diff --git a/include/components/controller.hpp b/include/components/controller.hpp index f70156bb..a8947e8c 100644 --- a/include/components/controller.hpp +++ b/include/components/controller.hpp @@ -76,6 +76,8 @@ class controller bool forward_action(const actions_util::action& cmd); bool try_forward_legacy_action(const string& cmd); + void switch_module_visibility(string module_name_raw, int visible); + connection& m_connection; signal_emitter& m_sig; const logger& m_log; diff --git a/include/modules/meta/base.hpp b/include/modules/meta/base.hpp index dd8db5c5..87dacf2e 100644 --- a/include/modules/meta/base.hpp +++ b/include/modules/meta/base.hpp @@ -114,6 +114,8 @@ namespace modules { virtual string name_raw() const = 0; virtual string name() const = 0; virtual bool running() const = 0; + virtual bool visible() const = 0; + virtual void set_visible(bool value) = 0; /** * Handle action, possibly with data attached @@ -145,6 +147,10 @@ namespace modules { string name_raw() const; string name() const; bool running() const; + + bool visible() const; + void set_visible(bool value); + void stop(); void halt(string error_message); void teardown(); @@ -184,6 +190,7 @@ namespace modules { private: atomic m_enabled{true}; + atomic m_visible{true}; atomic m_changed{true}; string m_cache; }; diff --git a/include/modules/meta/base.inl b/include/modules/meta/base.inl index ab963fbd..9551fa97 100644 --- a/include/modules/meta/base.inl +++ b/include/modules/meta/base.inl @@ -56,6 +56,18 @@ namespace modules { return static_cast(m_enabled); } + template + bool module::visible() const { + return static_cast(m_visible); + } + + template + void module::set_visible(bool value) { + m_log.info("%s: Visibility changed (state=%s)", m_name, value ? "shown" : "hidden"); + m_visible = value; + broadcast(); + } + template void module::stop() { if (!static_cast(m_enabled)) { diff --git a/include/modules/unsupported.hpp b/include/modules/unsupported.hpp index 4694cfc5..28e53155 100644 --- a/include/modules/unsupported.hpp +++ b/include/modules/unsupported.hpp @@ -27,6 +27,10 @@ namespace modules { bool running() const { \ return false; \ } \ + bool visible() const { \ + return false; \ + } \ + void set_visible(bool) {} \ void start() {} \ void stop() {} \ void halt(string) {} \ diff --git a/src/components/controller.cpp b/src/components/controller.cpp index f55a05d1..e7d0e5f3 100644 --- a/src/components/controller.cpp +++ b/src/components/controller.cpp @@ -530,6 +530,25 @@ bool controller::forward_action(const actions_util::action& action_triple) { return true; } +void controller::switch_module_visibility(string module_name_raw, int visible) { + for (auto&& mod : m_modules) { + if (mod->name_raw() != module_name_raw) + continue; + + if (visible == 0) { + mod->set_visible(false); + } else if (visible == 1) { + mod->set_visible(true); + } else if (visible == 2) { + mod->set_visible(!mod->visible()); + } + + return; + } + + m_log.err("controller: Module '%s' not found for visibility change (state=%s)", module_name_raw, visible ? "shown" : "hidden"); +} + /** * Process stored input data */ @@ -600,7 +619,7 @@ bool controller::process_update(bool force) { } for (const auto& module : block.second) { - if (!module->running()) { + if (!module->running() || !module->visible()) { continue; } @@ -833,6 +852,10 @@ bool controller::on(const signals::ipc::command& evt) { return false; } + string hide_module{"hide."}; + string show_module{"show."}; + string toggle_module{"toggle."}; + if (command == "quit") { enqueue(make_quit_evt(false)); } else if (command == "restart") { @@ -843,6 +866,12 @@ bool controller::on(const signals::ipc::command& evt) { m_bar->show(); } else if (command == "toggle") { m_bar->toggle(); + } else if (command.find(hide_module) == 0) { + switch_module_visibility(command.substr(hide_module.length()), 0); + } else if (command.find(show_module) == 0) { + switch_module_visibility(command.substr(show_module.length()), 1); + } else if (command.find(toggle_module) == 0) { + switch_module_visibility(command.substr(toggle_module.length()), 2); } else { m_log.warn("\"%s\" is not a valid ipc command", command); }