- From: Havoc Pennington <hp redhat com>
- To: xdg-list freedesktop org, wm-spec-list gnome org
- Subject: launch notification
- Date: 24 Oct 2001 22:52:47 -0400
I typed this in a couple months ago; I was going to try implementing
it before posting, but since that doesn't seem to be happening
quickly, I'm posting it before I lose it in the depths of my home
directory. ;-) I have some comments/revisions of my own in mind
already, but no time to deal with it right now.
Informal draft writeup of how to handle application launching in the X
environment. Needs conversion into an actual spec.
Executive summary of end-user benefits
- allow busy cursor launch feedback mode
- allow launch feedback mode where you put an animation
over the icon they clicked to cause the launch
- allow cancellation of a launch-in-progress
- allow WindowMaker-style (single-instance) launch buttons to work nicely
- allow task lists to display the currently-in-progress launches
- allow choice of which program displays the launch feedback
- avoid ending up with two conflicting launch feedbacks at once (e.g.
two different animations on the launcher icon)
- allow launch feedback for launches inside a single process
(for example opening a file manager window by clicking
on a directory icon)
- generic spec works across desktops
- as close to 100% reliable operation as possible.
"If everything implements the spec properly, then everything
will work properly."
- have a single program provide launch indication for the whole
desktop, regardless of who is launching it; this provides
- easy to support correctly in applications, so we can
add native support to all toolkits and legacy apps
(complexity burden placed on desktop components rather
than individual apps)
- ensure we have a path away from LD_PRELOAD hacks and such - i.e., a
way to avoid such hacks for apps that support the protocol
natively, so that once most apps support it natively, we can drop
- allow apps to control the indicator; for example, an app may want
to map a window of some kind without removing the indicator,
or remove the indicator before mapping a window.
- allow the window manager to keep track of when apps are launched
and which windows belong to a given launch attempt - this allows
the WM to for example put an app on the workspace which was active
at launch time
- allow the WM to be notified when an app has reached its final
start-up state. For example, if a word processor launches a splash
screen, then the main window, then both the splash screen and the
main window could be placed on the workspace which was active at
launch-time. However, this needs to happen without forcing all
windows from that app to always be on the launch workspace. So the WM
needs to know when an app's windows should no longer be treated in
a special way.
- allow a similar feedback mechanism and WM special-casing for
opening new windows within an application. For example, when
opening a new word processor window, it might be nice to
keep it on the workspace where "New" was selected from the menu.
(Of course it would be nicer if opening a new window were fast,
but for some apps that may not always be true. Consider
opening a large document, for example.)
- allow indication that is sensitive to where and how the
launching occurred; for example a sparkle at the launch point.
This should work even if the launch point is inside a
- allow apps to open new windows, or just plain start up, without
progress indication. This would normally be done for programs that
users may not think of as apps; say a panel applet. The main point
here is that toolkits should be able to provide API to control the
launch feedback, and the spec has to allow toolkits to implement
- allow the user to cancel a launch-in-progress, for example if the
progress indicator is a dialog, they could press the Stop button;
if it's a busy cursor, the window manager might provide a keybinding.
Proposed solution overview
There is a single "launch manager" active per-screen at any given
time. The launch manager may be the window manager, or it may be a
separate process. A launch manager displays the primary user feedback
for a "launch sequence." A launch sequence typically begins when the
user asks to launch an application or open a new document, and ends
when the app or document finishes loading.
Each launch sequence is identified by a unique ID. The launching
program initially notifies the launch manager that a launch ID exists
and gives the launch manager pertinent information about how to
display progress. Subsequent information about the status of the
launch is provided to the launch manager as appropriate, by the
launching program and also the launched application.
The launch manager owns a manager selection (see ICCCM 2.8) on each
screen that it manages. The name of the selection is
The launch manager and the window manager may be the same process.
However, window managers that do this are encouraged to have a mode
where they allow a separate process to own the _NET_LAUNCH_MANAGER
selection and handle launch management.
Only one launch manager runs at a time, because the launch manager is
primarily responsible for providing launch feedback. If a given
type of feedback would break down if two applications implemented it
simultaneously, then that type of feedback must be provided
by the launch manager.
For example, only one application can set the mouse cursor; only one
application can display an animation over the launcher icon. On the
other hand, two task lists or task menus could each display a task
button for launches-in-progress.
If a launch manager gives up the _NET_LAUNCH_MANAGER selection, it
should finish managing active launch sequences. The new launch manager
should not try to manage launch sequences that predate it.
_NET_LAUNCH_MANAGER must support the following targets:
The name of the launch manager
A launch sequence is an instance of launching something. For example,
running a program or opening a new window. Each launch sequence
involves a launcher (the program doing the launching) and a launchee
(whatever is being launched).
Launch sequences are identified by a launch sequence ID. The launch
sequence ID is a string, generated as follows:
The elements are:
- name of launcher; no rigorous semantics
- name of launchee; no rigorous semantics; can be same as launcher
- X server timestamp from the event causing the launch (or last event
received by the launcher) - obviously, do not use CurrentTime
- a uniqueness string; launchers should use this to ensure the
launch sequence ID is unique if they launch two or more copies
of the same application at the same time
The launcher/launchee names "namespace" the subsequent fields, and are
intended to be helpful when debugging. The X timestamp makes it very
likely that the launch ID is unique across the X display. The
uniqueness string ensures uniqueness for sequences from a given
It is remotely possible that two launcher process have the same name,
launch the same program, at the same time, and with the same
uniqueness string. Launchers are encouraged to use something other
than a monotonically increasing serial number for the uniqueness
string, as an extra safety net. For example, they might include their
process ID or some random digits.
The launch sequence ID should be a valid UTF-8 string.
The elements of the sequence ID may not contain the '/' separator
character, since that would render the ID unparseable. That said, no
application should rely on parsing the sequence ID; its format is only
specified as a debugging aid, and to ensure that IDs are unique.
An example sequence ID is:
Launch Sequence Window
Each launch sequence has a number of attributes that need to be
communicated between the launcher program, the launch manager, and the
program being launched. The easiest way to share a hash table between
X clients is to use an X window.
Each launch sequence thus has a corresponding X window, created by the
launcher program, where launch sequence properties can be set
and launch-related messages can be sent.
The launch sequence window must be an immediate child of the root
The following property MUST be set on this window before initiating
- _NET_LAUNCH_ID UTF8_STRING
The launch sequence ID
The following properties are optional, but if set must be set before
initiating the launch, and unless otherwise noted should be left
unchanged throughout the launch sequence:
- _NET_LAUNCHER_TYPE CARDINAL/32
An integer indicating the context of the launch:
#define _NET_LAUNCHER_TYPE_OTHER 0
#define _NET_LAUNCHER_TYPE_DOCK_ICON 1
#define _NET_LAUNCHER_TYPE_DESKTOP_ICON 2
#define _NET_LAUNCHER_TYPE_MENU 3
#define _NET_LAUNCHER_TYPE_KEY_SHORTCUT 4
If the property is unset, OTHER should be assumed.
Rationale: the launch manager may choose to special-case some of
these. For example, you can't display an animation over the top of
a menu or key shortcut, but you can over a desktop or dock icon.
- _NET_LAUNCHER_GEOMETRY CARDINAL/32
x, y, width, height geometry of the icon the user
clicked to begin the launch. The coordinates
are relative to _NET_LAUNCH_GEOMETRY_WINDOW if
that property is set, otherwise to the root window.
This property may be updated during the launch sequence,
to reflect e.g. moving the launch icon.
- _NET_LAUNCH_GEOMETRY_WINDOW WINDOW/32
Window that _NET_LAUNCHER_GEOMETRY is relative to.
If this window is not the root window, the launch manager
should track movement of the window around the screen.
That is, if displaying an animation on the launch icon,
if the user moves the window containing the launch icon,
the animation should also move.
- _NET_LAUNCHER_SUPPORTS_CANCEL CARDINAL/32
Contains 1 if the launcher supports cancelling this
launch sequence, 0 if not. If the property is unset,
0 should be assumed. Cancelling a launch sequence
means ending the operation that in progress, for example
killing the application being launched.
- _NET_LAUNCH_TYPE CARDINAL/32
An integer indicating the sort of thing being launched:
#define _NET_LAUNCHER_TYPE_OTHER 0
#define _NET_LAUNCHER_TYPE_APPLICATION 1
#define _NET_LAUNCHER_TYPE_DOCUMENT 2
If unset, OTHER should be assumed. OTHER most likely results in a
suboptimal user interface, so launchers are encouraged to set this
property if one of the standard types makes sense.
Rationale: when displaying launch progress, the launch manager may
need to use this information. For example, it may want to say
"Opening document Foo..." for documents and "Launching Foo..." for
applications, in a progress dialog.
- _NET_LAUNCH_NAME UTF8_STRING
The user-visible name of the launch sequence; normally the name of
the application being launched, or the name of the document being
loaded. _NET_LAUNCH_TYPE aids the launch manager in interpreting
- _NET_LAUNCH_DESKTOP CARDINAL/32
The active workspace from the _NET_CURRENT_DESKTOP property (see
extended window manager hints specification).
Implementation note: to set this hint without races, the launcher
program would have to track _NET_CURRENT_DESKTOP by selecting for
property notifies, and use the most-recently-notified value when
creating the launch sequence window. However, having lots of apps
select for PropertyNotify on the root window is probably bad.
Instead, it seems reasonable to accept the race; users who want to
be sure the app comes up on the right workspace can wait for the
launch feedback indicator to appear before switching workspaces,
if they do that then things will always work.
- _NET_LAUNCH_LEGACY_RESOURCE_CLASS STRING
A class (as for the first part of the WM_CLASS hint).
A name (as for the second part of the WM_CLASS hint).
A window title (as for WM_NAME)
If one or more of these three properties are set, then the launchee
is a legacy X client. If they are set, the following must be known
to the launcher via some reliable mechanism:
- the legacy X client will create at least one new toplevel
- the toplevel managed window it creates will have the
- the legacy X client does not support this specification
If one of these properties is set, then the launch manager is
responsible for completing the launch sequence by setting
_NET_LAUNCH_COMPLETE when the legacy launchee maps a toplevel X
window that matches the given resource class, name, and title. If
multiple properties are set, they must all be matched; that is, if
both a legacy class and a legacy title are given, then the launch
sequence ends only after mapping a window matching both the class
and the title.
The following property may be set at any time by any client:
- _NET_LAUNCH_CANCELLED CARDINAL/32
The value of this property is irrelevant; if the property exists,
the user has asked to cancel the launch. This property may be
set by any X client in response to user input.
If the launcher program set _NET_LAUNCHER_SUPPORTS_CANCEL, then
it should listen for PropertyNotify on this property, and cancel
the launch if a PropertyNotify is received.
If the launcher program did not set _NET_LAUNCHER_SUPPORTS_CANCEL,
it may ignore _NET_LAUNCH_CANCELLED
The launch manager should not end launch feedback when
_NET_LAUNCH_CANCELLED is set; instead, it should wait for the
cancellation to take effect.
The following property may be set by the launchee to indicate that
it's displaying launch progress to the user:
- _NET_LAUNCH_PULSE CARDINAL/32
The value of this property is irrelevant. If set, then the launchee
is making progress on starting up. Launchees are encouraged to
re-set _NET_LAUNCH_PULSE at regular intervals, indicating that
progress continues. This property should be set before showing a
splash screen, for example. See implementation notes for more
The purpose of this property is to allow the launch manager to
feel confident that the application is moving forward, and avoid
e.g. putting up a "the launchee appears to be stopped" dialog
on top of the launchee's splash screen.
The following property should be set by the launchee once it considers
itself fully started up, or by the launcher after cancellation:
- _NET_LAUNCH_COMPLETE CARDINAL/32
The launchee program should set this property on the launch
window when the launch sequence is complete. The launchee should
map all windows that are part of an application's initial
state BEFORE it sets this property. After launching is complete,
window managers will not place newly-mapped windows on the
The launcher program should set this property on the launch
window after cancelling the launch.
Launch feedback should be ended if _NET_LAUNCH_COMPLETE has been
The launcher program must destroy the launch sequence window
after this property is set.
Before initiating a launch, the launcher program should create a
launch sequence window and set its initial properties.
Then, it should send a client message to the root window
window = launch sequence window
message_type = _NET_INITIATE_LAUNCH
format = 32
data.l = timestamp; /* X timestamp of event (mouse click, etc.) causing
* launch, or CurrentTime if unavailable
data.l = 0; /* reserved, always set to 0 */
Launch termination, launch sequence window destruction
If a PropertyNotify for _NET_LAUNCH_COMPLETE is received on the launch
sequence window, then launching is complete. Launching is considered
to have ended at the time in the PropertyNotify event.
The launch sequence window may be destroyed at any time, either on
purpose by the launcher application, or because the launcher
application crashes. Clients monitoring a launch sequence should take
this into account.
- When reading the initial values from the launch sequence window,
a BadWindow error indicates that the window was already destroyed.
In this case, the launch sequence should be ignored. Launch
feedback should only be initiated if all the initial properties
of the launch sequence window are read successfully.
- Once launch feedback has been initiated, a DestroyNotify on the
launch sequence window indicates that the launch sequence is
complete. However, normally a PropertyNotify from
_NET_LAUNCH_COMPLETE will have been received before the window was
destroyed. Because DestroyNotify events have no timestamp, the time
of completion should be taken from the PropertyNotify on
_NET_LAUNCH_COMPLETE. If _NET_LAUNCH_COMPLETE was never set, the
time of completion is unknown.
If _NET_LAUNCH_CANCELLED is set, then the launcher program should
stop launching whatever was being launched, then set
_NET_LAUNCH_COMPLETE, then destroy the launch sequence window.
Communicating from a launcher process to a launchee process
To communicate the launch sequence information from a launcher process
to a launchee process, when possible two environment variables should
Launch sequence ID
Launch sequence window ID in hex format, e.g. "0x1a0000d"
Launchees don't actually need to know their launch sequence ID to
implement this specification, because their only real responsibility
is to set _NET_LAUNCH_COMPLETE on the launch sequence window. However
the launch ID may be useful in debugging or for future extensions.
Mechanisms other than the environment variable may be used in some
cases. Keep in mind that launcher and launchee are allowed to be in
the same process, for example when opening a document from the File
menu in an application.
Desktop entry extensions
[These should be included in the desktop entry spec, not in the
To share information about launchee applications between desktops, the
following fields are supported in .desktop files:
If not present, assumed to be FALSE. If present and TRUE, the
to-be-launched app supports this specification and can be expected
to set _NET_LAUNCH_COMPLETE on the window specified in the
DESKTOP_LAUNCH_WINDOW environment variable.
If present, specifies a class for
_NET_LAUNCH_LEGACY_RESOURCE_CLASS and that property should be
set by the launcher.
If present, specifies a resource name for
_NET_LAUNCH_LEGACY_RESOURCE_NAME and that property should be set
by the launcher.
If present, specifies a title for _NET_LAUNCH_LEGACY_NAME
and that property should be set by the launcher.
FIXME The three LaunchLegacy properties are in UTF-8 encoding in the
.desktop file, but have type STRING in X. What do we do about that?
The LaunchLegacy properties are mutually exclusive with
LaunchFeedbackSupported=1. If a .desktop file claims that launch
feedback is supported, and also gives the legacy fields, then
the legacy fields should be used and the launcher should assume that
launch feedback is not supported.
The launch feedback provided by the launch manager should be something
relatively unobtrusive; examples are changing the cursor, or a small
animation at the launcher icon.
Progress dialogs or splash screens should be provided by the launchee
application, rather than by the launch manager.
The launchee application should complete the launch sequence after it
has its first user-interaction-allowing window onscreen. (That is,
a splash screen should not end the launch sequence, but a dialog or
main window should.)
One possible solution to the "stuck cursor" problem seen with
current launch feedback solutions:
After a timeout, the launch manager might replace the unobtrusive
feedback (cursor, etc.) with a dialog that has a Stop button; when
clicked, the Stop button sets _NET_LAUNCH_CANCELLED if
_NET_LAUNCHER_SUPPORTS_CANCEL, and otherwise simply sets
_NET_LAUNCH_COMPLETE to give up on the whole launch feedback thing.
If a launch manager did something like this, the dialog should be
avoided if _NET_LAUNCH_PULSE has been set on the launch sequence
window recently. _NET_LAUNCH_PULSE indicates that the launchee is
moving forward and perhaps displaying a splash screen already.
Launchers should attempt to detect launchee failures and end the
launch sequence if appropriate; for example, if a launched application
exits with a nonzero exit code, it would be a good idea to set
_NET_LAUNCH_COMPLETE and end launch feedback. The launcher is
responsible for displaying an error dialog to the user in this case.
Launchers should not however end feedback if a launched process exits
normally, because the process may have been a wrapper script, may have
asked an already-open application to create a new window, etc.
Only the launch manager should "time out" a launchee and decide to end
launch feedback; the launcher application should never do this, it
should only end the launch sequence if it has a good reason to believe
the launchee crashed.
Task lists are encouraged to provide a button for each launch
sequence, and support launch cancellation from this button. This
allows users to get rid of the busy cursor if it's stuck.
Alternatively, a task list integrated with the launch manager could
for example pop up the aforementioned dialog-with-stop-button
if you clicked on the button for the launch sequence.
If displaying an animated busy cursor, the launch manager should
"spin" the cursor when _NET_LAUNCH_PULSE is updated. Launchees are
encouraged to update _NET_LAUNCH_PULSE in tune with their own splash
screen progress bar or the like.
] [Thread Prev