FreeDesktop proposed notifications spec ======================================= (c) 2004 Mike Hearn 2004 Christian Hammond ChangeLog: v0.1: * Initial version --------------------------------------------------------------------- OVERVIEW This is a draft standard for a desktop notifications service, through which applications can generate passive popups (sometimes known as "poptarts") to notify the user in an asynchronous manner of events. This specification explicitly does not include other types of notification presentation such as modal message boxes, window manager decorations or window list annotations. Example use cases include: * Presence changes in IM programs: for instance, MSN Messenger on Windows pioneered the use of passive popups to indicate presence changes. * New mail notification * Low disk space/battery warnings BASIC DESIGN In order to ensure that multiple notifications can easily be displayed at once, and to provide a convenient implementation, all notifications are controlled by a single session-scoped service which exposes a DBUS interface. On startup, a conforming implementation should take the "org.freedesktop.Notifications" service on the session bus. This service will be referred to as the "notification server" or just "the server" in this document. It can optionally be activated automatically by the bus process, however this is not required and notification server clients must not assume that it is available. The server should implement the "org.freedesktop.Notifications" interface on an object with the path "/org/freedesktop/Notifications". This is the only interface required by this version of the specification. A notification has the following components: - A summary: This is a single line overview of the notification. For instance "You have mail" or "A friend has come online". It should generally not be longer than 40 characters (FIXME: is 40 sane?). The summary must be encoded using UTF-8. - An optional body: This is a multi-line body of text. Each line is a paragraph, server implementations are free to word wrap them as they see fit. The text may contain simple markup as specified in the MARKUP section below. It must be encoded using UTF-8. If the body is omitted just the summary is displayed. - An optional array of images: See the ICONS/SOUNDS section below. - An optional sound: See the ICONS/SOUNDS section below. - An array of actions. The actions send a request message back to the notification client when invoked. This functionality may not be implemented by the notification server, conforming clients should check if it is available before using it (see the GetCapabilities message in the PROTOCOL section). An implementation is free to ignore any requested by the client. As an example one possible rendering of actions would be as buttons in the notification popup. - An expiration time: the timestamp in seconds since the epoch that the notification should close. If one wishes to have an expiration of 5 seconds from now, they must grab the current timestamp and add 5 seconds to it. If zero, the notification's expiration time is dependent on the notification server's settings, and may vary for the type of notification. The expiration time should be respected by implementations, but this is not required (this is for compatibility with KNotify). Each notification displayed is allocated a unique ID by the server (FIXME: should this be unique within a session, or just unique while the notification is active?). This can be used to hide the notification before the expiration time is reached. It can also be used to atomically replace the notification with another: this allows you to (for instance) modify the contents of a notification while it's on-screen. BACKWARDS COMPATIBILITY Prior art in this area is basically just the KNotify system. This specification strives to be compatible with KNotify, however there is still some semantic mismatch. Clients should try and avoid making assumptions about the presentation and abilities of the notification server: the message content is the most important thing. Clients can check with the server what capabilities are supported using the GetCapabilities message. See the PROTOCOL section. If a client requires a response from a passive popup, it should be coded such that a non-focus-stealing message box can be used instead and the notification server is only used when available. MARKUP Description text may contain markup. The markup is XML-based, and consists of a small subset of HTML along with a few additional tags. The following tags can optionally be supported: - ... - Bold - ... - Italic - ... - Underline - ... - Hyperlink ICONS/SOUNDS A notification can optionally include an array of images and/or a single sound. The array of images specifies frames in an animation, animations always loop. Implementations are free to ignore the image/sound data, and implementations that support images may not support animation. If the image array has more than one element, a "primary frame" can be specified - if not specified it defaults to the first frame. For implementations that support images but not animation (for instance a KNotify bridge), only the primary frame will be used. Each element of the array must have the same type as the first element, mixtures of strings and blobs are not allowed. The element types can be one of the following: * [string] Icon theme name. Any string that does not begin with the / character is assumed to be an icon theme name and is looked up according to the spec. The best size to fit the servers chosen presentation will be used. This is the recommended way of specifying images. * [string] Absolute path. Any string that begins with a / will be used as an absolute file path. Implementations should support at minimum files of type image/png and image/svg. * [binary] A data stream may be embedded in the message. This is assumed to be of type image/png. A sound can be specified, this will be played by the notification server when the notification is displayed. FIXME: elaborate here. PROTOCOL The following messages must be supported by all implementations. * GetCapabilities This message takes no parameters. It returns an array of strings. Each string describes an optional capability implemented by the server. The following values are defined by this spec: "body": Supports body text. Some implementations may only show the summary (for instance, onscreen displays, marquee/scrollers) "markup": Supports markup in the body text. "static-image" : Supports display of exactly 1 frame of any given image array. This value is mutually exclusive with "multi-image", it is a protocol error for the server to specify both. The client may still specify multiple frames even if this cap is missing, however the server is free to ignore them and use only the primary frame. "multi-image": The server will render an animation of all the frames in a given image array. "sound": The server will play the specified sound. Even if this cap is missing, a sound may still be specified however the server is free to ignore it. "actions": The server will provide the specified actions to the user. Even if this cap is missing, actions may still be specified by the client, however the server is free to ignore them. New vendor-specific caps may be specified as long as they start with "x-vendorname", so for instance "x-gnome-foo-cap". Caps may not contain spaces in their names (FIXME: this feels right but is it really necessary?) * Notify This message requires the following parameters in the exact order shown. For some parameters multiple types may be acceptable BYTE urgency: The urgency level: 0 - low urgency 1 - medium (default) 2 - high 3 - critical STRING summary STRING/NIL body: if nil the body is considered omitted. ARRAY images: the array may be empty. STRING/NIL sound: if nil the sound is considered omitted. DICT actions: each dictionary key is the localized name of the action, and each key maps to a UINT32 containing an action code. This code will be reported back to the client if the action is invoked by the user. UINT32/NIL expire time: if nil the notification never times out It returns a UINT32 that will never be reused within a session unless more than MAXINT notifications have been generated (ie an acceptable implementation for this is just an incrementing counter). * CloseNotification This message indicates that the notification should be removed from the users view. It can be used, for instance, if the event the notification pertains to is no longer relevant or to cancel a notification with no expiration. It takes one UINT32 parameter, the ID of the notificaton to cancel. * GetServerInformation This message takes no parameters, and returns the following values: STRING name: the product name of the server STRING vendor: "kde"/"freedesktop.org"/"Microsoft" etc etc STRING version: a version spec of arbitrary format All implementations must emit the following signals: * NotificationClosed A completed notification is one that has timed out, or been dismissed by the user. Has two parameters: * UINT32 id: containing the ID of the notification that was completed. * UINT32 reason: 1 for expires, 2 for being dismissed by the user, 3 for "other". The ID specified in the signal is invalidated *before* the signal is sent and may not be used in any further communications with the server. The following signals MAY be emitted by the server. * ActionInvoked If the server specifies "actions" in its caps array, and actions were specified in the original request, this signal must be emitted if the user invokes a given action (for instance, by clicking a button). ActionInvoked has two parameters: * UINT32 id: The ID of the notification containing the invoked action. * UINT32 action_id: The ID of the action that was invoked, which was specified in the original dictionary. REFERENCE