Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/modules/sni/host.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@ namespace waybar::modules::SNI {
class Host {
public:
Host(const std::size_t id, const Json::Value&, const Bar&,
const std::vector<std::string>&,
const std::function<void(std::unique_ptr<Item>&)>&,
const std::function<void(std::unique_ptr<Item>&)>&);
~Host();

void checkIgnoreList(const std::vector<std::string>& ignore_list,
const std::function<void(std::unique_ptr<Item>&)>& on_remove);

private:
void busAcquired(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring);
Expand All @@ -41,6 +45,7 @@ class Host {
SnWatcher* watcher_ = nullptr;
const Json::Value& config_;
const Bar& bar_;
const std::vector<std::string> ignore_list_;
const std::function<void(std::unique_ptr<Item>&)> on_add_;
const std::function<void(std::unique_ptr<Item>&)> on_remove_;
};
Expand Down
3 changes: 3 additions & 0 deletions include/modules/sni/tray.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ class Tray : public AModule {
private:
void onAdd(std::unique_ptr<Item>& item);
void onRemove(std::unique_ptr<Item>& item);
void checkIgnoreList(std::unique_ptr<Item>* item);
std::vector<std::string> parseIgnoreList(const Json::Value& config);

static inline std::size_t nb_hosts_ = 0;
bool show_passive_ = false;
Gtk::Box box_;
SNI::Watcher::singleton watcher_;
std::vector<std::string> ignore_list_;
SNI::Host host_;
};

Expand Down
48 changes: 48 additions & 0 deletions src/modules/sni/host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
namespace waybar::modules::SNI {

Host::Host(const std::size_t id, const Json::Value& config, const Bar& bar,
const std::vector<std::string>& ignore_list,
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()) + "-" +
Expand All @@ -16,6 +17,7 @@ Host::Host(const std::size_t id, const Json::Value& config, const Bar& bar,
sigc::mem_fun(*this, &Host::busAcquired))),
config_(config),
bar_(bar),
ignore_list_(ignore_list),
on_add_(on_add),
on_remove_(on_remove) {}

Expand All @@ -33,6 +35,39 @@ Host::~Host() {
g_clear_object(&watcher_);
}

void Host::checkIgnoreList(const std::vector<std::string>& ignore_list,
const std::function<void(std::unique_ptr<Item>&)>& on_remove) {
spdlog::debug("Host::checkIgnoreList - checking {} items against {} patterns", items_.size(), ignore_list.size());

for (auto it = items_.begin(); it != items_.end(); ) {
auto& item = *it;
spdlog::debug(" Checking item: bus_name='{}', category='{}', icon_name='{}', title='{}'",
item->bus_name, item->category, item->icon_name, item->title);

bool should_remove = false;

for (const auto& ignored : ignore_list) {
if (item->bus_name.find(ignored) != std::string::npos ||
item->category.find(ignored) != std::string::npos ||
item->icon_name.find(ignored) != std::string::npos ||
item->id.find(ignored) != std::string::npos ||
item->title.find(ignored) != std::string::npos) {
spdlog::info("Host: Ignoring item bus_name='{}', category='{}', icon_name='{}', title='{}' - matched pattern '{}'",
item->bus_name, item->category, item->icon_name, item->title, ignored);
on_remove(item);
should_remove = true;
break;
}
}

if (should_remove) {
it = items_.erase(it);
} else {
++it;
}
}
}

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),
Expand Down Expand Up @@ -100,7 +135,9 @@ void Host::registerHost(GObject* src, GAsyncResult* res, gpointer 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) {
spdlog::info("Host: Found {} pre-registered SNI items", g_strv_length(items));
for (uint32_t i = 0; items[i] != nullptr; i += 1) {
spdlog::info("Host: Processing pre-registered item: {}", items[i]);
host->addRegisteredItem(items[i]);
}
}
Expand All @@ -109,7 +146,9 @@ void Host::registerHost(GObject* src, GAsyncResult* res, gpointer data) {

void Host::itemRegistered(SnWatcher* watcher, const gchar* service, gpointer data) {
auto host = static_cast<SNI::Host*>(data);
spdlog::info("Host::itemRegistered called with service: {}", service);
host->addRegisteredItem(service);
//host->checkIgnoreList(host->ignore_list_, std::bind(&Host::itemUnregistered, host, std::placeholders::_1, std::placeholders::_2, data));
}

void Host::itemUnregistered(SnWatcher* watcher, const gchar* service, gpointer data) {
Expand All @@ -133,12 +172,21 @@ std::tuple<std::string, std::string> Host::getBusNameAndObjectPath(const std::st
}

void Host::addRegisteredItem(std::string service) {
// Check service string directly before parsing
for (const auto& ignored : ignore_list_) {
if (service.find(ignored) != std::string::npos) {
spdlog::info("Host: Ignoring service '{}' - matched pattern '{}'", service, ignored);
return;
}
}
std::string bus_name, object_path;
std::tie(bus_name, object_path) = getBusNameAndObjectPath(service);
spdlog::debug("SNI item registered: bus_name={}, object_path={}, full_service={}", bus_name, object_path, 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()) {
spdlog::debug("Adding SNI item: {}", bus_name);
items_.emplace_back(new Item(bus_name, object_path, config_, bar_));
on_add_(items_.back());
}
Expand Down
38 changes: 37 additions & 1 deletion src/modules/sni/tray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,29 @@

namespace waybar::modules::SNI {

std::vector<std::string> Tray::parseIgnoreList(const Json::Value& config) {
std::vector<std::string> ignore_list;
if (config["ignore-list"].isArray()) {
spdlog::info("Tray: Found ignore-list with {} items", config["ignore-list"].size());
for (const auto& item : config["ignore-list"]) {
if (item.isString()) {
ignore_list.push_back(item.asString());
spdlog::info("Tray: Adding to ignore list: {}", item.asString());
}
}
} else {
spdlog::info("Tray: No ignore-list configured");
}
return ignore_list;
}

Tray::Tray(const std::string& id, const Bar& bar, const Json::Value& config)
: AModule(config, "tray", id),
box_(bar.orientation, 0),
watcher_(SNI::Watcher::getInstance()),
host_(nb_hosts_, config, bar, std::bind(&Tray::onAdd, this, std::placeholders::_1),
ignore_list_(parseIgnoreList(config)),
host_(nb_hosts_, config, bar, ignore_list_,
std::bind(&Tray::onAdd, this, std::placeholders::_1),
std::bind(&Tray::onRemove, this, std::placeholders::_1)) {
box_.set_name("tray");
event_box_.add(box_);
Expand All @@ -33,12 +51,24 @@ Tray::Tray(const std::string& id, const Bar& bar, const Json::Value& config)
dp.emit();
}

void Tray::checkIgnoreList(std::unique_ptr<Item>* item_ptr) {
// Delegate to Host's checkIgnoreList method
host_.checkIgnoreList(ignore_list_, std::bind(&Tray::onRemove, this, std::placeholders::_1));
}

void Tray::onAdd(std::unique_ptr<Item>& item) {
spdlog::info("Tray::onAdd - item bus_name='{}', category='{}', icon_name='{}', title='{}'",
item->bus_name, item->category, item->icon_name, item->title);

if (config_["reverse-direction"].isBool() && config_["reverse-direction"].asBool()) {
box_.pack_end(item->event_box);
} else {
box_.pack_start(item->event_box);
}

spdlog::debug("Tray::onAdd deferred check - checking ignore list");
host_.checkIgnoreList(ignore_list_, std::bind(&Tray::onRemove, this, std::placeholders::_1));

dp.emit();
}

Expand All @@ -48,6 +78,12 @@ void Tray::onRemove(std::unique_ptr<Item>& item) {
}

auto Tray::update() -> void {
// Check if any items should be ignored now that properties have loaded
if (!ignore_list_.empty()) {
spdlog::debug("Tray::update() - checking ignore list");
host_.checkIgnoreList(ignore_list_, std::bind(&Tray::onRemove, this, std::placeholders::_1));
}

// Show tray only when items are available
std::vector<Gtk::Widget*> children = box_.get_children();
if (show_passive_) {
Expand Down