From 67df5f58384678e1ef9523bc17bee957551bea04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Piwo=C5=84ski?= Date: Sun, 30 Mar 2025 14:49:07 +0000 Subject: [PATCH] feat(Group): enhance widget visibility management - set visibility instantly on module update using dynamic signal handling. Improve performance - manage the visibility of updated module only instead of iterating over all modules on `hide_group`. --- include/AModule.hpp | 1 + include/group.hpp | 7 +++-- src/AModule.cpp | 1 + src/bar.cpp | 2 +- src/group.cpp | 75 ++++++++++++++++++++++++++------------------- 5 files changed, 51 insertions(+), 35 deletions(-) diff --git a/include/AModule.hpp b/include/AModule.hpp index 2ffc429c..f31b4354 100644 --- a/include/AModule.hpp +++ b/include/AModule.hpp @@ -15,6 +15,7 @@ class AModule : public IModule { static constexpr const char *MODULE_CLASS = "module"; ~AModule() override; + sigc::signal signal_updated; auto update() -> void override; virtual auto refresh(int shouldRefresh) -> void {}; operator Gtk::Widget &() override; diff --git a/include/group.hpp b/include/group.hpp index 99419b45..462c05c2 100644 --- a/include/group.hpp +++ b/include/group.hpp @@ -17,7 +17,7 @@ class Group : public AModule { operator Gtk::Widget &() override; virtual Gtk::Box &getBox(); - void addWidget(Gtk::Widget &widget); + void addWidget(AModule* module); protected: Gtk::Box box; @@ -33,7 +33,10 @@ class Group : public AModule { bool handleToggle(GdkEventButton *const &ev) override; void show_group(); void hide_group(); - void update_always_visible_modules(); + void manage_visibility(AModule* module); + void show_widget(Gtk::Widget& widget); + void hide_widget(Gtk::Widget& widget); + void hide_current_widget_if_inactive(); }; } // namespace waybar diff --git a/src/AModule.cpp b/src/AModule.cpp index 5abb779a..0d5aaaba 100644 --- a/src/AModule.cpp +++ b/src/AModule.cpp @@ -95,6 +95,7 @@ auto AModule::update() -> void { if (config_["on-update"].isString()) { pid_.push_back(util::command::forkExec(config_["on-update"].asString())); } + signal_updated.emit(this); } // Get mapping between event name and module action name // Then call overrided doAction in order to call appropriate module action diff --git a/src/bar.cpp b/src/bar.cpp index b7737d36..db3402bb 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -506,7 +506,7 @@ void waybar::Bar::getModules(const Factory& factory, const std::string& pos, std::shared_ptr module_sp(module); modules_all_.emplace_back(module_sp); if (group != nullptr) { - group->addWidget(*module); + group->addWidget(module); } else { if (pos == "modules-left") { modules_left_.emplace_back(module_sp); diff --git a/src/group.cpp b/src/group.cpp index 5af1febb..40208714 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -92,52 +92,57 @@ void Group::show_group() { revealer.set_reveal_child(true); } -void Group::update_always_visible_modules() { - if (always_visible_class.empty()) { - return; - } +void Group::hide_widget(Gtk::Widget& widget) { + widget.get_style_context()->add_class(add_class_to_drawer_children); + box.remove(widget); + revealer_box.pack_start(widget, false, false); +} - for (auto* event_box : revealer_box.get_children()) { - if (auto container = dynamic_cast(event_box)) { - for (auto* base_element : container->get_children()) { - if (base_element->get_style_context()->has_class(always_visible_class)) { - event_box->get_style_context()->remove_class(add_class_to_drawer_children); - - revealer_box.remove(*event_box); - box.pack_end(*event_box, false, false); - event_box->show(); - } - } - } - } +void Group::show_widget(Gtk::Widget& widget) { + widget.get_style_context()->remove_class(add_class_to_drawer_children); + revealer_box.remove(widget); + box.pack_end(widget, false, false); +} +void Group::hide_current_widget_if_inactive() { for (auto* event_box : box.get_children()) { if (event_box == &revealer) { continue; } - if (box.get_children().size() <= 2) { - break; - } - if (auto container = dynamic_cast(event_box)) { - for (auto* base_element : container->get_children()) { - if (!base_element->get_style_context()->has_class(always_visible_class)) { - event_box->get_style_context()->add_class(add_class_to_drawer_children); - - box.remove(*event_box); - revealer_box.pack_start(*event_box, false, false); - event_box->show(); + if (auto event_box_container = dynamic_cast(event_box)) { + for (auto* the_only_visible : event_box_container->get_children()) { + if (!the_only_visible->get_style_context()->has_class(always_visible_class)) { + hide_widget(*event_box); } } } } +} +void Group::manage_visibility(AModule* module) { + Gtk::Widget& widget = *module; + + if (auto container = dynamic_cast(&widget)) { + for (auto* base_element : container->get_children()) { + if (base_element->get_style_context()->has_class(always_visible_class)) { + if (box.get_children().size() == 2) { + Group::hide_current_widget_if_inactive(); + } + show_widget(widget); + } else { + // Do not hide if it's the only widget + revealer + if (box.get_children().size() <= 2) { + return; + } + hide_widget(widget); + } + } + } } void Group::hide_group() { box.unset_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT); revealer.set_reveal_child(false); - - Group::update_always_visible_modules(); } bool Group::handleMouseEnter(GdkEventCrossing* const& e) { @@ -167,12 +172,14 @@ bool Group::handleToggle(GdkEventButton* const& e) { } auto Group::update() -> void { - Group::update_always_visible_modules(); + // noop } Gtk::Box& Group::getBox() { return is_drawer ? (is_first_widget ? box : revealer_box) : box; } -void Group::addWidget(Gtk::Widget& widget) { +void Group::addWidget(AModule* module) { + Gtk::Widget& widget = *module; + getBox().pack_start(widget, false, false); if (is_drawer && !is_first_widget) { @@ -180,6 +187,10 @@ void Group::addWidget(Gtk::Widget& widget) { } is_first_widget = false; + + if (!always_visible_class.empty()) { + module->signal_updated.connect(sigc::mem_fun(*this, &Group::manage_visibility)); + } } Group::operator Gtk::Widget&() { return event_box_; }