From 5a2b5624dcd0afc5b2a94a5df32faea0fc39811b Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Fri, 29 Mar 2019 18:40:28 -0700 Subject: [PATCH] feat(tray): process tray icon update signals --- include/modules/sni/item.hpp | 5 +++ src/modules/sni/item.cpp | 61 ++++++++++++++++++++++++++++++++++-- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/include/modules/sni/item.hpp b/include/modules/sni/item.hpp index 10388cd9..016ca4e6 100644 --- a/include/modules/sni/item.hpp +++ b/include/modules/sni/item.hpp @@ -50,6 +50,10 @@ public: private: void proxyReady(Glib::RefPtr& result); void setProperty(const Glib::ustring& name, Glib::VariantBase& value); + void getUpdatedProperties(); + void processUpdatedProperties(Glib::RefPtr& result); + void onSignal(const Glib::ustring& sender_name, const Glib::ustring& signal_name, + const Glib::VariantContainerBase& arguments); void updateImage(); Glib::RefPtr extractPixBuf(GVariant *variant); @@ -60,6 +64,7 @@ private: Glib::RefPtr cancellable_; Glib::RefPtr proxy_; + bool update_pending_; }; } // namespace waybar::modules::SNI diff --git a/src/modules/sni/item.cpp b/src/modules/sni/item.cpp index ddc6354a..fdd481a2 100644 --- a/src/modules/sni/item.cpp +++ b/src/modules/sni/item.cpp @@ -1,14 +1,16 @@ #include "modules/sni/item.hpp" #include +#include using namespace Glib; static const ustring SNI_INTERFACE_NAME = sn_item_interface_info()->name; +static const unsigned UPDATE_DEBOUNCE_TIME = 10; waybar::modules::SNI::Item::Item(std::string bn, std::string op, const Json::Value& config) - : bus_name(bn), object_path(op), icon_size(16), effective_icon_size(0) -{ + : bus_name(bn), object_path(op), icon_size(16), effective_icon_size(0), + update_pending_(false) { if (config["icon-size"].isUInt()) { icon_size = config["icon-size"].asUInt(); } @@ -36,6 +38,8 @@ void waybar::modules::SNI::Item::proxyReady(Glib::RefPtr& resu setProperty(name, value); } + this->proxy_->signal_signal().connect(sigc::mem_fun(*this, &Item::onSignal)); + if (this->id.empty() || this->category.empty() || this->status.empty()) { std::cerr << "Invalid Status Notifier Item: " + this->bus_name + "," + this->object_path << std::endl; @@ -100,6 +104,59 @@ waybar::modules::SNI::Item::setProperty(const ustring& name, } } +void +waybar::modules::SNI::Item::getUpdatedProperties() { + update_pending_ = false; + + auto params = VariantContainerBase::create_tuple({ + Variant::create(SNI_INTERFACE_NAME) + }); + proxy_->call("org.freedesktop.DBus.Properties.GetAll", + sigc::mem_fun(*this, &Item::processUpdatedProperties), params); +}; + +void +waybar::modules::SNI::Item::processUpdatedProperties( + Glib::RefPtr& _result) { + try { + auto result = proxy_->call_finish(_result); + // extract "a{sv}" from VariantContainerBase + Variant> properties_variant; + result.get_child(properties_variant); + auto properties = properties_variant.get(); + + for (const auto& [name, value]: properties) { + VariantBase old_value; + proxy_->get_cached_property(old_value, name); + if (!value.equal(old_value)) { + proxy_->set_cached_property(name, value); + setProperty(name, const_cast(value)); + } + } + + this->updateImage(); + // this->event_box.set_tooltip_text(this->title); + } catch (const Glib::Error& err) { + g_warning("Failed to update properties: %s", err.what().c_str()); + } catch (const std::exception& err) { + g_warning("Failed to update properties: %s", err.what()); + } +} + +void +waybar::modules::SNI::Item::onSignal(const ustring& sender_name, + const ustring& signal_name, const VariantContainerBase& arguments) { + if (!update_pending_ && signal_name.compare(0, 3, "New") == 0) { + /* Debounce signals and schedule update of all properties. + * Based on behavior of Plasma dataengine for StatusNotifierItem. + */ + update_pending_ = true; + Glib::signal_timeout().connect_once( + sigc::mem_fun(*this, &Item::getUpdatedProperties), UPDATE_DEBOUNCE_TIME); + } +} + + static void pixbuf_data_deleter(const guint8* data) { g_free((void*) data);