summaryrefslogtreecommitdiff
path: root/SPECIFICATION
blob: 513f9375e8bb643f104a55b52f2df00d17c07df5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
FreeDesktop proposed notifications spec
=======================================

(c) 2004 Mike Hearn <mike@navi.cx>
    2004 Christian Hammond <chipx86@chipx86.com>

ChangeLog:

v0.1:
  * Initial version
v0.2:
  * Add replaces field to protocol
  
---------------------------------------------------------------------

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". Tip: It
  should generally not be longer than 40 characters though this is not
  a requirement and server implementations should word wrap if
  necessary. 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.
This is unique within the session - while the notification server is
running the ID will not be recycled unless the capacity of a uint32 is
exceeded.

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.

FIXME: is this enough? is it even worth trying to be compatible with
KNotify given how different these systems are? Might just be easier to
implement this protocol in KNotify itself as a separate thing.


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:

- <b>...</b> - Bold
- <i>...</i> - Italic
- <u>...</u> - Underline
- <a href="...">...</a> - 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. If marked up text is sent
            to a server that does not give this cap, the markup will show
            through as regular text so must be stripped clientside.

  "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.
                   
  "multi-image": The server will render an animation of all the frames
                 in a given image array. The client may still specify
                 multiple frames even if this cap and/or static-image
                 is missing, however the server is free to ignore them
                 and use only the primary frame.

  "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

  UINT32 replaces: if non-zero this is the notification ID that
  this notification replaces. The server must atomically (ie with
  no flicker or other visual cues) replace the given notification
  with this one. This allows clients to effectively modify the
  notification while it's active.
  
  BYTE urgency: The urgency level:
        0 - low urgency
	1 - medium
	2 - high
	3 - critical

  Other values should be treated as "medium" in this version of the spec.

  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.
  If non-nil, a UNIX time_t (since the epoch) at which point the notification
  will be automatically closed. If zero, use the default server timeout.
  
  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). The returned UINT32 will never be zero, as this is an invalid
  ID.

* 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. The NotificationClosed signal is emitted by this
  method.

* 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.