diff --git a/include/bar.hpp b/include/bar.hpp index 1b9617be..4aa17c17 100644 --- a/include/bar.hpp +++ b/include/bar.hpp @@ -98,7 +98,7 @@ class Bar { private: void onMap(GdkEventAny *); auto setupWidgets() -> void; - void getModules(const Factory &, const std::string &); + void getModules(const Factory &, const std::string &, Gtk::Box*); void setupAltFormatKeyForModule(const std::string &module_name); void setupAltFormatKeyForModuleList(const char *module_list_name); void setMode(const bar_mode &); @@ -119,6 +119,7 @@ class Bar { using BarIpcClient = modules::sway::BarIpcClient; std::unique_ptr _ipc_client; #endif + std::vector> modules_all_; }; } // namespace waybar diff --git a/include/group.hpp b/include/group.hpp new file mode 100644 index 00000000..f282f9c5 --- /dev/null +++ b/include/group.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include +#include +#include +#include "AModule.hpp" +#include "bar.hpp" +#include "factory.hpp" + +namespace waybar { + +class Group : public AModule { + public: + Group(const std::string&, const Bar&, const Json::Value&); + ~Group() = default; + auto update() -> void; + operator Gtk::Widget &(); + Gtk::Box box; +}; + +} // namespace waybar diff --git a/man/waybar.5.scd.in b/man/waybar.5.scd.in index 92d0774a..c42f6eb8 100644 --- a/man/waybar.5.scd.in +++ b/man/waybar.5.scd.in @@ -218,6 +218,28 @@ When positioning Waybar on the left or right side of the screen, sometimes it's Valid options for the "rotate" property are: 0, 90, 180 and 270. +## Grouping modules + +Module groups allow stacking modules in the direction orthogonal to the bar direction. When the bar is positioned on the top or bottom of the screen, modules in a group are stacked vertically. Likewise, when positioned on the left or right, modules in a group are stacked horizontally. + +A module group is defined by specifying a module named "group/some-group-name". The group must also be configured with a list of contained modules. Example: + +``` +{ + "modules-right": ["group/hardware", "clock"], + + "group/hardware": { + "modules": [ + "cpu", + "memory", + "battery" + ] + }, + + ... +} +``` + # SUPPORTED MODULES - *waybar-backlight(5)* diff --git a/meson.build b/meson.build index a15ef59d..7f2d9562 100644 --- a/meson.build +++ b/meson.build @@ -150,6 +150,7 @@ src_files = files( 'src/bar.cpp', 'src/client.cpp', 'src/config.cpp', + 'src/group.cpp', 'src/util/ustring_clen.cpp' ) diff --git a/src/bar.cpp b/src/bar.cpp index 789bea95..fbd4623f 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -9,6 +9,7 @@ #include "bar.hpp" #include "client.hpp" #include "factory.hpp" +#include "group.hpp" #include "wlr-layer-shell-unstable-v1-client-protocol.h" #ifdef HAVE_SWAY @@ -710,19 +711,7 @@ void waybar::Bar::setupAltFormatKeyForModuleList(const char* module_list_name) { } void waybar::Bar::handleSignal(int signal) { - for (auto& module : modules_left_) { - auto* custom = dynamic_cast(module.get()); - if (custom != nullptr) { - custom->refresh(signal); - } - } - for (auto& module : modules_center_) { - auto* custom = dynamic_cast(module.get()); - if (custom != nullptr) { - custom->refresh(signal); - } - } - for (auto& module : modules_right_) { + for (auto& module : modules_all_) { auto* custom = dynamic_cast(module.get()); if (custom != nullptr) { custom->refresh(signal); @@ -730,19 +719,35 @@ void waybar::Bar::handleSignal(int signal) { } } -void waybar::Bar::getModules(const Factory& factory, const std::string& pos) { - if (config[pos].isArray()) { - for (const auto& name : config[pos]) { +void waybar::Bar::getModules(const Factory& factory, const std::string& pos, Gtk::Box* group = nullptr) { + auto module_list = group ? config[pos]["modules"] : config[pos]; + if (module_list.isArray()) { + for (const auto& name : module_list) { try { - auto module = factory.makeModule(name.asString()); - if (pos == "modules-left") { - modules_left_.emplace_back(module); + auto ref = name.asString(); + AModule* module; + + if (ref.compare(0, 6, "group/") == 0 && ref.size() > 6) { + auto group_module = new waybar::Group(ref, *this, config[ref]); + getModules(factory, ref, &group_module->box); + module = group_module; + } else { + module = factory.makeModule(ref); } - if (pos == "modules-center") { - modules_center_.emplace_back(module); - } - if (pos == "modules-right") { - modules_right_.emplace_back(module); + + modules_all_.emplace_back(module); + if (group) { + group->pack_start(*module, false, false); + } else { + if (pos == "modules-left") { + modules_left_.emplace_back(module); + } + if (pos == "modules-center") { + modules_center_.emplace_back(module); + } + if (pos == "modules-right") { + modules_right_.emplace_back(module); + } } module->dp.connect([module, &name] { try { diff --git a/src/group.cpp b/src/group.cpp new file mode 100644 index 00000000..9d2188cc --- /dev/null +++ b/src/group.cpp @@ -0,0 +1,19 @@ +#include "group.hpp" +#include +#include + +namespace waybar { + +Group::Group(const std::string& name, const Bar& bar, const Json::Value& config) + : AModule(config, name, "", false, false), + box{bar.vertical ? Gtk::ORIENTATION_HORIZONTAL : Gtk::ORIENTATION_VERTICAL, 0} + { +} + +auto Group::update() -> void { + // noop +} + +Group::operator Gtk::Widget&() { return box; } + +} // namespace waybar diff --git a/src/modules/pulseaudio.cpp b/src/modules/pulseaudio.cpp index cf427800..8f2b25de 100644 --- a/src/modules/pulseaudio.cpp +++ b/src/modules/pulseaudio.cpp @@ -211,7 +211,7 @@ static const std::array ports = { }; const std::vector waybar::modules::Pulseaudio::getPulseIcon() const { - std::vector res = {default_source_name_}; + std::vector res = {current_sink_name_, default_source_name_}; std::string nameLC = port_name_ + form_factor_; std::transform(nameLC.begin(), nameLC.end(), nameLC.begin(), ::tolower); for (auto const &port : ports) {