SNI: Properly unsubscribe from item reload signal

I think not unsubscribing is the root cause of the mysterious calling of
ItemPropertyChanged from random names/object paths.
This commit is contained in:
scorpion-26 2023-08-24 00:09:05 +02:00
parent 383f25dbe1
commit aee06ab49d

View file

@ -41,6 +41,7 @@ namespace SNI
EventBox* gtkEvent = nullptr; EventBox* gtkEvent = nullptr;
int watcherID = -1; int watcherID = -1;
int propertyChangeWatcherID = -1;
}; };
std::vector<Item> items; std::vector<Item> items;
@ -301,6 +302,7 @@ namespace SNI
{ {
LOG("SNI: " << name << " vanished!"); LOG("SNI: " << name << " vanished!");
g_bus_unwatch_name(it->watcherID); g_bus_unwatch_name(it->watcherID);
g_dbus_connection_signal_unsubscribe(dbusConnection, it->propertyChangeWatcherID);
items.erase(it); items.erase(it);
InvalidateWidget(); InvalidateWidget();
return; return;
@ -318,6 +320,11 @@ namespace SNI
static void ItemPropertyChanged(GDBusConnection*, const char* senderName, const char* object, const char*, const char*, GVariant*, void* name) static void ItemPropertyChanged(GDBusConnection*, const char* senderName, const char* object, const char*, const char*, GVariant*, void* name)
{ {
// I think the multiple calling of this callback is a symptom of not unsubscribing the ItemPropertyChanged callback. Since this is now done, I
// think the reloadedNames and object path checking is no longer needed. Since it doesn't do any harm (except being a little bit pointless)
// I'll leave the checks here for now.
// TODO: Investigate whether it is now actually fixed
if (reloadedNames.insert(senderName).second == false) if (reloadedNames.insert(senderName).second == false)
{ {
// senderName has already requested a change, ignore // senderName has already requested a change, ignore
@ -327,19 +334,32 @@ namespace SNI
std::string nameStr = (const char*)name; std::string nameStr = (const char*)name;
LOG("SNI: Reloading " << (const char*)name << " " << object << " (Sender: " << senderName << ")"); LOG("SNI: Reloading " << (const char*)name << " " << object << " (Sender: " << senderName << ")");
// We don't care about *what* changed, just remove and reload
// We can't trust the object path given to us, since ItemPropertyChanged is called multiple times with the same name, but with different
// object paths.
auto it = std::find_if(items.begin(), items.end(), auto it = std::find_if(items.begin(), items.end(),
[&](const Item& item) [&](const Item& item)
{ {
return item.name == nameStr; return item.name == nameStr;
}); });
// We can't trust the object path given to us, since ItemPropertyChanged is called multiple times with the same name, but with different std::string itemObjectPath;
// object paths. if (it != items.end())
std::string itemObjectPath = it->object; {
itemObjectPath = it->object;
}
else
{
// Item not already registered, fallback to provided name and hope the object path provided is accurate
LOG("SNI: Couldn't find name for actual object path!");
itemObjectPath = object;
}
// We don't care about *what* changed, just remove and reload
LOG("SNI: Actual object path: " << itemObjectPath) LOG("SNI: Actual object path: " << itemObjectPath)
if (it != items.end()) if (it != items.end())
{ {
g_bus_unwatch_name(it->watcherID); g_bus_unwatch_name(it->watcherID);
g_dbus_connection_signal_unsubscribe(dbusConnection, it->propertyChangeWatcherID);
items.erase(it); items.erase(it);
} }
else else
@ -376,7 +396,8 @@ namespace SNI
// Add handler for icon change // Add handler for icon change
char* staticBuf = new char[item.name.size() + 1]{0x0}; char* staticBuf = new char[item.name.size() + 1]{0x0};
memcpy(staticBuf, item.name.c_str(), item.name.size()); memcpy(staticBuf, item.name.c_str(), item.name.size());
g_dbus_connection_signal_subscribe( LOG("SNI: Allocating static name buffer for " << item.name);
item.propertyChangeWatcherID = g_dbus_connection_signal_subscribe(
dbusConnection, item.name.c_str(), "org.kde.StatusNotifierItem", nullptr, nullptr, nullptr, G_DBUS_SIGNAL_FLAGS_NONE, dbusConnection, item.name.c_str(), "org.kde.StatusNotifierItem", nullptr, nullptr, nullptr, G_DBUS_SIGNAL_FLAGS_NONE,
ItemPropertyChanged, staticBuf, ItemPropertyChanged, staticBuf,
+[](void* ptr) +[](void* ptr)