refactor(tray): infer changed properties from signal name
Comparing two GVariants is too expensive; let's collect the set of properties updated by each signal and apply them unconditionally.pull/1145/head
parent
929fc16994
commit
4b6253e810
|
@ -11,6 +11,9 @@
|
||||||
#include <libdbusmenu-gtk/dbusmenu-gtk.h>
|
#include <libdbusmenu-gtk/dbusmenu-gtk.h>
|
||||||
#include <sigc++/trackable.h>
|
#include <sigc++/trackable.h>
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
namespace waybar::modules::SNI {
|
namespace waybar::modules::SNI {
|
||||||
|
|
||||||
class Item : public sigc::trackable {
|
class Item : public sigc::trackable {
|
||||||
|
@ -64,7 +67,7 @@ class Item : public sigc::trackable {
|
||||||
|
|
||||||
Glib::RefPtr<Gio::DBus::Proxy> proxy_;
|
Glib::RefPtr<Gio::DBus::Proxy> proxy_;
|
||||||
Glib::RefPtr<Gio::Cancellable> cancellable_;
|
Glib::RefPtr<Gio::Cancellable> cancellable_;
|
||||||
bool update_pending_;
|
std::set<std::string_view> update_pending_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules::SNI
|
} // namespace waybar::modules::SNI
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
#include "modules/sni/item.hpp"
|
#include "modules/sni/item.hpp"
|
||||||
|
|
||||||
#include <gdkmm/general.h>
|
#include <gdkmm/general.h>
|
||||||
#include <glibmm/main.h>
|
#include <glibmm/main.h>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct fmt::formatter<Glib::ustring> : formatter<std::string> {
|
struct fmt::formatter<Glib::ustring> : formatter<std::string> {
|
||||||
|
@ -40,8 +43,7 @@ Item::Item(const std::string& bn, const std::string& op, const Json::Value& conf
|
||||||
object_path(op),
|
object_path(op),
|
||||||
icon_size(16),
|
icon_size(16),
|
||||||
effective_icon_size(0),
|
effective_icon_size(0),
|
||||||
icon_theme(Gtk::IconTheme::create()),
|
icon_theme(Gtk::IconTheme::create()) {
|
||||||
update_pending_(false) {
|
|
||||||
if (config["icon-size"].isUInt()) {
|
if (config["icon-size"].isUInt()) {
|
||||||
icon_size = config["icon-size"].asUInt();
|
icon_size = config["icon-size"].asUInt();
|
||||||
}
|
}
|
||||||
|
@ -148,8 +150,6 @@ void Item::setProperty(const Glib::ustring& name, Glib::VariantBase& value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Item::getUpdatedProperties() {
|
void Item::getUpdatedProperties() {
|
||||||
update_pending_ = false;
|
|
||||||
|
|
||||||
auto params = Glib::VariantContainerBase::create_tuple(
|
auto params = Glib::VariantContainerBase::create_tuple(
|
||||||
{Glib::Variant<Glib::ustring>::create(SNI_INTERFACE_NAME)});
|
{Glib::Variant<Glib::ustring>::create(SNI_INTERFACE_NAME)});
|
||||||
proxy_->call("org.freedesktop.DBus.Properties.GetAll",
|
proxy_->call("org.freedesktop.DBus.Properties.GetAll",
|
||||||
|
@ -166,10 +166,7 @@ void Item::processUpdatedProperties(Glib::RefPtr<Gio::AsyncResult>& _result) {
|
||||||
auto properties = properties_variant.get();
|
auto properties = properties_variant.get();
|
||||||
|
|
||||||
for (const auto& [name, value] : properties) {
|
for (const auto& [name, value] : properties) {
|
||||||
Glib::VariantBase old_value;
|
if (update_pending_.count(name.raw())) {
|
||||||
proxy_->get_cached_property(old_value, name);
|
|
||||||
if (!old_value || !value.equal(old_value)) {
|
|
||||||
proxy_->set_cached_property(name, value);
|
|
||||||
setProperty(name, const_cast<Glib::VariantBase&>(value));
|
setProperty(name, const_cast<Glib::VariantBase&>(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,18 +178,37 @@ void Item::processUpdatedProperties(Glib::RefPtr<Gio::AsyncResult>& _result) {
|
||||||
} catch (const std::exception& err) {
|
} catch (const std::exception& err) {
|
||||||
spdlog::warn("Failed to update properties: {}", err.what());
|
spdlog::warn("Failed to update properties: {}", err.what());
|
||||||
}
|
}
|
||||||
|
update_pending_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mapping from a signal name to a set of possibly changed properties.
|
||||||
|
* Commented signals are not handled by the tray module at the moment.
|
||||||
|
*/
|
||||||
|
static const std::map<std::string_view, std::set<std::string_view>> signal2props = {
|
||||||
|
{"NewTitle", {"Title"}},
|
||||||
|
{"NewIcon", {"IconName", "IconPixmap"}},
|
||||||
|
// {"NewAttentionIcon", {"AttentionIconName", "AttentionIconPixmap", "AttentionMovieName"}},
|
||||||
|
// {"NewOverlayIcon", {"OverlayIconName", "OverlayIconPixmap"}},
|
||||||
|
{"NewIconThemePath", {"IconThemePath"}},
|
||||||
|
{"NewToolTip", {"ToolTip"}},
|
||||||
|
{"NewStatus", {"Status"}},
|
||||||
|
// {"XAyatanaNewLabel", {"XAyatanaLabel"}},
|
||||||
|
};
|
||||||
|
|
||||||
void Item::onSignal(const Glib::ustring& sender_name, const Glib::ustring& signal_name,
|
void Item::onSignal(const Glib::ustring& sender_name, const Glib::ustring& signal_name,
|
||||||
const Glib::VariantContainerBase& arguments) {
|
const Glib::VariantContainerBase& arguments) {
|
||||||
spdlog::trace("Tray item '{}' got signal {}", id, signal_name);
|
spdlog::trace("Tray item '{}' got signal {}", id, signal_name);
|
||||||
if (!update_pending_ && signal_name.compare(0, 3, "New") == 0) {
|
auto changed = signal2props.find(signal_name.raw());
|
||||||
/* Debounce signals and schedule update of all properties.
|
if (changed != signal2props.end()) {
|
||||||
* Based on behavior of Plasma dataengine for StatusNotifierItem.
|
if (update_pending_.empty()) {
|
||||||
*/
|
/* Debounce signals and schedule update of all properties.
|
||||||
update_pending_ = true;
|
* Based on behavior of Plasma dataengine for StatusNotifierItem.
|
||||||
Glib::signal_timeout().connect_once(sigc::mem_fun(*this, &Item::getUpdatedProperties),
|
*/
|
||||||
UPDATE_DEBOUNCE_TIME);
|
Glib::signal_timeout().connect_once(sigc::mem_fun(*this, &Item::getUpdatedProperties),
|
||||||
|
UPDATE_DEBOUNCE_TIME);
|
||||||
|
}
|
||||||
|
update_pending_.insert(changed->second.begin(), changed->second.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue