diff options
Diffstat (limited to 'swaybar/tray/host.c')
-rw-r--r-- | swaybar/tray/host.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/swaybar/tray/host.c b/swaybar/tray/host.c index c5756f17..30339fec 100644 --- a/swaybar/tray/host.c +++ b/swaybar/tray/host.c @@ -115,6 +115,25 @@ static bool register_to_watcher(struct swaybar_host *host) { return ret >= 0; } +static int handle_new_watcher(sd_bus_message *msg, + void *data, sd_bus_error *error) { + char *service, *old_owner, *new_owner; + int ret = sd_bus_message_read(msg, "sss", &service, &old_owner, &new_owner); + if (ret < 0) { + wlr_log(WLR_ERROR, "Failed to parse owner change message: %s", strerror(-ret)); + return ret; + } + + if (!*old_owner) { + struct swaybar_host *host = data; + if (strcmp(service, host->watcher_interface) == 0) { + register_to_watcher(host); + } + } + + return 0; +} + bool init_host(struct swaybar_host *host, char *protocol, struct swaybar_tray *tray) { size_t len = snprintf(NULL, 0, "org.%s.StatusNotifierWatcher", protocol) + 1; @@ -124,7 +143,7 @@ bool init_host(struct swaybar_host *host, char *protocol, } snprintf(host->watcher_interface, len, "org.%s.StatusNotifierWatcher", protocol); - sd_bus_slot *reg_slot = NULL, *unreg_slot = NULL; + sd_bus_slot *reg_slot = NULL, *unreg_slot = NULL, *watcher_slot = NULL; int ret = sd_bus_match_signal(tray->bus, ®_slot, host->watcher_interface, watcher_path, host->watcher_interface, "StatusNotifierItemRegistered", handle_sni_registered, tray); @@ -142,6 +161,15 @@ bool init_host(struct swaybar_host *host, char *protocol, goto error; } + ret = sd_bus_match_signal(tray->bus, &watcher_slot, "org.freedesktop.DBus", + "/org/freedesktop/DBus", "org.freedesktop.DBus", "NameOwnerChanged", + handle_new_watcher, host); + if (ret < 0) { + wlr_log(WLR_ERROR, "Failed to subscribe to unregistering events: %s", + strerror(-ret)); + goto error; + } + pid_t pid = getpid(); size_t service_len = snprintf(NULL, 0, "org.%s.StatusNotifierHost-%d", protocol, pid) + 1; @@ -163,12 +191,14 @@ bool init_host(struct swaybar_host *host, char *protocol, sd_bus_slot_set_floating(reg_slot, 1); sd_bus_slot_set_floating(unreg_slot, 1); + sd_bus_slot_set_floating(watcher_slot, 1); wlr_log(WLR_DEBUG, "Registered %s", host->service); return true; error: sd_bus_slot_unref(reg_slot); sd_bus_slot_unref(unreg_slot); + sd_bus_slot_unref(watcher_slot); finish_host(host); return false; } |