Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing DBus service for tray #2437

Open
Mikilio opened this issue Aug 28, 2023 · 5 comments
Open

Missing DBus service for tray #2437

Mikilio opened this issue Aug 28, 2023 · 5 comments

Comments

@Mikilio
Copy link

Mikilio commented Aug 28, 2023

DBus service file I'm using:

# /usr/share/dbus-1/services/org.kde.StatusNotifierWatcher.service
[D-BUS Service]
Name=org.kde.StatusNotifierWatcher
Exec=/usr/bin/waybar
# comment SystemdService to start waybar directly
SystemdService=waybar.service

While testing this, I found that Qt apps may fail to display icon when waybar is started with dbus service.
This happens because Qt5 expects both org.kde.StatusNotifierWatcher and org.kde.StatusNotifierHost to be ready by the moment of QSystemTrayIcon initialization. Since there's an obvious time lag between the registration of those interfaces, only Watcher is ready when the Qt app checks IsStatusNotifierHostRegistered.
As a result, we get qt.qpa.menu: StatusNotifierHost is not registered instead of the icon.

tl;dr: exec 'sleep 1; nextcloud' in sway config actually has higher chance to work 😞

Originally posted by @alebastr in #483 (comment)

Ideally this should be added to the project.

@mutoroglin
Copy link
Contributor

I do have the same issue with the nextcloud-client whenever I launch waybar. Thanks for the workaround @Mikilio and it would be great if this is corrected in waybar

@pshirshov
Copy link

pshirshov commented Sep 15, 2023

This is an extremely annoying issue. We need some way to check that the tray is initialized and ready to use.

Relevant: #1864

@pshirshov
Copy link

#2197

@pshirshov
Copy link

There seems to be a reliable workaround:

  systemd.user.services.hyprland-tray-init-shim = {
    Unit = {
      Description = "hyprland-tray-init-shim";
      StopWhenUnneeded = true;
      ConditionEnvironment = "WAYLAND_DISPLAY";
      Requires = [ "waybar.service" ];
      After = [ "waybar.service" ];
    };

    Service = {
      ExecStart =
        "${pkgs.bash}/bin/bash -c 'while ! dbus-send --session --dest=org.freedesktop.DBus --type=method_call --print-reply /org/freedesktop/DBus org.freedesktop.DBus.ListNames | grep org.kde.StatusNotifierWatcher; do sleep 0.1; done'";
      RemainAfterExit = true;
      Type = "oneshot";
      Environment = [ "PATH=/run/current-system/sw/bin" ];
    };

    Install.WantedBy = [ "hyprland-session.target" ];
  };

This systemd unit waits until waybar tray is ready (by checking that a dbus service is advertised) then exits. This check seems be more reliable than sleeps.

@genevieve-me
Copy link

genevieve-me commented Sep 24, 2023

This systemd unit waits until waybar tray is ready ... then exits.

Having my systemd user services launch after this service does work for me, but causes up to a 15 second delay before waybar appears and my tray apps start. Edit: Waybar doesn't actually have a long delay before advertising StatusNotifierWatcher : tested by running the above bash snippet and cold starting waybar, and the bash job exits almost immediately. However, when sway is first started, waybar is waiting for something before finishing startup. Even when manually launched from a CLI during that 15 second period after sway starts, it just emits [info] Using configuration file ... and hangs. Based on the output of systemctl --user list-jobs I suspect it's the XDG desktop portal:

42  graphical-session.target                         start waiting
83  xdg-desktop-portal.service                       start running
138 xdg-desktop-portal-wlr.service                   start waiting
61  nextcloud-client.service                         start waiting
41  sway-session.target                              start waiting

While this unfortunately makes the workaround less usable for me, I think this is an issue with my (home-manager's) systemd setup, not with waybar itself. In general, if programs have previously connected to the system bus to provide tray icons, and the StatusNotifierHost is stopped and started later, the tray icons will persist (waybar will pick them up). But here, programs decide on launch that no tray is available and therefore won't connect to dbus to provide them for the rest of their lifespan.

Regardless, even after I patched waybar to support dbus activation, I observed the following : when waybar was not running and I restarted nextcloud-client, waybar was started (so the dbus service file was in effect) but nextcloud-client still didn't show any tray icon. I'm not sure why this occurs : I would have thought that the dbus server would "wai[t] for the application to finish launching and then (if all goes well) delive[r] the message" to set up a tray icon, as described in the KDE docs.

Waybar patch for dbus activation service file

From 0e27aa8b6159cba5af5f480697e92bc6d50485fc Mon Sep 17 00:00:00 2001
From: Genevieve <[email protected]>
Date: Sun, 24 Sep 2023 15:01:45 -0400
Subject: [PATCH] Enable dbus activation

Waybar takes a while to advertise its tray capabilities, so applications will
act as though no tray is available even if they are started AFTER waybar
is finished launching (for example, systemd services with
`After=waybar.service`.

This change registers waybar for dbus activation, so it will be started if not
present when an application requests a tray. Ideally it should also tell
applications to wait for waybar's tray to be ready when they request one.

[1] https://dbus.freedesktop.org/doc/dbus-specification.html
[2] https://develop.kde.org/docs/features/d-bus/dbus_autostart_services/
---
 meson.build                                        | 6 ++++++
 resources/org.kde.StatusNotifierWatcher.service.in | 4 ++++
 2 files changed, 10 insertions(+)
 create mode 100644 resources/org.kde.StatusNotifierWatcher.service.in

diff --git a/meson.build b/meson.build
index 9ccd83d..1fc7f0e 100644
--- a/meson.build
+++ b/meson.build
@@ -292,6 +292,12 @@ if dbusmenu_gtk.found()
         'src/modules/sni/host.cpp',
         'src/modules/sni/item.cpp'
     )
+    configure_file(
+      configuration: conf_data,
+      input: './resources/org.kde.StatusNotifierWatcher.service.in',
+      output: '@BASENAME@',
+      install_dir: get_option('datadir') + '/dbus-1/services'
+    )
 endif
 
 if libudev.found() and (is_linux or libepoll.found())
diff --git a/resources/org.kde.StatusNotifierWatcher.service.in b/resources/org.kde.StatusNotifierWatcher.service.in
new file mode 100644
index 0000000..544fedd
--- /dev/null
+++ b/resources/org.kde.StatusNotifierWatcher.service.in
@@ -0,0 +1,4 @@
+[D-BUS Service]
+Name=org.kde.StatusNotifierWatcher
+Exec=@prefix@/bin/waybar
+SystemdService=waybar.service
-- 
2.42.0

(It's also probably worth linking to #2221 and noting the work to codify a replacement XDG spec, since StatusNotifierItem is old and not well loved, but it doesn't appear to me that work will be finished for a while.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants