Re: System tray windows



On Thu, Mar 28, 2002 at 06:59:58PM -0500, Havoc Pennington wrote:
> 
> Hi,
> 
> So I talked to Owen about this issue for a while, and played with the
> KDE 3 implementation (recent RPMs from the Red Hat beta).
> 
> I think Gregory is right on two points:
> 
>  - there is no real reason to have the window manager involved; 
>    seems to just create odd issues
> 
>  - the KDE setup does not handle multiple system trays at all 
>    well. I added several to the panel, and got some 
>    entertaining infinite loops with system tray icons 
>    moving around between trays, sometimes a tray eventually 
>    manages to get one permanently but which one will get the 
>    icon is random.
> 
> Looking at the KDE source code, I discovered another interesting
> point, which is that KDE already uses QXEmbed to embed the tray 
> icons, using a draft of the XEMBED protocol.
> 
> 
> Let me make a proposal which is a bit different from the various
> current setups.
> 
> 
> Discovery
> ===
> 
> The system tray has to own a manager selection. I would modify
> Gregory's proposal in these ways:
> 
>  - add the screen number to the selection name to 
>    handle multihead

I concur, assuming this is useful. It didn't seem that it would be so I
left that out before.


>  - use the manager selection _only_ for uniqueness 
>    (in the same way XSETTINGS uses it). This avoids 
>    the complicated code needed to convert/provide 
>    selection data, we just need the simple stuff.

More on this below.


> Because the selection owner window is apparently supposed to be
> destroyed when the manager selection is lost, normally the 
> selection owner window will not be the same as any of the 
> user-visible windows.

Right.


> A system tray that fails to get the selection can ask the user 
> if it should exit, or just do nothing, as it sees fit.

Correct. Something that would make the UI better here would be to require
the tray to advertise its name and similar info. Then a tray which would
prompt the user could provide to him better information. The Gtk+ 
clipboard manager I presented in December (to xdg-list) tries to find
a visible name (WM_NAME) for a running clipboard manager to prompt.


> To have multiple system tray applets, the best approach is to have
> them all in one process owning the manager selection - i.e. have one
> system tray app that handles multiple user-visible tray areas.  This
> app would then support a mechanism for moving tray icons between
> areas, for example.

Right. This is what using the same mechanism to provide cross-desktop
panels would do.


> Use of XEMBED
> ===

This can't be required until the XEMBED protocol is published. :-)
As you can see in the sample implementations, it is used between the gtk+
versions.


> Docking
> ===
> 
> According to Owen, he and Matthias agreed that the "recommended" way
> to do docking is to provide the plug ID to the socket, rather than 
> the plug finding the socket. Thus we want to ask the socket to insert 
> the plug.

Right. The proposed version works this way.


> Rather than doing this via the window manager, one suggestion is: the
> application sends a client message to the manager selection owner
> window. This window may not correspond to the window the plug will be
> reparented into (in fact, KDE now uses and GTK will want to use a
> separate socket window for each plug, plus the issue of needing
> to destroy the selection owner when losing the selection).
> 
> Client message is nicer than the manager selection because it avoids
> the sizable amount of code that can be required to implement
> getting/setting selection data in a robust way and is just generally
> easier to deal with.

I think you've misestimated the code here; again, see below.

> Ending embedding
> ===
> 
> The XEMBED spec needs to specify how to un-embed, that mechanism will 
> be used to remove a system tray docklet.

Needs publication. Two simple ways to do this are by withdrawing the window
(as one withdraws a toplevel window) or simply destroying it. Since the
client with the window to be docked will need to handle destruction on
error, destroying shouldn't be a problem.


> There's an unavoidable problem where if the system tray crashes,
> embedded plug windows will get X errors.

If, in the future, save sets can be extended to allow mapping to be
prevented then that will be solved.

> Mapping
> ===
> 
> XEMBED is apparently currently in flux with respect to how mapping
> works, where Owen wanted plugs to be able to map/unmap while remaining
> embedded, and the original spec always maps the plug immediately.
> 
> But anyhow, the way it works is that the system tray is given the
> window ID of the docklet via some mechanism such as the client
> message, and then the XEMBED spec kicks in and specifies the rest of
> it.

See below about client messages. The system tray and associated windows
are very similar functionally to icon windows (i.e., Window icon_window
in the XWMHints structure) The proposed protocol retains that similarity
in that the icon window owner never maps the icon window.


> Class hint on plug
> ===
> 
> Docked windows should set a class hint, this is mostly so that 
> the system tray can remember the position of docked windows by 
> type. For a simple tray, the tray might remember the order in which 
> the docked windows appear. For a more complex case where a single 
> manager selection holder has two user-visible tray areas, 
> it could remember which tray each icon should appear inside.

Ok. I didn't want to specify this kind of detail before since people
seemed confused enough already. :-) If you look in the sample implementation
at the Xlib-only dock, you'll see that it resizes windows to 24px high
while retaining the aspect ratio and then places the windows in order
of increasing width to the right.  This allows for a system clock to
be used in the tray - yes, like Windows, but really because a clock indicates
a status. If the class hint will be set, it may be a good idea to set
normal hints and provide a preferred placement like beginning or end.
(Beginning and end allow for locale-based adjustments.)


> Handling changing system tray
> ===
> 
> When the system tray dies, apps that want to keep providing a 
> docklet will need to watch for a new system tray grabbing the manager
> selection, and provide a new docklet when they see one.

