From 75c9477aa8182ed429cf795a21067443adb45b12 Mon Sep 17 00:00:00 2001 From: Alexis Date: Tue, 4 Sep 2018 23:50:08 +0200 Subject: [PATCH] feat(Tray): handle item unregister --- include/modules/sni/snh.hpp | 8 ++-- include/modules/sni/sni.hpp | 12 +++--- include/modules/sni/snw.hpp | 31 +++++++-------- src/bar.cpp | 6 +-- src/modules/battery.cpp | 6 +-- src/modules/pulseaudio.cpp | 2 +- src/modules/sni/snh.cpp | 57 +++++++++++++++------------ src/modules/sni/sni.cpp | 32 +++++++--------- src/modules/sni/snw.cpp | 68 ++++++++++++++++++++------------- src/modules/sni/tray.cpp | 8 ++-- src/modules/sway/window.cpp | 2 +- src/modules/sway/workspaces.cpp | 2 +- 12 files changed, 127 insertions(+), 107 deletions(-) diff --git a/include/modules/sni/snh.hpp b/include/modules/sni/snh.hpp index 585f2888..f0a3bc2f 100644 --- a/include/modules/sni/snh.hpp +++ b/include/modules/sni/snh.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include "modules/sni/sni.hpp" @@ -8,8 +9,7 @@ namespace waybar::modules::SNI { class Host { public: - Host(Glib::Dispatcher&); - ~Host(); + Host(Glib::Dispatcher*); std::vector items; private: static void busAcquired(GDBusConnection*, const gchar*, gpointer); @@ -23,14 +23,14 @@ class Host { static void itemUnregistered(SnOrgKdeStatusNotifierWatcher*, const gchar*, gpointer); - void getBusNameAndObjectPath(const gchar*, gchar**, gchar**); + std::tuple getBusNameAndObjectPath(const gchar*); void addRegisteredItem(const gchar* service); uint32_t bus_name_id_; uint32_t watcher_id_; std::string bus_name_; std::string object_path_; - Glib::Dispatcher& dp_; + Glib::Dispatcher* dp_; GCancellable* cancellable_ = nullptr; SnOrgKdeStatusNotifierWatcher* watcher_ = nullptr; }; diff --git a/include/modules/sni/sni.hpp b/include/modules/sni/sni.hpp index eb57902c..9b04404b 100644 --- a/include/modules/sni/sni.hpp +++ b/include/modules/sni/sni.hpp @@ -7,8 +7,12 @@ namespace waybar::modules::SNI { class Item { public: - Item(std::string, std::string, Glib::Dispatcher&); - ~Item(); + Item(std::string, std::string, Glib::Dispatcher*); + + std::string bus_name; + std::string object_path; + Gtk::EventBox event_box; + int icon_size; int effective_icon_size; Gtk::Image* image; @@ -31,9 +35,7 @@ class Item { void updateImage(); Glib::RefPtr getIconByName(std::string name, int size); - std::string bus_name_; - std::string object_path_; - Glib::Dispatcher& dp_; + Glib::Dispatcher* dp_; GCancellable* cancellable_ = nullptr; SnOrgKdeStatusNotifierItem* proxy_ = nullptr; }; diff --git a/include/modules/sni/snw.hpp b/include/modules/sni/snw.hpp index f8965e38..807b0f75 100644 --- a/include/modules/sni/snw.hpp +++ b/include/modules/sni/snw.hpp @@ -5,24 +5,25 @@ namespace waybar::modules::SNI { -typedef enum { - GF_WATCH_TYPE_HOST, - GF_WATCH_TYPE_ITEM -} GfWatchType; - -typedef struct { - GfWatchType type; - gchar* service; - gchar* bus_name; - gchar* object_path; - guint watch_id; -} GfWatch; - class Watcher { public: Watcher(); ~Watcher(); private: + typedef enum { + GF_WATCH_TYPE_HOST, + GF_WATCH_TYPE_ITEM + } GfWatchType; + + typedef struct { + GfWatchType type; + Watcher* watcher; + gchar* service; + gchar* bus_name; + gchar* object_path; + guint watch_id; + } GfWatch; + static void busAcquired(GDBusConnection*, const gchar*, gpointer); static gboolean handleRegisterHost(Watcher*, GDBusMethodInvocation*, const gchar*); @@ -30,8 +31,8 @@ class Watcher { GDBusMethodInvocation*, const gchar*); static GfWatch* gfWatchFind(GSList* list, const gchar* bus_name, const gchar* object_path); - static GfWatch* gfWatchNew(GfWatchType type, - const gchar* service, const gchar* bus_name, const gchar* object_path); + static GfWatch* gfWatchNew(GfWatchType, const gchar*, const gchar*, + const gchar*, Watcher*); static void nameVanished(GDBusConnection* connection, const char* name, gpointer data); diff --git a/src/bar.cpp b/src/bar.cpp index 750816ca..7b210186 100644 --- a/src/bar.cpp +++ b/src/bar.cpp @@ -198,14 +198,14 @@ auto waybar::Bar::setupWidgets() -> void getModules(factory, "modules-left"); getModules(factory, "modules-center"); getModules(factory, "modules-right"); - for (auto& module : modules_left_) { + for (auto const& module : modules_left_) { left.pack_start(*module, false, true, 0); } - for (auto& module : modules_center_) { + for (auto const& module : modules_center_) { center.pack_start(*module, true, true, 0); } std::reverse(modules_right_.begin(), modules_right_.end()); - for (auto& module : modules_right_) { + for (auto const& module : modules_right_) { right.pack_end(*module, false, false, 0); } } diff --git a/src/modules/battery.cpp b/src/modules/battery.cpp index 78470e77..002b8ed5 100644 --- a/src/modules/battery.cpp +++ b/src/modules/battery.cpp @@ -4,7 +4,7 @@ waybar::modules::Battery::Battery(const Json::Value& config) : ALabel(config, "{capacity}%") { try { - for (auto &node : fs::directory_iterator(data_dir_)) { + for (auto const& node : fs::directory_iterator(data_dir_)) { if (fs::is_directory(node) && fs::exists(node / "capacity") && fs::exists(node / "status") && fs::exists(node / "uevent")) { batteries_.push_back(node); @@ -20,7 +20,7 @@ waybar::modules::Battery::Battery(const Json::Value& config) if (fd_ == -1) { throw std::runtime_error("Unable to listen batteries."); } - for (auto &bat : batteries_) { + for (auto const& bat : batteries_) { inotify_add_watch(fd_, (bat / "uevent").c_str(), IN_ACCESS); } label_.set_name("battery"); @@ -51,7 +51,7 @@ auto waybar::modules::Battery::update() -> void try { uint16_t total = 0; std::string status; - for (auto &bat : batteries_) { + for (auto const& bat : batteries_) { uint16_t capacity; std::string _status; std::ifstream(bat / "capacity") >> capacity; diff --git a/src/modules/pulseaudio.cpp b/src/modules/pulseaudio.cpp index 4d41fd56..3e59a675 100644 --- a/src/modules/pulseaudio.cpp +++ b/src/modules/pulseaudio.cpp @@ -118,7 +118,7 @@ const std::string waybar::modules::Pulseaudio::getPortIcon() const "hifi", "phone", }; - for (auto port : ports) { + for (auto const& port : ports) { if (port_name_.find(port) != std::string::npos) { return port; } diff --git a/src/modules/sni/snh.cpp b/src/modules/sni/snh.cpp index 49a6fb89..4c5ae7e3 100644 --- a/src/modules/sni/snh.cpp +++ b/src/modules/sni/snh.cpp @@ -2,7 +2,9 @@ #include -waybar::modules::SNI::Host::Host(Glib::Dispatcher& dp) +using namespace waybar::modules::SNI; + +Host::Host(Glib::Dispatcher* dp) : dp_(dp) { GBusNameOwnerFlags flags = static_cast( @@ -14,11 +16,7 @@ waybar::modules::SNI::Host::Host(Glib::Dispatcher& dp) &Host::busAcquired, nullptr, nullptr, this, nullptr); } -waybar::modules::SNI::Host::~Host() -{ -} - -void waybar::modules::SNI::Host::busAcquired(GDBusConnection* connection, +void Host::busAcquired(GDBusConnection* connection, const gchar* name, gpointer data) { auto host = static_cast(data); @@ -29,7 +27,7 @@ void waybar::modules::SNI::Host::busAcquired(GDBusConnection* connection, &Host::nameAppeared, &Host::nameVanished, data, nullptr); } -void waybar::modules::SNI::Host::nameAppeared(GDBusConnection* connection, +void Host::nameAppeared(GDBusConnection* connection, const gchar* name, const gchar* name_owner, gpointer data) { auto host = static_cast(data); @@ -45,7 +43,7 @@ void waybar::modules::SNI::Host::nameAppeared(GDBusConnection* connection, host->cancellable_, &Host::proxyReady, data); } -void waybar::modules::SNI::Host::nameVanished(GDBusConnection* connection, +void Host::nameVanished(GDBusConnection* connection, const gchar* name, gpointer data) { auto host = static_cast(data); @@ -55,7 +53,7 @@ void waybar::modules::SNI::Host::nameVanished(GDBusConnection* connection, host->items.clear(); } -void waybar::modules::SNI::Host::proxyReady(GObject* src, GAsyncResult* res, +void Host::proxyReady(GObject* src, GAsyncResult* res, gpointer data) { GError* error = nullptr; @@ -78,7 +76,7 @@ void waybar::modules::SNI::Host::proxyReady(GObject* src, GAsyncResult* res, &Host::registerHost, data); } -void waybar::modules::SNI::Host::registerHost(GObject* src, GAsyncResult* res, +void Host::registerHost(GObject* src, GAsyncResult* res, gpointer data) { GError* error = nullptr; @@ -109,7 +107,7 @@ void waybar::modules::SNI::Host::registerHost(GObject* src, GAsyncResult* res, g_strfreev(items); } -void waybar::modules::SNI::Host::itemRegistered( +void Host::itemRegistered( SnOrgKdeStatusNotifierWatcher* watcher, const gchar* service, gpointer data) { std::cout << "Item registered" << std::endl; @@ -117,32 +115,41 @@ void waybar::modules::SNI::Host::itemRegistered( host->addRegisteredItem(service); } -void waybar::modules::SNI::Host::itemUnregistered( +void Host::itemUnregistered( SnOrgKdeStatusNotifierWatcher* watcher, const gchar* service, gpointer data) { - std::cout << "Item Unregistered" << std::endl; + auto host = static_cast(data); + auto [bus_name, object_path] = host->getBusNameAndObjectPath(service); + for (auto it = host->items.begin(); it != host->items.end(); ++it) { + if (it->bus_name == bus_name && it->object_path == object_path) { + host->items.erase(it); + std::cout << "Item Unregistered" << std::endl; + break; + } + } + host->dp_->emit(); } -void waybar::modules::SNI::Host::getBusNameAndObjectPath(const gchar* service, - gchar** bus_name, gchar** object_path) +std::tuple Host::getBusNameAndObjectPath( + const gchar* service) { - gchar* tmp = g_strstr_len (service, -1, "/"); + std::string bus_name; + std::string object_path; + gchar* tmp = g_strstr_len(service, -1, "/"); if (tmp != nullptr) { gchar** str = g_strsplit(service, "/", 2); - *bus_name = g_strdup(str[0]); - *object_path = g_strdup(tmp); + bus_name = str[0]; + object_path = tmp; g_strfreev(str); } else { - *bus_name = g_strdup(service); - *object_path = g_strdup("/StatusNotifierItem"); + bus_name = service; + object_path = "/StatusNotifierItem"; } + return { bus_name, object_path }; } -void waybar::modules::SNI::Host::addRegisteredItem(const gchar* service) +void Host::addRegisteredItem(const gchar* service) { - gchar* bus_name = nullptr; - gchar* object_path = nullptr; - - getBusNameAndObjectPath(service, &bus_name, &object_path); + auto [bus_name, object_path] = getBusNameAndObjectPath(service); items.emplace_back(bus_name, object_path, dp_); } \ No newline at end of file diff --git a/src/modules/sni/sni.cpp b/src/modules/sni/sni.cpp index 0cd06a71..ae5ca4ff 100644 --- a/src/modules/sni/sni.cpp +++ b/src/modules/sni/sni.cpp @@ -2,22 +2,19 @@ #include -waybar::modules::SNI::Item::Item(std::string bus_name, std::string object_path, - Glib::Dispatcher& dp) - : icon_size(16), effective_icon_size(0), - image(Gtk::manage(new Gtk::Image())), - bus_name_(bus_name), object_path_(object_path), dp_(dp) +waybar::modules::SNI::Item::Item(std::string bn, std::string op, + Glib::Dispatcher* dp) + : bus_name(bn), object_path(op), event_box(), + icon_size(16), effective_icon_size(0), + image(Gtk::manage(new Gtk::Image())), dp_(dp) { + event_box.add(*image); cancellable_ = g_cancellable_new(); sn_org_kde_status_notifier_item_proxy_new_for_bus(G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, bus_name_.c_str(), object_path_.c_str(), + G_DBUS_PROXY_FLAGS_NONE, bus_name.c_str(), object_path.c_str(), cancellable_, &Item::proxyReady, this); } -waybar::modules::SNI::Item::~Item() -{ -} - void waybar::modules::SNI::Item::proxyReady(GObject* obj, GAsyncResult* res, gpointer data) { @@ -36,8 +33,8 @@ void waybar::modules::SNI::Item::proxyReady(GObject* obj, GAsyncResult* res, return; } auto conn = g_dbus_proxy_get_connection(G_DBUS_PROXY(proxy)); - g_dbus_connection_call(conn, item->bus_name_.c_str(), - item->object_path_.c_str(), "org.freedesktop.DBus.Properties", "GetAll", + g_dbus_connection_call(conn, item->bus_name.c_str(), + item->object_path.c_str(), "org.freedesktop.DBus.Properties", "GetAll", g_variant_new("(s)", "org.kde.StatusNotifierItem"), G_VARIANT_TYPE("(a{sv})"), G_DBUS_CALL_FLAGS_NONE, -1, item->cancellable_, &Item::getAll, data); @@ -103,8 +100,8 @@ void waybar::modules::SNI::Item::getAll(GObject* obj, GAsyncResult* res, g_variant_iter_free(it); g_variant_unref(properties); if (item->id.empty() || item->category.empty() || item->status.empty()) { - std::cerr << "Invalid Status Notifier Item: " + item->bus_name_ + "," - + item->object_path_ << std::endl; + std::cerr << "Invalid Status Notifier Item: " + item->bus_name + "," + + item->object_path << std::endl; return; } if (!item->icon_theme_path.empty()) { @@ -113,7 +110,7 @@ void waybar::modules::SNI::Item::getAll(GObject* obj, GAsyncResult* res, item->icon_theme_path.c_str()); } item->updateImage(); - item->dp_.emit(); + item->dp_->emit(); // TODO: handle change } @@ -144,11 +141,10 @@ Glib::RefPtr waybar::modules::SNI::Item::getIconByName( std::string name, int request_size) { int icon_size = 0; - Glib::RefPtr icon_theme = - Gtk::IconTheme::get_default(); + Glib::RefPtr icon_theme = Gtk::IconTheme::get_default(); icon_theme->rescan_if_needed(); auto sizes = icon_theme->get_icon_sizes(name.c_str()); - for (auto size : sizes) { + for (auto const& size : sizes) { // -1 == scalable if (size == request_size || size == -1) { icon_size = request_size; diff --git a/src/modules/sni/snw.cpp b/src/modules/sni/snw.cpp index fc314f54..208cc1e1 100644 --- a/src/modules/sni/snw.cpp +++ b/src/modules/sni/snw.cpp @@ -2,7 +2,9 @@ #include -waybar::modules::SNI::Watcher::Watcher() +using namespace waybar::modules::SNI; + +Watcher::Watcher() { GBusNameOwnerFlags flags = static_cast( G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT @@ -13,12 +15,12 @@ waybar::modules::SNI::Watcher::Watcher() watcher_ = sn_org_kde_status_notifier_watcher_skeleton_new(); } -waybar::modules::SNI::Watcher::~Watcher() +Watcher::~Watcher() { } -void waybar::modules::SNI::Watcher::busAcquired(GDBusConnection* connection, - const gchar* name, gpointer data) +void Watcher::busAcquired(GDBusConnection* connection, const gchar* name, + gpointer data) { GError* error = nullptr; auto host = static_cast(data); @@ -41,9 +43,8 @@ void waybar::modules::SNI::Watcher::busAcquired(GDBusConnection* connection, std::cout << "Bus aquired" << std::endl; } -gboolean waybar::modules::SNI::Watcher::handleRegisterHost( - Watcher* obj, GDBusMethodInvocation* invocation, - const gchar* service) +gboolean Watcher::handleRegisterHost(Watcher* obj, + GDBusMethodInvocation* invocation, const gchar* service) { const gchar* bus_name = service; const gchar* object_path = "/StatusNotifierHost"; @@ -64,7 +65,7 @@ gboolean waybar::modules::SNI::Watcher::handleRegisterHost( bus_name, object_path); return TRUE; } - watch = gfWatchNew(GF_WATCH_TYPE_HOST, service, bus_name, object_path); + watch = gfWatchNew(GF_WATCH_TYPE_HOST, service, bus_name, object_path, obj); obj->hosts_ = g_slist_prepend(obj->hosts_, watch); sn_org_kde_status_notifier_watcher_set_is_status_notifier_host_registered( obj->watcher_, TRUE); @@ -78,9 +79,8 @@ gboolean waybar::modules::SNI::Watcher::handleRegisterHost( return TRUE; } -gboolean waybar::modules::SNI::Watcher::handleRegisterItem( - Watcher* obj, GDBusMethodInvocation* invocation, - const gchar* service) +gboolean Watcher::handleRegisterItem(Watcher* obj, + GDBusMethodInvocation* invocation, const gchar* service) { const gchar* bus_name = service; const gchar* object_path = "/StatusNotifierItem"; @@ -102,7 +102,7 @@ gboolean waybar::modules::SNI::Watcher::handleRegisterItem( obj->watcher_, invocation); return TRUE; } - watch = gfWatchNew(GF_WATCH_TYPE_ITEM, service, bus_name, object_path); + watch = gfWatchNew(GF_WATCH_TYPE_ITEM, service, bus_name, object_path, obj); obj->items_ = g_slist_prepend(obj->items_, watch); obj->updateRegisteredItems(obj->watcher_); gchar* tmp = g_strdup_printf("%s%s", bus_name, object_path); @@ -114,8 +114,8 @@ gboolean waybar::modules::SNI::Watcher::handleRegisterItem( return TRUE; } -waybar::modules::SNI::GfWatch* waybar::modules::SNI::Watcher::gfWatchFind( - GSList* list, const gchar* bus_name, const gchar* object_path) +Watcher::GfWatch* Watcher::gfWatchFind(GSList* list, const gchar* bus_name, + const gchar* object_path) { for (GSList* l = list; l != nullptr; l = g_slist_next (l)) { GfWatch* watch = static_cast(l->data); @@ -127,12 +127,12 @@ waybar::modules::SNI::GfWatch* waybar::modules::SNI::Watcher::gfWatchFind( return nullptr; } -waybar::modules::SNI::GfWatch* waybar::modules::SNI::Watcher::gfWatchNew( - GfWatchType type, const gchar* service, const gchar* bus_name, - const gchar* object_path) +Watcher::GfWatch* Watcher::gfWatchNew(GfWatchType type, const gchar* service, + const gchar* bus_name, const gchar* object_path, Watcher* watcher) { GfWatch* watch = g_new0(GfWatch, 1); watch->type = type; + watch->watcher = watcher; watch->service = g_strdup(service); watch->bus_name = g_strdup(bus_name); watch->object_path = g_strdup(object_path); @@ -142,26 +142,40 @@ waybar::modules::SNI::GfWatch* waybar::modules::SNI::Watcher::gfWatchNew( return watch; } -void waybar::modules::SNI::Watcher::nameVanished(GDBusConnection* connection, - const char* name, gpointer data) +void Watcher::nameVanished(GDBusConnection* connection, const char* name, + gpointer data) { - //TODO - std::cout << "name vanished" << std::endl; + auto watch = static_cast(data); + if (watch->type == GF_WATCH_TYPE_HOST) { + watch->watcher->hosts_ = g_slist_remove(watch->watcher->hosts_, watch); + if (watch->watcher->hosts_ == nullptr) { + sn_org_kde_status_notifier_watcher_set_is_status_notifier_host_registered( + watch->watcher->watcher_, FALSE); + sn_org_kde_status_notifier_watcher_emit_status_notifier_host_registered( + watch->watcher->watcher_); + } + } else if (watch->type == GF_WATCH_TYPE_ITEM) { + watch->watcher->items_ = g_slist_remove(watch->watcher->items_, watch); + watch->watcher->updateRegisteredItems(watch->watcher->watcher_); + gchar* tmp = g_strdup_printf("%s%s", watch->bus_name, watch->object_path); + sn_org_kde_status_notifier_watcher_emit_status_notifier_item_unregistered( + watch->watcher->watcher_, tmp); + g_free(tmp); + } } -void waybar::modules::SNI::Watcher::updateRegisteredItems( - SnOrgKdeStatusNotifierWatcher* obj) +void Watcher::updateRegisteredItems(SnOrgKdeStatusNotifierWatcher* obj) { GVariantBuilder builder; g_variant_builder_init(&builder, G_VARIANT_TYPE("as")); for (GSList* l = items_; l != nullptr; l = g_slist_next(l)) { GfWatch* watch = static_cast(l->data); - gchar* item = g_strdup_printf ("%s%s", watch->bus_name, watch->object_path); - g_variant_builder_add (&builder, "s", item); - g_free (item); + gchar* item = g_strdup_printf("%s%s", watch->bus_name, watch->object_path); + g_variant_builder_add(&builder, "s", item); + g_free(item); } GVariant* variant = g_variant_builder_end(&builder); - const gchar** items = g_variant_get_strv (variant, nullptr); + const gchar** items = g_variant_get_strv(variant, nullptr); sn_org_kde_status_notifier_watcher_set_registered_status_notifier_items( obj, items); g_variant_unref(variant); diff --git a/src/modules/sni/tray.cpp b/src/modules/sni/tray.cpp index 6ddf7447..4a6b932e 100644 --- a/src/modules/sni/tray.cpp +++ b/src/modules/sni/tray.cpp @@ -3,15 +3,15 @@ #include waybar::modules::SNI::Tray::Tray(const Json::Value& config) - : config_(config), watcher_(), host_(dp) + : config_(config), watcher_(), host_(&dp) { } auto waybar::modules::SNI::Tray::update() -> void { - for (auto item : host_.items) { - item.image->set_tooltip_text(item.title); - box_.pack_start(*item.image); + for (auto& item : host_.items) { + item.event_box.set_tooltip_text(item.title); + box_.pack_start(item.event_box); } if (box_.get_children().size() > 0) { box_.set_name("tray"); diff --git a/src/modules/sway/window.cpp b/src/modules/sway/window.cpp index a2f4469b..8faf7491 100644 --- a/src/modules/sway/window.cpp +++ b/src/modules/sway/window.cpp @@ -44,7 +44,7 @@ auto waybar::modules::sway::Window::update() -> void std::tuple waybar::modules::sway::Window::getFocusedNode( Json::Value nodes) { - for (auto &node : nodes) { + for (auto const& node : nodes) { if (node["focused"].asBool() && node["type"] == "con") { return { node["id"].asInt(), node["name"].asString() }; } diff --git a/src/modules/sway/workspaces.cpp b/src/modules/sway/workspaces.cpp index 3e74801b..878f783c 100644 --- a/src/modules/sway/workspaces.cpp +++ b/src/modules/sway/workspaces.cpp @@ -49,7 +49,7 @@ auto waybar::modules::sway::Workspaces::update() -> void ++it; } } - for (auto node : workspaces_) { + for (auto const& node : workspaces_) { if (!config_["all-outputs"].asBool() && bar_.output_name != node["output"].asString()) { continue;