desktop-notifications.rst 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  1. .. _desktop_notifications:
  2. Desktop notifications
  3. =======================
  4. |kitty| implements an extensible escape code (OSC 99) to show desktop
  5. notifications. It is easy to use from shell scripts and fully extensible to show
  6. title and body. Clicking on the notification can optionally focus the window it
  7. came from, and/or send an escape code back to the application running in that
  8. window.
  9. The design of the escape code is partially based on the discussion in the
  10. defunct `terminal-wg <https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/13>`__
  11. The escape code has the form::
  12. <OSC> 99 ; metadata ; payload <terminator>
  13. Here ``<OSC>`` is :code:`<ESC>]` and ``<terminator>`` is
  14. :code:`<ESC><backslash>`. The ``metadata`` is a section of colon separated
  15. :code:`key=value` pairs. Every key must be a single character from the set
  16. :code:`a-zA-Z` and every value must be a word consisting of characters from
  17. the set :code:`a-zA-Z0-9-_/\+.,(){}[]*&^%$#@!`~`. The payload must be
  18. interpreted based on the metadata section. The two semi-colons *must* always be
  19. present even when no metadata is present.
  20. Before going into details, lets see how one can display a simple, single line
  21. notification from a shell script::
  22. printf '\x1b]99;;Hello world\x1b\\'
  23. To show a message with a title and a body::
  24. printf '\x1b]99;i=1:d=0;Hello world\x1b\\'
  25. printf '\x1b]99;i=1:p=body;This is cool\x1b\\'
  26. .. tip::
  27. |kitty| also comes with its own :doc:`statically compiled command line tool </kittens/notify>` to easily display
  28. notifications, with all their advanced features. For example:
  29. .. code-block:: sh
  30. kitten notify "Hello world" A good day to you
  31. The most important key in the metadata is the ``p`` key, it controls how the
  32. payload is interpreted. A value of ``title`` means the payload is setting the
  33. title for the notification. A value of ``body`` means it is setting the body,
  34. and so on, see the table below for full details.
  35. The design of the escape code is fundamentally chunked, this is because
  36. different terminal emulators have different limits on how large a single escape
  37. code can be. Chunking is accomplished by the ``i`` and ``d`` keys. The ``i``
  38. key is the *notification id* which is an :ref:`identifier`.
  39. The ``d`` key stands for *done* and can only take the
  40. values ``0`` and ``1``. A value of ``0`` means the notification is not yet done
  41. and the terminal emulator should hold off displaying it. A non-zero value means
  42. the notification is done, and should be displayed. You can specify the title or
  43. body multiple times and the terminal emulator will concatenate them, thereby
  44. allowing arbitrarily long text (terminal emulators are free to impose a sensible
  45. limit to avoid Denial-of-Service attacks). The size of the payload must be no
  46. longer than ``2048`` bytes, *before being encoded* or ``4096`` encoded bytes.
  47. Both the ``title`` and ``body`` payloads must be either :ref:`safe_utf8` text
  48. or UTF-8 text that is :ref:`base64` encoded, in which case there must be an
  49. ``e=1`` key in the metadata to indicate the payload is :ref:`base64`
  50. encoded. No HTML or other markup in the plain text is allowed. It is strictly
  51. plain text, to be interpreted as such.
  52. Allowing users to filter notifications
  53. -------------------------------------------------------
  54. .. versionadded:: 0.36.0
  55. Specifying application name and notification type
  56. Well behaved applications should identify themselves to the terminal
  57. by means of two keys ``f`` which is the application name and ``t``
  58. which is the notification type. These are free form keys, they can contain
  59. any values, their purpose is to allow users to easily filter out
  60. notifications they do not want. Both keys must have :ref:`base64`
  61. encoded UTF-8 text as their values. The ``t`` key can be specified multiple
  62. times, as notifications can have more than one type. See the `freedesktop.org
  63. spec
  64. <https://specifications.freedesktop.org/notification-spec/notification-spec-latest.html#categories>`__
  65. for examples of notification types.
  66. .. note::
  67. The application name should generally be set to the filename of the
  68. applications `desktop file
  69. <https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#file-naming>`__
  70. (without the ``.desktop`` part) or the bundle identifier for a macOS
  71. application. While not strictly necessary, this allows the terminal
  72. emulator to deduce an icon for the notification when one is not specified.
  73. .. tip::
  74. |kitty| has sophisticated notification filtering and management
  75. capabilities via :opt:`filter_notification`.
  76. Being informed when user activates the notification
  77. -------------------------------------------------------
  78. When the user clicks the notification, a couple of things can happen, the
  79. terminal emulator can focus the window from which the notification came, and/or
  80. it can send back an escape code to the application indicating the notification
  81. was activated. This is controlled by the ``a`` key which takes a comma separated
  82. set of values, ``report`` and ``focus``. The value ``focus`` means focus the
  83. window from which the notification was issued and is the default. ``report``
  84. means send an escape code back to the application. The format of the returned
  85. escape code is::
  86. <OSC> 99 ; i=identifier ; <terminator>
  87. The value of ``identifier`` comes from the ``i`` key in the escape code sent by
  88. the application. If the application sends no identifier, then the terminal
  89. *must* use ``i=0``. (Ideally ``i`` should have been left out from the response,
  90. but for backwards compatibility ``i=0`` is used). Actions can be preceded by a
  91. negative sign to turn them off, so for example if you do not want any action,
  92. turn off the default ``focus`` action with::
  93. a=-focus
  94. Complete specification of all the metadata keys is in the :ref:`table below <keys_in_notificatons_protocol>`.
  95. If a terminal emulator encounters a key in the metadata it does not understand,
  96. the key *must* be ignored, to allow for future extensibility of this escape
  97. code. Similarly if values for known keys are unknown, the terminal emulator
  98. *should* either ignore the entire escape code or perform a best guess effort to
  99. display it based on what it does understand.
  100. Being informed when a notification is closed
  101. ------------------------------------------------
  102. .. versionadded:: 0.36.0
  103. Notifications of close events
  104. If you wish to be informed when a notification is closed, you can specify
  105. ``c=1`` when sending the notification. For example::
  106. <OSC> 99 ; i=mynotification : c=1 ; hello world <terminator>
  107. Then, the terminal will send the following
  108. escape code to inform when the notification is closed::
  109. <OSC> 99 ; i=mynotification : p=close ; <terminator>
  110. If no notification id was specified ``i=0`` will be used in the response
  111. If ``a=report`` is specified and the notification is activated/clicked on
  112. then both the activation report and close notification are sent. If the notification
  113. is updated then the close event is not sent unless the updated notification
  114. also requests a close notification.
  115. Note that on some platforms, such as macOS, the OS does not inform applications
  116. when notifications are closed, on such platforms, terminals reply with::
  117. <OSC> 99 ; i=mynotification : p=close ; untracked <terminator>
  118. This means that the terminal has no way of knowing when the notification is
  119. closed. Instead, applications can poll the terminal to determine which
  120. notifications are still alive (not closed), with::
  121. <OSC> 99 ; i=myid : p=alive ; <terminator>
  122. The terminal will reply with::
  123. <OSC> 99 ; i=myid : p=alive ; id1,id2,id3 <terminator>
  124. Here, ``myid`` is present for multiplexer support. The response from the terminal
  125. contains a comma separated list of ids that are still alive.
  126. Updating or closing an existing notification
  127. ----------------------------------------------
  128. .. versionadded:: 0.36.0
  129. The ability to update and close a previous notification
  130. To update a previous notification simply send a new notification with the same
  131. *notification id* (``i`` key) as the one you want to update. If the original
  132. notification is still displayed it will be replaced, otherwise a new
  133. notification is displayed. This can be used, for example, to show progress of
  134. an operation. How smoothly the existing notification is replaced
  135. depends on the underlying OS, for example, on Linux the replacement is usually flicker
  136. free, on macOS it isn't, because of Apple's design choices.
  137. Note that if no ``i`` key is specified, no updating must take place, even if
  138. there is a previous notification without an identifier. The terminal must
  139. treat these as being two unique *unidentified* notifications.
  140. To close a previous notification, send::
  141. <OSC> i=<notification id> : p=close ; <terminator>
  142. This will close a previous notification with the specified id. If no such
  143. notification exists (perhaps because it was already closed or it was activated)
  144. then the request is ignored. If no ``i`` key is specified, this must be a no-op.
  145. Automatically expiring notifications
  146. -------------------------------------
  147. A notification can be marked as expiring (being closed) automatically after
  148. a specified number of milliseconds using the ``w`` key. The default if
  149. unspecified is ``-1`` which means to use whatever expiry policy the OS has for
  150. notifications. A value of ``0`` means the notification should never expire.
  151. Values greater than zero specify the number of milliseconds after which the
  152. notification should be auto-closed. Note that the value of ``0``
  153. is best effort, some platforms honor it and some do not. Positive values
  154. are robust, since they can be implemented by the terminal emulator itself,
  155. by manually closing the notification after the expiry time. The notification
  156. could still be closed before the expiry time by user interaction or OS policy,
  157. but it is guaranteed to be closed once the expiry time has passed.
  158. Adding icons to notifications
  159. --------------------------------
  160. .. versionadded:: 0.36.0
  161. Custom icons in notifications
  162. Applications can specify a custom icon to be displayed with a notification.
  163. This can be the application's logo or a symbol such as error or warning
  164. symbols. The simplest way to specify an icon is by *name*, using the ``n``
  165. key. The value of this key is :ref:`base64` encoded UTF-8 text. Names
  166. can be either application names, or symbol names. The terminal emulator
  167. will try to resolve the name based on icons and applications available
  168. on the computer it is running on. The following list of well defined names
  169. must be supported by any terminal emulator implementing this spec.
  170. The ``n`` key can be specified multiple times, the terminal will go through
  171. the list in order and use the first icon that it finds available on the
  172. system.
  173. .. table:: Universally available icon names
  174. ======================== ==============================================
  175. Name Description
  176. ======================== ==============================================
  177. ``error`` An error symbol
  178. ``warn``, ``warning`` A warning symbol
  179. ``info`` A symbol denoting an informational message
  180. ``question`` A symbol denoting asking the user a question
  181. ``help`` A symbol denoting a help message
  182. ``file-manager`` A symbol denoting a generic file manager application
  183. ``system-monitor`` A symbol denoting a generic system monitoring/information application
  184. ``text-editor`` A symbol denoting a generic text editor application
  185. ======================== ==============================================
  186. If an icon name is an application name it should be an application identifier,
  187. such as the filename of the application's :file:`.desktop` file on Linux or its
  188. bundle identifier on macOS. For example if the cross-platform application
  189. FooBar has a desktop file named: :file:`foo-bar.desktop` and a bundle
  190. identifier of ``net.foo-bar-website.foobar`` then it should use the icon names
  191. ``net.foo-bar-website.foobar`` *and* ``foo-bar`` so that terminals running on
  192. both platforms can find the application icon.
  193. If no icon is specified, but the ``f`` key (application name) is specified, the
  194. terminal emulator should use the value of the ``f`` key to try to find a
  195. suitable icon.
  196. Adding icons by transmitting icon data
  197. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  198. This can be done by using the ``p=icon`` key. Then, the payload is the icon
  199. image in any of the ``PNG``, ``JPEG`` or ``GIF`` image formats. It is recommended
  200. to use an image size of ``256x256`` for icons. Since icons are binary data,
  201. they must be transmitted encoded, with ``e=1``.
  202. When both an icon name and an image are specified, the terminal emulator must
  203. first try to find a locally available icon matching the name and only if one
  204. is not found, fallback to the provided image. This is so that users are
  205. presented with icons from their current icon theme, where possible.
  206. Transmitted icon data can be cached using the ``g`` key. The value of the ``g``
  207. key must be a random globally unique UUID like :ref:`identifier`. Then, the
  208. terminal emulator will cache the transmitted data using that key. The cache
  209. should exist for as long as the terminal emulator remains running. Thus, in
  210. future notifications, the application can simply send the ``g`` key to display
  211. a previously cached icon image with needing to re-transmit the actual data with
  212. ``p=icon``. The ``g`` key refers only to the icon data, multiple different
  213. notifications with different icon or application names can use the same ``g``
  214. key to refer to the same icon. Terminal multiplexers must cache icon data
  215. themselves and refresh it in the underlying terminal implementation when
  216. detaching and then re-attaching. This means that applications once started
  217. need to transmit icon data only once until they are quit.
  218. .. note::
  219. To avoid DoS attacks terminal implementations can impose a reasonable max size
  220. on the icon cache and evict icons in order of last used. Thus theoretically,
  221. a previously cached icon may become unavailable, but given that icons are
  222. small images, practically this is not an issue in all but the most resource
  223. constrained environments, and the failure mode is simply that the icon is not
  224. displayed.
  225. .. note::
  226. How the icon is displayed depends on the underlying OS notifications
  227. implementation. For example, on Linux, typically a single icon is displayed.
  228. On macOS, both the terminal emulator's icon and the specified custom icon
  229. are displayed.
  230. Adding buttons to the notification
  231. ---------------------------------------
  232. Buttons can be added to the notification using the *buttons* payload, with ``p=buttons``.
  233. Buttons are a list of UTF-8 text separated by the Unicode Line Separator
  234. character (U+2028) which is the UTF-8 bytes ``0xe2 0x80 0xa8``. They can be
  235. sent either as :ref:`safe_utf8` or :ref:`base64`. When the user clicks on one
  236. of the buttons, and reporting is enabled with ``a=report``, the terminal will
  237. send an escape code of the form::
  238. <OSC> 99 ; i=identifier ; button_number <terminator>
  239. Here, `button_number` is a number from 1 onwards, where 1 corresponds
  240. to the first button, two to the second and so on. If the user activates the
  241. notification as a whole, and not a specific button, the response, as described
  242. above is::
  243. <OSC> 99 ; i=identifier ; <terminator>
  244. If no identifier was specified when creating the notification, ``i=0`` is used.
  245. The terminal *must not* send a response unless report is requested with
  246. ``a=report``.
  247. .. note::
  248. The appearance of the buttons depends on the underlying OS implementation.
  249. On most Linux systems, the buttons appear as individual buttons on the
  250. notification. On macOS they appear as a drop down menu that is accessible
  251. when hovering the notification. Generally, using more than two or three
  252. buttons is not a good idea.
  253. .. _notifications_query:
  254. Playing a sound with notifications
  255. -----------------------------------------
  256. .. versionadded:: 0.36.0
  257. The ability to control the sound played with notifications
  258. By default, notifications may or may not have a sound associated with them
  259. depending on the policies of the OS notifications service. Sometimes it
  260. might be useful to ensure a notification is not accompanied by a sound.
  261. This can be done by using the ``s`` key which accepts :ref:`base64` encoded
  262. UTF-8 text as its value. The set of known sounds names is in the table below,
  263. any other names are implementation dependent, for instance, on Linux, terminal emulators will
  264. probably support the `standard sound names
  265. <https://specifications.freedesktop.org/sound-naming-spec/latest/#names>`__
  266. .. table:: Standard sound names
  267. ======================== ==============================================
  268. Name Description
  269. ======================== ==============================================
  270. ``system`` The default system sound for a notification, which may be some kind of beep or just silence
  271. ``silent`` No sound must accompany the notification
  272. ``error`` A sound associated with error messages
  273. ``warn``, ``warning`` A sound associated with warning messages
  274. ``info`` A sound associated with information messages
  275. ``question`` A sound associated with questions
  276. ======================== ==============================================
  277. Support for sound names can be queried as described below.
  278. Querying for support
  279. -------------------------
  280. .. versionadded:: 0.36.0
  281. The ability to query for support
  282. An application can query the terminal emulator for support of this protocol, by
  283. sending the following escape code::
  284. <OSC> 99 ; i=<some identifier> : p=? ; <terminator>
  285. A conforming terminal must respond with an escape code of the form::
  286. <OSC> 99 ; i=<some identifier> : p=? ; key=value : key=value <terminator>
  287. The identifier is present to support terminal multiplexers, so that they know
  288. which window to redirect the query response too.
  289. Here, the ``key=value`` parts specify details about what the terminal
  290. implementation supports. Currently, the following keys are defined:
  291. ======= ================================================================================
  292. Key Value
  293. ======= ================================================================================
  294. ``a`` Comma separated list of actions from the ``a`` key that the terminal
  295. implements. If no actions are supported, the ``a`` key must be absent from the
  296. query response.
  297. ``c`` ``c=1`` if the terminal supports close events, otherwise the ``c``
  298. must be omitted.
  299. ``o`` Comma separated list of occassions from the ``o`` key that the
  300. terminal implements. If no occasions are supported, the value
  301. ``o=always`` must be sent in the query response.
  302. ``p`` Comma spearated list of supported payload types (i.e. values of the
  303. ``p`` key that the terminal implements). These must contain at least
  304. ``title``.
  305. ``s`` Comma separated list of sound names from the table of standard sound names above.
  306. Terminals will report the list of standard sound names they support.
  307. Terminals *should* support atleast ``system`` and ``silent``.
  308. ``u`` Comma separated list of urgency values that the terminal implements.
  309. If urgency is not supported, the ``u`` key must be absent from the
  310. query response.
  311. ``w`` ``w=1`` if the terminal supports auto expiring of notifications.
  312. ======= ================================================================================
  313. In the future, if this protocol expands, more keys might be added. Clients must
  314. ignore keys they do not understand in the query response.
  315. To check if a terminal emulator supports this notifications protocol the best way is to
  316. send the above *query action* followed by a request for the `primary device
  317. attributes <https://vt100.net/docs/vt510-rm/DA1.html>`_. If you get back an
  318. answer for the device attributes without getting back an answer for the *query
  319. action* the terminal emulator does not support this notifications protocol.
  320. .. _keys_in_notificatons_protocol:
  321. Specification of all keys used in the protocol
  322. --------------------------------------------------
  323. ======= ==================== ========== =================
  324. Key Value Default Description
  325. ======= ==================== ========== =================
  326. ``a`` Comma separated list ``focus`` What action to perform when the
  327. of ``report``, notification is clicked
  328. ``focus``, with
  329. optional leading
  330. ``-``
  331. ``c`` ``0`` or ``1`` ``0`` When non-zero an escape code is sent to the application when the notification is closed.
  332. ``d`` ``0`` or ``1`` ``1`` Indicates if the notification is
  333. complete or not. A non-zero value
  334. means it is complete.
  335. ``e`` ``0`` or ``1`` ``0`` If set to ``1`` means the payload is :ref:`base64` encoded UTF-8,
  336. otherwise it is plain UTF-8 text with no C0 control codes in it
  337. ``f`` :ref:`base64` ``unset`` The name of the application sending the notification. Can be used to filter out notifications.
  338. encoded UTF-8
  339. application name
  340. ``g`` :ref:`identifier` ``unset`` Identifier for icon data. Make these globally unqiue,
  341. like an UUID.
  342. ``i`` :ref:`identifier` ``unset`` Identifier for the notification. Make these globally unqiue,
  343. like an UUID, so that terminal multiplexers can
  344. direct responses to the correct window. Note that for backwards
  345. compatibility reasons i=0 is special and should not be used.
  346. ``n`` :ref:`base64` ``unset`` Icon name. Can be specified multiple times.
  347. encoded UTF-8
  348. application name
  349. ``o`` One of ``always``, ``always`` When to honor the notification request. ``unfocused`` means when the window
  350. ``unfocused`` or the notification is sent on does not have keyboard focus. ``invisible``
  351. ``invisible`` means the window both is unfocused
  352. and not visible to the user, for example, because it is in an inactive tab or
  353. its OS window is not currently active.
  354. ``always`` is the default and always honors the request.
  355. ``p`` One of ``title``, ``title`` Type of the payload. If a notification has no title, the body will be used as title.
  356. ``body``, A notification with not title and no body is ignored. Terminal
  357. ``close``, emulators should ignore payloads of unknown type to allow for future
  358. ``icon``, expansion of this protocol.
  359. ``?``, ``alive``,
  360. ``buttons``
  361. ``s`` :ref:`base64` ``system`` The sound name to play with the notification. ``silent`` means no sound.
  362. encoded sound ``system`` means to play the default sound, if any, of the platform notification service.
  363. name Other names are implementation dependent.
  364. ``t`` :ref:`base64` ``unset`` The type of the notification. Used to filter out notifications. Can be specified multiple times.
  365. encoded UTF-8
  366. notification type
  367. ``u`` ``0, 1 or 2`` ``unset`` The *urgency* of the notification. ``0`` is low, ``1`` is normal and ``2`` is critical.
  368. If not specified normal is used.
  369. ``w`` ``>=-1`` ``-1`` The number of milliseconds to auto-close the notification after.
  370. ======= ==================== ========== =================
  371. .. versionadded:: 0.35.0
  372. Support for the ``u`` key to specify urgency
  373. .. versionadded:: 0.31.0
  374. Support for the ``o`` key to prevent notifications from focused windows
  375. .. note::
  376. |kitty| also supports the `legacy OSC 9 protocol developed by iTerm2
  377. <https://iterm2.com/documentation-escape-codes.html>`__ for desktop
  378. notifications.
  379. .. _base64:
  380. Base64
  381. ---------------
  382. The base64 encoding used in the this specification is the one defined in
  383. :rfc:`4648`. When a base64 payload is chunked, either the chunking should be
  384. done before encoding or after. When the chunking is done before encoding, no
  385. more than 2048 bytes of data should be encoded per chunk and the encoded data
  386. **must** include the base64 padding bytes, if any. When the chunking is done
  387. after encoding, each encoded chunk must be no more than 4096 bytes in size.
  388. There may or may not be padding bytes at the end of the last chunk, terminals
  389. must handle either case.
  390. .. _safe_utf8:
  391. Escape code safe UTF-8
  392. --------------------------
  393. This must be valid UTF-8 as per the spec in :rfc:`3629`. In addition, in order
  394. to make it safe for transmission embedded inside an escape code, it must
  395. contain none of the C0 and C1 control characters, that is, the unicode
  396. characters: U+0000 (NUL) - U+1F (Unit separator), U+7F (DEL) and U+80 (PAD) - U+9F
  397. (APC). Note that in particular, this means that no newlines, carriage returns,
  398. tabs, etc. are allowed.
  399. .. _identifier:
  400. Identifier
  401. ----------------
  402. Any string consisting solely of characters from the set ``[a-zA-Z0-9_-+.]``,
  403. that is, the letters ``a-z``, ``A-Z``, the underscore, the hyphen, the plus
  404. sign and the period. Applications should make these globally unique, like a
  405. UUID for maximum robustness.
  406. .. important::
  407. Terminals **must** sanitize ids received from client programs before sending
  408. them back in responses, to mitigate input injection based attacks. That is, they must
  409. either reject ids containing characters not from the above set, or remove
  410. bad characters when reading ids sent to them.