Right. To watch for one, await the MANAGER client message which is required
of selection managers; please, no more time-based polling - be event-driven.


> This is in contrast to the current KDE setup, where the new system 
> tray appears and gets the list of existing docklets, and then 
> reparents them. Instead I'm suggesting that each docklet self-reparent 
> into a system tray if they see one. This avoids having to keep track
> of the list in the window manager.
> 
> The "fallback" mode can also be handled by clients in this way; they
> can choose to fall back by not displaying the tray icon, by displaying
> an error, by displaying a small window, or as appropriate. Nicer than
> displaying tiny little windows all the time.
> 
> 
> So in summary:
> 
>  - manager selection to fix uniqueness problem
>  - simple client message to get the docklet ID 
>    to the system tray
>  - punt all the behavior specification to XEMBED 
>    as soon as we have the docklet ID communicated
>  - clients are responsible for handling 
>    system tray appearing/disappearing
>  - we provide the implementation note that 
>    system tray icons should set a class hint
> 
> I think that covers all the issues, and is very simple to implement.
> Moving KDE to this method I believe would mostly involve deleting
> code; all the KWin and kwinmodule code would go away, and the  . . .

KWin is KDE's window manager by all accounts. I think they still need one
of those. ;-)

> KSystemTray class would be modified to handle the
> appearance/disappearance of system trays and send the client message.
> The applet code would remain the same except for trivial selection
> ownership code (can be copied from XSETTINGS sample implementation for
> example).
> 
> Havoc

Last time I checked the XSETTINGS code, there were some things missing.
(It was a while ago so my memory may be incorrect.) Please check the samples
I've provided. They'd better be complete and if they aren't I'd like to be
informed. (I think I've still not added X error checking.)
The URL again is:

  http://www.phys.lsu.edu/students/merchan/misc/StatusManager.tar.gz


ConvertSelection vs. ClientMessage
----------------------------------

Client here refers to the requestor clients (docklets) and owner
refers to the selection owner (dock or tray)

In the simplest possible method, ConvertSelection is simpler; the one
I've proposed is not the simplest.

The simplest possible method would be to use a target like INSERT_REQUESTOR
which will not use the property but will take the requestor window as the
one to be embedded.

When the standard communication method is used, the window to be docked
need never inquire about the owner window.

Sending the ClientMessage in any case fails to provide notice of error.
If another were used to provide this notice it could lead to an infinite
wait when the error is that the owner has ceased to be; the X server handles
error in that case.

Sending the ClientMessage to the owner window may introduce racing if the
owner changes between when the client gets its id and sends the message.

Sending the ClientMessage to the root window requires processing from every
other client which is watching root.

ConvertSelection allows clients to check that the manager can handle the
docking request through use of the TARGETS target and allows for other
information, such as VERSION, should it be needed.

The manager has to be able to handle the hell that is MULTIPLE anyway so
the side effect target is simple by comparison. Testing the samples
uncovered bugs in Gtk+'s MULTIPLE handling and they were fixed (afaict)
before 2.0 was released.

The client side complexities can be completely hidden from application
developers. The CGDocklet object in the sample does this for Gtk+.
(It's also similar to the existing GNOME API for docklets.)

I proposed that INSERT_PROPERTY be used for two reasons:
 -  It may be desirable to separate the requestor from the window to embed.
    (This can also be done with one of the data fields in a ClientMessage.)
 -  The atom is listed in the ICCCM with a defined purpose. As such, it is
    more likely to be already interned than some other atom and the number
    of atoms on the display may be kept low.

XSETTINGS is a one-to-many protocol and as such using the manager selection
for uniqueness only is prudent. System tray interaction is one-to-one
and so as with cut/copy/paste and drag-and-drop it is better to use
the selection mechanism fully.


The ClientMessage method, while simpler to code, will either create a
potential for races or lead to more overhead. But most importantly,
it does not permit error handling. It also requires the additional
specifcation of a message format.

The ConvertSelection method allows for error handling. Although it is more
complex, those complexities are presented only to the tray writer and the
API implementor.


Shall I produce a DocBook XML write-up of the spec? If so, I'll also update
the example programs; I think I've cleaned up the code some since that
tarball was made and I'll have to do so to add screen-specificity and
classing.  (I can't add XEMBED to the Xlib versions because I don't have
the spec.)

FYI - the Gtk+ versions (gdock and gtk-sample) should also be useful for
checking focus passing et al. I already passed it along to Bill Haneman
of Sun Accessibilty and he asked to pass it to whom they have working on
GNOME's panel. Running gdock and a few copies of gtk-sample is similar to
running a panel with a few applets. (gtk-sample makes a button which is not
something you'd want in the tray, but shows that it can be done.) A recent
build against Gtk+ 2.0.0 shows some focus indication problems, but that may
be my code.


Cheers,
Gregory Merchan


P.S. - It would be good to have a common colloqial description of the
       user-visible parts. "System Tray" is good for the tray, especially
       since it is what KDE (which uses it more than GNOME) calls it and
       also because that's what Windows calls it. But what are the things
       in it? "Docklet" sound silly and anything with "window" or "icon"
       seems too technical. Maybe "status indicator"?  I've not checked
       end-user docs, so maybe there's already a name. If there isn't
       a name already, I hope the i18n teams are contacted about it;
       other things seem to have been problematic because in translation
       the names have become ridiculously long or awkward.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]