mirror of
https://github.com/rad4day/Waybar.git
synced 2023-12-21 10:22:59 +01:00
![Jan Beich](/assets/img/avatar_default.png)
In file included from ../src/factory.cpp:1: In file included from ../include/factory.hpp:4: ../include/modules/clock.hpp:5:10: fatal error: 'fmt/time.h' file not found #include "fmt/time.h" ^~~~~~~~~~~~ In file included from ../src/bar.cpp:4: In file included from ../include/factory.hpp:4: In file included from ../include/modules/clock.hpp:3: In file included from /usr/include/fmt/chrono.h:12: /usr/include/fmt/locale.h:19:35: error: parameter type 'fmt::v5::internal::buffer' (aka 'basic_buffer<char>') is an abstract class const std::locale& loc, buffer<Char>& buf, ^ /usr/include/spdlog/fmt/bundled/core.h:238:16: note: unimplemented pure virtual method 'grow' in 'basic_buffer' virtual void grow(std::size_t capacity) = 0; ^ In file included from ../src/modules/sni/host.cpp:3: /usr/include/fmt/ostream.h:22:9: error: expected member name or ';' after declaration specifiers buffer<Char>& buffer_; ~~~~~~^ /usr/include/fmt/ostream.h:25:19: error: expected ')' formatbuf(buffer<Char>& buf) : buffer_(buf) {} ^ /usr/include/fmt/ostream.h:25:12: note: to match this '(' formatbuf(buffer<Char>& buf) : buffer_(buf) {} ^ /usr/include/fmt/ostream.h:25:42: error: use of undeclared identifier 'buf'; did you mean 'prettify_handler::buf'? formatbuf(buffer<Char>& buf) : buffer_(buf) {} ^~~ prettify_handler::buf /usr/include/spdlog/fmt/bundled/format-inl.h:551:11: note: 'prettify_handler::buf' declared here buffer &buf; ^
144 lines
5.0 KiB
C++
144 lines
5.0 KiB
C++
#include "modules/sni/host.hpp"
|
|
#include <fmt/ostream.h>
|
|
#include <spdlog/spdlog.h>
|
|
|
|
namespace waybar::modules::SNI {
|
|
|
|
Host::Host(const std::size_t id, const Json::Value& config,
|
|
const std::function<void(std::unique_ptr<Item>&)>& on_add,
|
|
const std::function<void(std::unique_ptr<Item>&)>& on_remove)
|
|
: bus_name_("org.kde.StatusNotifierHost-" + std::to_string(getpid()) + "-" +
|
|
std::to_string(id)),
|
|
object_path_("/StatusNotifierHost/" + std::to_string(id)),
|
|
bus_name_id_(Gio::DBus::own_name(Gio::DBus::BusType::BUS_TYPE_SESSION, bus_name_,
|
|
sigc::mem_fun(*this, &Host::busAcquired))),
|
|
config_(config),
|
|
on_add_(on_add),
|
|
on_remove_(on_remove) {}
|
|
|
|
Host::~Host() {
|
|
if (bus_name_id_ > 0) {
|
|
Gio::DBus::unwatch_name(bus_name_id_);
|
|
bus_name_id_ = 0;
|
|
}
|
|
if (watcher_id_ > 0) {
|
|
Gio::DBus::unwatch_name(watcher_id_);
|
|
watcher_id_ = 0;
|
|
}
|
|
g_cancellable_cancel(cancellable_);
|
|
g_clear_object(&cancellable_);
|
|
g_clear_object(&watcher_);
|
|
}
|
|
|
|
void Host::busAcquired(const Glib::RefPtr<Gio::DBus::Connection>& conn, Glib::ustring name) {
|
|
watcher_id_ = Gio::DBus::watch_name(conn,
|
|
"org.kde.StatusNotifierWatcher",
|
|
sigc::mem_fun(*this, &Host::nameAppeared),
|
|
sigc::mem_fun(*this, &Host::nameVanished));
|
|
}
|
|
|
|
void Host::nameAppeared(const Glib::RefPtr<Gio::DBus::Connection>& conn, const Glib::ustring name,
|
|
const Glib::ustring& name_owner) {
|
|
if (cancellable_ != nullptr) {
|
|
// TODO
|
|
return;
|
|
}
|
|
cancellable_ = g_cancellable_new();
|
|
sn_watcher_proxy_new(conn->gobj(),
|
|
G_DBUS_PROXY_FLAGS_NONE,
|
|
"org.kde.StatusNotifierWatcher",
|
|
"/StatusNotifierWatcher",
|
|
cancellable_,
|
|
&Host::proxyReady,
|
|
this);
|
|
}
|
|
|
|
void Host::nameVanished(const Glib::RefPtr<Gio::DBus::Connection>& conn, const Glib::ustring name) {
|
|
g_cancellable_cancel(cancellable_);
|
|
g_clear_object(&cancellable_);
|
|
g_clear_object(&watcher_);
|
|
items_.clear();
|
|
}
|
|
|
|
void Host::proxyReady(GObject* src, GAsyncResult* res, gpointer data) {
|
|
GError* error = nullptr;
|
|
SnWatcher* watcher = sn_watcher_proxy_new_finish(res, &error);
|
|
if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
|
spdlog::error("Host: {}", error->message);
|
|
g_error_free(error);
|
|
return;
|
|
}
|
|
auto host = static_cast<SNI::Host*>(data);
|
|
host->watcher_ = watcher;
|
|
if (error != nullptr) {
|
|
spdlog::error("Host: {}", error->message);
|
|
g_error_free(error);
|
|
return;
|
|
}
|
|
sn_watcher_call_register_host(
|
|
host->watcher_, host->object_path_.c_str(), host->cancellable_, &Host::registerHost, data);
|
|
}
|
|
|
|
void Host::registerHost(GObject* src, GAsyncResult* res, gpointer data) {
|
|
GError* error = nullptr;
|
|
sn_watcher_call_register_host_finish(SN_WATCHER(src), res, &error);
|
|
if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
|
spdlog::error("Host: {}", error->message);
|
|
g_error_free(error);
|
|
return;
|
|
}
|
|
auto host = static_cast<SNI::Host*>(data);
|
|
if (error != nullptr) {
|
|
spdlog::error("Host: {}", error->message);
|
|
g_error_free(error);
|
|
return;
|
|
}
|
|
g_signal_connect(host->watcher_, "item-registered", G_CALLBACK(&Host::itemRegistered), data);
|
|
g_signal_connect(host->watcher_, "item-unregistered", G_CALLBACK(&Host::itemUnregistered), data);
|
|
auto items = sn_watcher_dup_registered_items(host->watcher_);
|
|
if (items != nullptr) {
|
|
for (uint32_t i = 0; items[i] != nullptr; i += 1) {
|
|
host->addRegisteredItem(items[i]);
|
|
}
|
|
}
|
|
g_strfreev(items);
|
|
}
|
|
|
|
void Host::itemRegistered(SnWatcher* watcher, const gchar* service, gpointer data) {
|
|
auto host = static_cast<SNI::Host*>(data);
|
|
host->addRegisteredItem(service);
|
|
}
|
|
|
|
void Host::itemUnregistered(SnWatcher* watcher, const gchar* service, gpointer data) {
|
|
auto host = static_cast<SNI::Host*>(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->on_remove_(*it);
|
|
host->items_.erase(it);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
std::tuple<std::string, std::string> Host::getBusNameAndObjectPath(const std::string service) {
|
|
auto it = service.find('/');
|
|
if (it != std::string::npos) {
|
|
return {service.substr(0, it), service.substr(it)};
|
|
}
|
|
return {service, "/StatusNotifierItem"};
|
|
}
|
|
|
|
void Host::addRegisteredItem(std::string service) {
|
|
auto [bus_name, object_path] = getBusNameAndObjectPath(service);
|
|
auto it = std::find_if(items_.begin(), items_.end(), [&bus_name, &object_path](const auto& item) {
|
|
return bus_name == item->bus_name && object_path == item->object_path;
|
|
});
|
|
if (it == items_.end()) {
|
|
items_.emplace_back(new Item(bus_name, object_path, config_));
|
|
on_add_(items_.back());
|
|
}
|
|
}
|
|
|
|
} // namespace waybar::modules::SNI
|