aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoan Bruguera Micó <joanbrugueram@gmail.com>2024-11-10 15:24:15 +0000
committerSimon Ser <contact@emersion.fr>2024-11-28 20:39:59 +0100
commit4da33f1dd18986e7a147a38a5dfae21db75f22bf (patch)
treeac589e392087b93c154de1bbb92d4cd774067a9c
parent79c8197381e0e2cffc65c670702d50cbafcccbbd (diff)
swaybar: Emit property changes for SNI watcher
Emit property change signals for the IsStatusNotifierHostRegistered and RegisteredStatusNotifierItems properties in StatusNotifierWatcher, so code relying on the PropertiesChanged signal, instead of signals such as StatusNotifierHostRegistered, can work properly. A library that is affected by this is the libappindicator-gtk3* library and it can cause tray icons to be missing after starting swaybar due to a race condition, as follows: * An application using libappindicator-gtk3 starts, e.g. nm-applet. * Some time later, swaybar starts. * swaybar creates the StatusNotifierWatcher. * libappindicator-gtk3 observes the new watcher, but it sees that IsStatusNotifierHostRegistered=false, so it falls back to the Freedesktop System tray protocol. * swaybar creates the StatusNotifierHost. At this point, libappindicator-gtk3 should "un-fallback" back to SNI. However, since swaybar does not emit the PropertiesChange signal on IsStatusNotifierHostRegistered, libappindicator-gtk3 doesn't get notified, and stays in fallback state forever. * As a result, nm-applet will not show in the swaybar tray. This race can be made reliable by inserting a 1-second long sleep here: https://github.com/swaywm/sway/blob/03483ff3707a358d935e451d39748e58c205ce8a/swaybar/tray/tray.c#L57 (*) Note that the libappindicator-gtk3 library has been mostly replaced by libayatana-appindicator, which is not affected by this. The affected version is still used by Arch Linux, source code at: https://bazaar.launchpad.net/~indicator-applet-developers/libappindicator/trunk/files/298 (cherry picked from commit f23d10074739de31e9339796dc06348fd919c515)
-rw-r--r--swaybar/tray/watcher.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/swaybar/tray/watcher.c b/swaybar/tray/watcher.c
index 3cfea8d8..54f000bd 100644
--- a/swaybar/tray/watcher.c
+++ b/swaybar/tray/watcher.c
@@ -38,6 +38,8 @@ static int handle_lost_service(sd_bus_message *msg,
list_del(watcher->items, idx--);
sd_bus_emit_signal(watcher->bus, obj_path, watcher->interface,
"StatusNotifierItemUnregistered", "s", id);
+ sd_bus_emit_properties_changed(watcher->bus, obj_path, watcher->interface,
+ "RegisteredStatusNotifierItems", NULL);
free(id);
if (using_standard_protocol(watcher)) {
break;
@@ -50,6 +52,10 @@ static int handle_lost_service(sd_bus_message *msg,
sway_log(SWAY_DEBUG, "Unregistering Status Notifier Host '%s'", service);
free(watcher->hosts->items[idx]);
list_del(watcher->hosts, idx);
+ if (watcher->hosts->length == 0) {
+ sd_bus_emit_properties_changed(watcher->bus, obj_path, watcher->interface,
+ "IsStatusNotifierHostRegistered", NULL);
+ }
}
}
@@ -82,6 +88,8 @@ static int register_sni(sd_bus_message *msg, void *data, sd_bus_error *error) {
if (list_seq_find(watcher->items, cmp_id, id) == -1) {
sway_log(SWAY_DEBUG, "Registering Status Notifier Item '%s'", id);
list_add(watcher->items, id);
+ sd_bus_emit_properties_changed(watcher->bus, obj_path, watcher->interface,
+ "RegisteredStatusNotifierItems", NULL);
sd_bus_emit_signal(watcher->bus, obj_path, watcher->interface,
"StatusNotifierItemRegistered", "s", id);
} else {
@@ -104,6 +112,10 @@ static int register_host(sd_bus_message *msg, void *data, sd_bus_error *error) {
if (list_seq_find(watcher->hosts, cmp_id, service) == -1) {
sway_log(SWAY_DEBUG, "Registering Status Notifier Host '%s'", service);
list_add(watcher->hosts, strdup(service));
+ if (watcher->hosts->length == 1) {
+ sd_bus_emit_properties_changed(watcher->bus, obj_path, watcher->interface,
+ "IsStatusNotifierHostRegistered", NULL);
+ }
sd_bus_emit_signal(watcher->bus, obj_path, watcher->interface,
"StatusNotifierHostRegistered", "");
} else {