mirror of
https://github.com/swaywm/sway
synced 2024-11-26 09:03:54 +01:00
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:
03483ff370/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
This commit is contained in:
parent
03483ff370
commit
f23d100747
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user