diff --git a/include/bar.hpp b/include/bar.hpp index 6dc3c03df..5c7d07302 100644 --- a/include/bar.hpp +++ b/include/bar.hpp @@ -73,6 +73,7 @@ class Bar { Json::Value config; struct wl_surface *surface; bool visible = true; + Gtk::Box box_; Gtk::Window window; Gtk::Orientation orientation = Gtk::ORIENTATION_HORIZONTAL; Gtk::PositionType position = Gtk::POS_TOP; @@ -87,7 +88,7 @@ class Bar { private: void onMap(GdkEventAny *); auto setupWidgets() -> void; - void getModules(const Factory &, const std::string &, waybar::Group *); + void getModules(const std::string &); void setupAltFormatKeyForModule(const std::string &module_name); void setupAltFormatKeyForModuleList(const char *module_list_name); void setMode(const bar_mode &); @@ -105,10 +106,11 @@ class Bar { uint32_t width_, height_; bool passthrough_; + Factory factory_; + Gtk::Box left_; Gtk::Box center_; Gtk::Box right_; - Gtk::Box box_; std::vector> modules_left_; std::vector> modules_center_; std::vector> modules_right_; @@ -116,7 +118,6 @@ class Bar { using BarIpcClient = modules::sway::BarIpcClient; std::unique_ptr _ipc_client; #endif - std::vector> modules_all_; }; } // namespace waybar diff --git a/include/factory.hpp b/include/factory.hpp index f805aab5e..668bcb3f2 100644 --- a/include/factory.hpp +++ b/include/factory.hpp @@ -11,11 +11,13 @@ class Bar; class Factory { public: Factory(const Bar& bar, const Json::Value& config); - AModule* makeModule(const std::string& name, const std::string& pos) const; + std::shared_ptr addModule(const std::string& name, const std::string& pos); + std::vector> modules_all_; private: const Bar& bar_; const Json::Value& config_; + waybar::AModule* makeModule(const std::string& name, const std::string& pos, waybar::Factory& factory) const; }; } // namespace waybar diff --git a/include/group.hpp b/include/group.hpp index 67cf43855..3b825f408 100644 --- a/include/group.hpp +++ b/include/group.hpp @@ -5,13 +5,14 @@ #include #include "AModule.hpp" +#include "factory.hpp" #include "gtkmm/revealer.h" namespace waybar { class Group : public AModule { public: - Group(const std::string&, const std::string&, const Json::Value&, bool); + Group(const std::string&, const std::string&, const Json::Value&, bool, const std::string&, Factory&); virtual ~Group() = default; auto update() -> void override; operator Gtk::Widget&() override; diff --git a/src/bar.cpp b/src/bar.cpp index 872632acb..cdbc3ee8a 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -7,7 +7,6 @@ #include "client.hpp" #include "factory.hpp" -#include "group.hpp" #ifdef HAVE_SWAY #include "modules/sway/bar.hpp" @@ -139,7 +138,8 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config) left_(Gtk::ORIENTATION_HORIZONTAL, 0), center_(Gtk::ORIENTATION_HORIZONTAL, 0), right_(Gtk::ORIENTATION_HORIZONTAL, 0), - box_(Gtk::ORIENTATION_HORIZONTAL, 0) { + box_(Gtk::ORIENTATION_HORIZONTAL, 0), + factory_(*this, config) { window.set_title("waybar"); window.set_name("waybar"); window.set_decorated(false); @@ -466,49 +466,26 @@ void waybar::Bar::setupAltFormatKeyForModuleList(const char* module_list_name) { } void waybar::Bar::handleSignal(int signal) { - for (auto& module : modules_all_) { + for (const auto& module : factory_.modules_all_) { module->refresh(signal); } } -void waybar::Bar::getModules(const Factory& factory, const std::string& pos, - waybar::Group* group = nullptr) { - auto module_list = group ? config[pos]["modules"] : config[pos]; +void waybar::Bar::getModules(const std::string& pos) { + auto module_list = config[pos]; if (module_list.isArray()) { for (const auto& name : module_list) { try { auto ref = name.asString(); - AModule* module; - - if (ref.compare(0, 6, "group/") == 0 && ref.size() > 6) { - auto hash_pos = ref.find('#'); - auto id_name = ref.substr(6, hash_pos - 6); - auto class_name = hash_pos != std::string::npos ? ref.substr(hash_pos + 1) : ""; - - auto vertical = (group ? group->getBox().get_orientation() : box_.get_orientation()) == - Gtk::ORIENTATION_VERTICAL; - - auto group_module = new waybar::Group(id_name, class_name, config[ref], vertical); - getModules(factory, ref, group_module); - module = group_module; - } else { - module = factory.makeModule(ref, pos); + auto module = factory_.addModule(ref, pos); + if (pos == "modules-left") { + modules_left_.emplace_back(module); } - - std::shared_ptr module_sp(module); - modules_all_.emplace_back(module_sp); - if (group) { - group->addWidget(*module); - } else { - if (pos == "modules-left") { - modules_left_.emplace_back(module_sp); - } - if (pos == "modules-center") { - modules_center_.emplace_back(module_sp); - } - if (pos == "modules-right") { - modules_right_.emplace_back(module_sp); - } + if (pos == "modules-center") { + modules_center_.emplace_back(module); + } + if (pos == "modules-right") { + modules_right_.emplace_back(module); } module->dp.connect([module, ref] { try { @@ -539,10 +516,9 @@ auto waybar::Bar::setupWidgets() -> void { setupAltFormatKeyForModuleList("modules-right"); setupAltFormatKeyForModuleList("modules-center"); - Factory factory(*this, config); - getModules(factory, "modules-left"); - getModules(factory, "modules-center"); - getModules(factory, "modules-right"); + getModules("modules-left"); + getModules("modules-center"); + getModules("modules-right"); for (auto const& module : modules_left_) { left_.pack_start(*module, false, false); } diff --git a/src/factory.cpp b/src/factory.cpp index 0549fe09f..b5fc3bccb 100644 --- a/src/factory.cpp +++ b/src/factory.cpp @@ -1,6 +1,8 @@ #include "factory.hpp" +#include #include "bar.hpp" +#include "gtkmm/enums.h" #if defined(HAVE_CHRONO_TIMEZONES) || defined(HAVE_LIBDATE) #include "modules/clock.hpp" @@ -110,10 +112,20 @@ #include "modules/temperature.hpp" #include "modules/user.hpp" -waybar::Factory::Factory(const Bar& bar, const Json::Value& config) : bar_(bar), config_(config) {} +waybar::Factory::Factory(const Bar& bar, const Json::Value& config) : bar_(bar), config_(config) { +} + +std::shared_ptr waybar::Factory::addModule(const std::string& name, + const std::string& pos) { + auto module = makeModule(name, pos, *this); + std::shared_ptr module_sp(module); + modules_all_.emplace_back(module_sp); + return module_sp; +} waybar::AModule* waybar::Factory::makeModule(const std::string& name, - const std::string& pos) const { + const std::string& pos, + waybar::Factory& factory) const { try { auto hash_pos = name.find('#'); auto ref = name.substr(0, hash_pos); @@ -325,6 +337,16 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name, if (ref.compare(0, 5, "cffi/") == 0 && ref.size() > 5) { return new waybar::modules::CFFI(ref.substr(5), id, config_[name]); } + if (ref.compare(0, 6, "group/") == 0 && ref.size() > 6) { + return new waybar::Group( + ref.substr(6), + hash_pos != std::string::npos ? ref.substr(hash_pos + 1) : "", + config_[name], + bar_.box_.get_orientation() == Gtk::ORIENTATION_VERTICAL, + pos, + factory + ); + } } catch (const std::exception& e) { auto err = fmt::format("Disabling module \"{}\", {}", name, e.what()); throw std::runtime_error(err); diff --git a/src/group.cpp b/src/group.cpp index 262cae656..07fe5bc64 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -19,13 +19,12 @@ const Gtk::RevealerTransitionType getPreferredTransitionType(bool is_vertical) { if (is_vertical) { return Gtk::RevealerTransitionType::REVEALER_TRANSITION_TYPE_SLIDE_UP; - } else { - return Gtk::RevealerTransitionType::REVEALER_TRANSITION_TYPE_SLIDE_LEFT; } + return Gtk::RevealerTransitionType::REVEALER_TRANSITION_TYPE_SLIDE_LEFT; } Group::Group(const std::string& name, const std::string& id, const Json::Value& config, - bool vertical) + bool vertical, const std::string& pos, Factory& factory) : AModule(config, name, id, true, true), box{vertical ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL, 0}, revealer_box{vertical ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL, 0} { @@ -81,6 +80,26 @@ Group::Group(const std::string& name, const std::string& id, const Json::Value& addHoverHandlerTo(revealer); } + + auto module_list = config_["modules"]; + if (module_list.isArray()) { + for (const auto& name : module_list) { + try { + auto ref = name.asString(); + auto module = factory.addModule(ref, pos); + addWidget(*module); + module->dp.connect([module, ref] { + try { + module->update(); + } catch (const std::exception& e) { + spdlog::error("{}: {}", ref, e.what()); + } + }); + } catch (const std::exception& e) { + spdlog::warn("module {}: {}", name.asString(), e.what()); + } + } + } } bool Group::handleMouseHover(GdkEventCrossing* const& e) {