On Replacing AllTray & Other Docking Software

Oct 21st
Posted by Michael Trausch  as FLOSS, GNU/Linux, GPLv3, UNIX, Ubuntu, computing, gnome

This post is a bit of a “brain dump” of sorts for some thoughts that I have as to replacing AllTray with a more versatile, powerful, and robust tool to handle various needs of users when it comes to taking applications and docking them to the system tray.

Why?

I’ve used AllTray for a long time. It is one of those pieces of software that performs a useful function, but you have to know its quirks to make it do what you want quite often, and you have to work around some of the things that it does for it to retain that usefulness. Users shouldn’t have to do that—they should just be able to start using a program or utility and have it work properly. Also, utilities should be (reasonably) independent of the environment that they run within, which AllTray isn’t. And, good utilities should integrate with the system pretty well, which AllTray does not, since it carries a hard dependency on GDK/GTK. (Kdocker is an alternative piece of software, and while I don’t know how well it works compared to AllTray, I know that it is bound to Qt, which is just as bad.)

The license will most likely be GPLv3, since nothing will actually link to it and it’s not a library. If there is a library component, it will be LGPLv3.

The actual “braindump”

The actual *docking* part isn’t terribly hard, it would seem. With GTK+ it can be done in only a few lines of code (especially in C#). However, C# wouldn’t be the language to use for the this tool, because of the dependency on Mono. My thinking is that the proper language to use would be C itself. It makes me think of how easy everything would be if only the desktop environment and all its software were already written in managed code… the effective cost of using C# would be significantly less than it is already.

Using C as the language isn’t that big a deal to me. What is a big deal to me is that the application be well-integrated and well-behaved. For example, AllTray depends on GTK for some of its tasks, and uses a custom (ugly, IMHO) widget for displaying its title when you over over it in the system tray. There’s another program out there, KDocker, that would appear to be slightly more featureful than AllTray, but it carries with it a dependency on Qt, which I don’t like. Ideally, the core for such a docking utility should be able to have various back-ends that serve the purpose of integration with the system, with a single back-end that would apply without dependencies on anything else for the rare scenario where neither GTK+ nor Qt are available.

What would this thing be required to do?

  • Dock any arbitrary application to the system tray, not just a single window from the application. (Using the System Tray Protocol Specification)
  • Run in a single instance, managing multiple applications within that instance if necessary.
  • Provide session management for those who use it, and act as a session manager for applications that are run underneath it that support session management.
  • Be able to use something like inotify to be able to show an indication of when the application’s title for its windows change.
  • Use a single icon for the application, with a window list if the application carries more than a single window.
  • Use individual backends which provide a native look and feel depending on the desktop environment currently in use.
  • Use the application’s icon to represent the application in the system tray.
  • Support blinking the icon when the application decides to do something like present a modal dialog box or something (if this is even possible, that much I am not quite sure of).
  • Detect the desktop environment currently in use and (if possible) load a backend to integrate with it.
  • Carry a dependency on GLib so as to make implementing it quicker and less error-prone.
  • NOT carry any hard dependencies on any widget libraries like GTK+ or Qt.
  • Return an error to the user if there is no running system tray, and there isn’t one after some sort of timeout (say, when starting the desktop environment, there may not be a system tray right away). (I don’t think that sort of situation would be commonplace, but it’s not really the job of this program to create a system tray if one doesn’t exist, since this is the job of the desktop environment.)

The backends would not have any specific configuration items (the entire configuration would be housed somewhere like ${HOME}/.config/docker, for example). There probably ought to be a backend entrypoint that would show a dialog for configuration, but I haven’t really figured out if that’d be the case yet. The docker should probably do all of its configuration by way of the command line for each invocation, which is suitable for use as a desktop shortcut or panel launcher.

This approach requires that each individual desktop environment have its own backend, which might become a bit of a pain for supporting a great number of desktop environments, but the upshot of that is that the application then feels native no matter what environment the user is using. Obviously support for GNOME and KDE would happen, and most everything else would depend on someone with programming experience for various environments to implement a backend for it.

The backend doesn’t handle, say, docking, since there’s a standard for that already. It would handle things like displaying the tip when hovered over or displaying a menu when right-clicked. So, the job that each backend would do would be pretty lightweight. And as much as possible should be handled in the core, with the backend consisting of just enough “hooks” into the target system to be able to provide a useful interface.

The way that this would have to work, using C as the programming language, would be that the core would have to use dlopen() and friends to load the backend and then use the entrypoints that the backend provides. Since dlopen, dlclose, dlsym, and dlerror are defined by POSIX.1-2001, support for those should be in every reasonably modern Unix-like system that supports at least a subset of POSIX. This of course eliminates Windows, but I am not terribly worried about that since there are probably other Windows-only utilities that serve this purpose.

The primary goal, then, is to replace other DE-dependent and toolkit-dependent dockers with a utility that carries the goal to be universally useful and highly robust. The aim of this goal is to replace AllTray entirely in (at the very least) Ubuntu, and hopefully be seen as useful in other distributions as well.

I’ll need some help…

This is the part where it’ll get interesting. I’ll need some help in actually doing this, in many areas.

For the moment, where I’ll need help (be that from Google, or from people in-the-know that happen upon this post) is to find all of the documentation that I’ll need to understand how to implement the software. I can use software that already exists to try to learn how the underlying system works, to a degree anyway. But some of the software doesn’t handle various situations correctly (or I don’t have a way to see if it does) and so studying them would be less than useful for everything I am trying to do. Namely, the things I need to find out yet are:

  • How to run a program in such a way as to be able to reliably know what windows belong to the program and be able to dock them. I suspect that it’d involve using LD_PRELOAD and some monitoring trickery, but I would hope that there is some sort of API to do this already. Also, need to know how to manage the application itself; say it continues running but without any windows, the tray icon should obviously disappear while it’s running like that, until it has windows to manage again.
  • How to perform session management and be a session manager for subordinate programs. (I might be able to study the source for KDocker to learn the answer to that, though I am not 100% certain yet of that.) I also have a paper to read yet on the subject that may have all the information that I am looking for, though I am not certain there yet, either.
  • How to reliably detect the running desktop environment without resorting to ugly kludges and ad-hoc trickery.
  • How to work independent of the currently-running window manager and operate reliably for any standards-compliant WM that is running, without having to special-case for various types of software or various types of window managers.

I suspect that there is useful documentation out there for most (if not all) of those things for X11 and other relevant points. I just haven’t found what I am looking for yet for all of it. Standards documents and system documentation are useful things to find, and maybe an example or two of source code on how to do it as well, are what I am looking for, so that I can try to understand these things better.

At some point down the road, I’ll need help with getting the backends written when they have an API to conform to. I can, in all probability, write a GTK+ backend that will work for XFCE and GNOME since I use GNOME. However, I don’t use KDE or anything that runs on top of Qt, so I will definitely need help from someone that is familiar with writing software for Qt to get a Qt backend written. If XFCE has any sort of non-standard special UI guidelines that are incompatible with GNOME, then I’ll need some help there, too. Any other non-GNOME or non-KDE environments (such as GNUstep, if it supports it anyway) that support the System Tray Protocol Specification will need backends written for them by people that are able to do so.

Leave a Reply

Powered By Wordpress || Designed By Ridgey