-
Notifications
You must be signed in to change notification settings - Fork 2k
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
D-Bus implementation of system tray support #11703
Comments
Leaving a note here that I'm currently in the process of learning DBus, and I plan to at least try to implement the system tray with it. I'm not sure how much time it'll take me; if someone more familiar with DBus than me would like to take the torch, just let me know so I can shift my efforts on something else :) Also, shouldn't the title of the issue be "DBus implementation" rather than "AppIndicator"? |
We've had to recently switch from libappindicator to a manual DBus implementation due to the GTK4 migration, as you can't load both GTK3 and 4 in a single process. This was implemented here: slgobinath/SafeEyes#558, but needed to be adjusted to also include some non-standard attributes like slgobinath/SafeEyes#646 since desktop environments expect it, it seems. |
Developers could implement an unlimited number of incompatible system-tray protocols over D-Bus if they wanted to (and perhaps they already have). D-Bus is just a message delivery protocol and some conventions for how to use it, and the only protocols that are standardized at the D-Bus level are features of the message bus itself, and a few basic building blocks like Properties and ObjectManager. Anything higher-level is outside D-Bus' scope, the same way that the Standard C committee probably don't know anything about SDL. If the desired feature is something like "be compatible with Ubuntu AppIndicator" or "be compatible with KDE StatusNotifierItem", it would be worthwhile to mention one of those in the title. Something compatible with both ubuntu/gnome-shell-extension-appindicator and KDE Plasma is probably the closest to standardization that we're going to see any time soon.
D-Bus, the protocol, has no guarantees either way on this. The message bus (usually dbus-daemon or dbus-broker, dbus-daemon is the reference implementation) just passes methods to the service and passes replies back. So this is a fact about the D-Bus library you used to implement the service (QtDBus?) rather than a fact about the D-Bus protocol. The wire protocol does technically allow overloading (and lots of other inadvisable things), but that isn't part of the interoperable subset of the protocol and not all client libraries will allow it. It's conventional to behave as though overloading isn't possible, and give methods with different arguments different names if it becomes necessary (e.g. |
The intent of the title was more "Stop depending on libappindicator to support KStatusNotifierItem". That's why it was split out of #10873 where the initial libappindicator implementation was added. libappindicator's Launchpad page flat-out says "Based on KSNI" and ubuntu/gnome-shell-extension-appindicator also implements the same thing as evidenced by the KSNI IDL file in their repo.
Thanks. TIL.
IIRC, the overloading-implying error messages I was referring to were being emitted by dbus-daemon as plaintext strings in message bodies and swallowed up by QtDBus, only visible because I was using |
@ssokolow : just wanted to say that I'm excited with your intention here 👍 I just had a nightmare Effectively, one or the other library ended up overwriting the That said, though, I plan on porting all of opensim-creator's platform code (i.e. everything that isn't CPU/memory/OpenGL) to SDL3 eventually, which puts nativefiledialog in my crosshairs! Keep up the good work ❤ |
:) Here's hoping I can find some time to extend my PyQt QtDBus demonstration/proof of concept/exploratory piece with the remaining bits and pieces (mainly |
Given that I've never implemented that specific D-Bus API using PyQt5 (my API of choice for my own creations at the moment), I got nerd-sniped and decided to implement a Python proof of concept for practice with the API.
It's bedtime, but I've successfully exercised most of the functionality on offer. Granted, two of the parts that are left are important to what SDL would want, but they're more things I don't have time for tonight than things I anticipate having trouble with:
ContextMenu(x, y)
method. (Shouldn't be difficult... just a bit time-consuming since I don't have a "D-Bus XML schema to PyQt5 QDBus" boilerplate generator, so I need to transcribe the relevant bits of thecom.canonical.dbusmenu
schema by hand first.)(According to ubuntu/gnome-shell-extension-appindicator, rich tooltips, which also need compound data types, were never implemented by libappindicator or Unity to begin with and I doubt SDL has a pressing need for overlay icons or custom-animated "needs attention" tray icon states.)
I have, however, already discovered something relevant. It looks like the FreeDesktop version of the spec stalled once it became clear that GNOME had no interest in implementing tray icons of any kind.
My Kubuntu Linux 22.04 LTS doesn't implement
org.freedesktop.StatusNotifierItem
and does implementorg.kde.StatusNotifierItem
and the interface definition in ubuntu/gnome-shell-extension-appindicator also uses that interface name though, so far, aside fromorg.kde
instead oforg.freedesktop
, I have produced interfaces my Plasma 5.x is OK with by following what is described on FreeDesktop.org....so, yeah. If anyone has any questions about implementing the StatusNotifierItem API, I'm now in a better position to answer them.
I'm not sure what details you consider significant, but I'm certainly willing to give it a shot.
At the highest level, the gist of how it works is:
org.kde.StatusNotifierItem
interface, with properties likeCategory
(set it to "ApplicationStatus") to define the icon's appearance and behaviour, and with methods likeAction
andScroll
which will be called by the SNI host when the user interacts with it.org.kde.StatusNotifierWatcher.RegisterStatusNotifierItem
method under/StatusNotifierWatcher
onorg.kde.StatusNotifierWatcher
(the name the active SNI host will claim) and it takes the service name you registered in step 1 as a string as its only argument.org.kde.StatusNotifierItem.*
properties you implemented and to get a listing of which methods have been implemented and will create an icon based on what it finds. (eg. whether left-clicking and right-clicking do the same thing depends on whether you've registered separate handlers forAction
andContextMenu
and whether theItemIsMenu
boolean property is true or false.)This XML schema is what
ubuntu/gnome-shell-extension-appindicator
is feeding toGDBusProxy
to describe what it expects to find while the FreeDesktop document goes into more detail on what the argument values should be but doesn't touch on "not standard, but widely implemented" extensions to the API.As far as tooling goes, here are the tools I used which I'd highly recommend:
qdbusviewer
from Qt's development tools (eg.qttools5-dev-tools
for Qt 5 on *buntu Linux) provides a great interactive browser for D-Bus introspection, as well as being a GUI for interactively querying properties and calling methods with sufficiently simple type signatures. The dialog that pops up when double-clicking a method is also a great way to check what type signature you're exporting. (I made good use of it to verify that I was exporting the API that I thought I was.)dbus-monitor
is a non-graphical tool for logging what's flowing over the bus to diagnose things which tends to be part of the same package as the D-Bus daemon itself. (eg. Very useful for stuff like seeing which error messages the D-Bus daemon is returning to the SNI Host when your type signatures aren't quite right on stuff it's supposed to call.)dbus-monitor
which is much more amenable to exclusion-based filtering than baredbus-monitor
if you want to look at "everything except the irrelevant cruft that Workrave, Yakuake, and Pidgin are flooding the bus with". It also, in my experience, presents the argument lists for method calls in a format that's cleaner for lining up and comparing when you have a working SNI implementation and a buggy SNI implementation side-by-side. (D-Bus will tell you there's no such method if the signatures don't match. I haven't checked if that's because it supports method overloading, but I've never seen any APIs use that if it does.)Also, in case you want to poke at a working implementation for basically everything relevant except for the
IconThemePath
property (a non-standard-but-commonly-implemented extension for amending the search path forIconName
), theIconPixmap
property, and theMenu
property (For describing a menu for the panel host to render, as opposed to theContextMenu
method where you draw it yourself at the specified x,y coordinates), here's the current state of my PyQt5+QtDBus practice piece as I left it last night:https://gist.github.com/ssokolow/1cbe7d9341d6b4401b17c0f7eebbd2b8
(I'll update it when I make more time to keep working on it.)
Beyond that, I'll wait for you to ask further questions.
Originally posted by @ssokolow in #10873 (comment)
The text was updated successfully, but these errors were encountered: