desktop-notifications.rst 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  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. The most important key in the metadata is the ``p`` key, it controls how the
  27. payload is interpreted. A value of ``title`` means the payload is setting the
  28. title for the notification. A value of ``body`` means it is setting the body,
  29. and so on, see the table below for full details.
  30. The design of the escape code is fundamentally chunked, this is because
  31. different terminal emulators have different limits on how large a single escape
  32. code can be. Chunking is accomplished by the ``i`` and ``d`` keys. The ``i``
  33. key is the *notification id* which can be any string containing the characters
  34. ``[a-zA-Z0-9_-+.]``. The ``d`` key stands for *done* and can only take the
  35. values ``0`` and ``1``. A value of ``0`` means the notification is not yet done
  36. and the terminal emulator should hold off displaying it. A non-zero value means
  37. the notification is done, and should be displayed. You can specify the title or
  38. body multiple times and the terminal emulator will concatenate them, thereby
  39. allowing arbitrarily long text (terminal emulators are free to impose a sensible
  40. limit to avoid Denial-of-Service attacks). The size of the payload must be no
  41. longer than ``2048`` bytes, *before being encoded* or ``4096`` encoded bytes.
  42. Both the ``title`` and ``body`` payloads must be either :ref:`safe_utf8` text ,
  43. or UTF-8 text that is :ref:`base64` encoded, in which case there must be an
  44. ``e=1`` key in the metadata to indicate the payload is :ref:`base64`
  45. encoded. No HTML or other markup in the plain text is allowed. It is strictly
  46. plain text, to be interpreted as such.
  47. Allowing users to filter notifications
  48. -------------------------------------------------------
  49. Well behaved applications should identify themselves to the terminal
  50. by means of two keys ``f`` which is the application name and ``t``
  51. which is the notification type. These are free form keys, they can contain
  52. any values, their purpose is to allow users to easily filter out
  53. notifications they do not want. Both keys must have :ref:`base64`
  54. encoded UTF-8 text as their values. The ``t`` key can be specified multiple
  55. times, as notifications can have more than one type. See the `freedesktop.org
  56. spec
  57. <https://specifications.freedesktop.org/notification-spec/notification-spec-latest.html#categories>`__
  58. for examples of notification types.
  59. .. note::
  60. The application name should generally be set to the filename of the
  61. applications `desktop file
  62. <https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#file-naming>`__
  63. (without the ``.desktop`` part) or the bundle identifier for a macOS
  64. application. While not strictly necessary, this allows the terminal
  65. emulator to deduce an icon for the notification when one is not specified.
  66. .. note::
  67. |kitty| has sophisticated notification filtering and management
  68. capabilities via :opt:`filter_notification`.
  69. Being informed when user activates the notification
  70. -------------------------------------------------------
  71. When the user clicks the notification, a couple of things can happen, the
  72. terminal emulator can focus the window from which the notification came, and/or
  73. it can send back an escape code to the application indicating the notification
  74. was activated. This is controlled by the ``a`` key which takes a comma separated
  75. set of values, ``report`` and ``focus``. The value ``focus`` means focus the
  76. window from which the notification was issued and is the default. ``report``
  77. means send an escape code back to the application. The format of the returned
  78. escape code is::
  79. <OSC> 99 ; i=identifier ; <terminator>
  80. The value of ``identifier`` comes from the ``i`` key in the escape code sent by
  81. the application. If the application sends no identifier, then the terminal
  82. *must* use ``i=0``. Actions can be preceded by a negative sign to turn them
  83. off, so for example if you do not want any action, turn off the default
  84. ``focus`` action with::
  85. a=-focus
  86. Complete specification of all the metadata keys is in the :ref:`table below <keys_in_notificatons_protocol>`.
  87. If a terminal emulator encounters a key in the metadata it does not understand,
  88. the key *must* be ignored, to allow for future extensibility of this escape
  89. code. Similarly if values for known keys are unknown, the terminal emulator
  90. *should* either ignore the entire escape code or perform a best guess effort to
  91. display it based on what it does understand.
  92. Being informed when a notification is closed
  93. ------------------------------------------------
  94. .. versionadded:: 0.36.0
  95. Notifications of close events were added in kitty version 0.36.0
  96. If you wish to be informed when a notification is closed, you can specify
  97. ``c=1`` when sending the notification. For example::
  98. <OSC> 99 ; i=mynotification : c=1 ; hello world <terminator>
  99. Then, the terminal will send the following
  100. escape code to inform when the notification is closed::
  101. <OSC> 99 ; i=mynotification : p=close ; <terminator>
  102. If no notification id was specified ``i=0`` will be used.
  103. If ``a=report`` is specified and the notification is activated/clicked on
  104. then both the activation report and close notification are sent. If the notification
  105. is updated then the close event is not sent unless the updated notification
  106. also requests a close notification.
  107. Note that on some platforms, such as macOS, the OS does not inform applications
  108. when notifications are closed, on such platforms, terminals reply with::
  109. <OSC> 99 ; i=mynotification : p=close ; untracked <terminator>
  110. This means that the terminal has no way of knowing when the notification is
  111. closed. Instead, applications can poll the terminal to determine which
  112. notifications are still alive (not closed), with::
  113. <OSC> 99 ; i=myid : p=alive ; <terminator>
  114. The terminal will reply with::
  115. <OSC> 99 ; i=myid : p=alive ; id1,id2,id3 <terminator>
  116. Here, ``myid`` is present for multiplexer support. The response from the terminal
  117. contains a comma separated list of ids that are still alive.
  118. Updating or closing an existing notification
  119. ----------------------------------------------
  120. .. versionadded:: 0.36.0
  121. The ability to update and close a previous notification was added in kitty 0.36.0
  122. To update a previous notification simply send a new notification with the same
  123. *notification id* (``i`` key) as the one you want to update. If the original
  124. notification is still displayed it will be replaced, otherwise a new
  125. notification is displayed. This can be used, for example, to show progress of
  126. an operation. Note that how smoothly the existing notification is replaced
  127. depends on the underlying OS, for example, on Linux the replacement is usually flicker
  128. free, on macOS it isn't, because of Apple's design choices.
  129. To close a previous notification, send::
  130. <OSC> i=<notification id> : p=close ; <terminator>
  131. This will close a previous notification with the specified id. If no such
  132. notification exists (perhaps because it was already closed or it was activated)
  133. then the request is ignored.
  134. Automatically expiring notifications
  135. -------------------------------------
  136. A notification can be marked as expiring (being closed) automatically after
  137. a specified number of milliseconds using the ``w`` key. The default if
  138. unspecified is ``-1`` which means to use whatever expiry policy the OS has for
  139. notifications. A value of ``0`` means the notification should never expire.
  140. Values greater than zero specify the number of milliseconds after which the
  141. notification should be auto-closed. Note that the value of ``0``
  142. is best effort, some platforms honor it and some do not. Positive values
  143. are robust, since they can be implemented by the terminal emulator itself,
  144. by manually closing the notification after the expiry time. The notification
  145. could still be closed before the expiry time by user interaction or OS policy,
  146. but it is guaranteed to be closed once the expiry time has passed.
  147. .. _notifications_query:
  148. Querying for support
  149. -------------------------
  150. .. versionadded:: 0.36.0
  151. The ability to query for support was added in kitty 0.36.0
  152. An application can query the terminal emulator for support of this protocol, by
  153. sending the following escape code::
  154. <OSC> 99 ; i=<some identifier> : p=? ; <terminator>
  155. A conforming terminal must respond with an escape code of the form::
  156. <OSC> 99 ; i=<some identifier> : p=? ; key=value : key=value <terminator>
  157. The identifier is present to support terminal multiplexers, so that they know
  158. which window to redirect the query response too.
  159. Here, the ``key=value`` parts specify details about what the terminal
  160. implementation supports. Currently, the following keys are defined:
  161. ======= ================================================================================
  162. Key Value
  163. ======= ================================================================================
  164. ``a`` Comma separated list of actions from the ``a`` key that the terminal
  165. implements. If no actions are supported, the ``a`` key must be absent from the
  166. query response.
  167. ``c`` ``c=1`` if the terminal supports close events, otherwise the ``c``
  168. must be omitted.
  169. ``o`` Comma separated list of occassions from the ``o`` key that the
  170. terminal implements. If no occasions are supported, the value
  171. ``o=always`` must be sent in the query response.
  172. ``p`` Comma spearated list of supported payload types (i.e. values of the
  173. ``p`` key that the terminal implements). These must contain at least
  174. ``title`` and ``body``.
  175. ``u`` Comma separated list of urgency values that the terminal implements.
  176. If urgency is not supported, the ``u`` key must be absent from the
  177. query response.
  178. ``w`` ``w=1`` if the terminal supports auto expiring of notifications.
  179. ======= ================================================================================
  180. In the future, if this protocol expands, more keys might be added. Clients must
  181. ignore keys they do not understand in the query response.
  182. To check if a terminal emulator supports this notifications protocol the best way is to
  183. send the above *query action* followed by a request for the `primary device
  184. attributes <https://vt100.net/docs/vt510-rm/DA1.html>`_. If you get back an
  185. answer for the device attributes without getting back an answer for the *query
  186. action* the terminal emulator does not support this notifications protocol.
  187. .. _keys_in_notificatons_protocol:
  188. Specification of all keys used in the protocol
  189. --------------------------------------------------
  190. ======= ==================== ========== =================
  191. Key Value Default Description
  192. ======= ==================== ========== =================
  193. ``a`` Comma separated list ``focus`` What action to perform when the
  194. of ``report``, notification is clicked
  195. ``focus``, with
  196. optional leading
  197. ``-``
  198. ``c`` ``0`` or ``1`` ``0`` When non-zero an escape code is sent to the application when the notification is closed.
  199. ``d`` ``0`` or ``1`` ``1`` Indicates if the notification is
  200. complete or not. A non-zero value
  201. means it is complete.
  202. ``e`` ``0`` or ``1`` ``0`` If set to ``1`` means the payload is :ref:`base64` encoded UTF-8,
  203. otherwise it is plain UTF-8 text with no C0 control codes in it
  204. ``f`` :ref:`base64` ``unset`` The name of the application sending the notification. Can be used to filter out notifications.
  205. encoded UTF-8
  206. application name
  207. ``i`` ``[a-zA-Z0-9-_+.]`` ``0`` Identifier for the notification. Make these globally unqiue,
  208. like an UUID, so that terminal multiplexers can
  209. direct responses to the correct window.
  210. ``o`` One of ``always``, ``always`` When to honor the notification request. ``unfocused`` means when the window
  211. ``unfocused`` or the notification is sent on does not have keyboard focus. ``invisible``
  212. ``invisible`` means the window both is unfocused
  213. and not visible to the user, for example, because it is in an inactive tab or
  214. its OS window is not currently active.
  215. ``always`` is the default and always honors the request.
  216. ``p`` One of ``title``, ``title`` Whether the payload is the notification title or body or query. If a
  217. ``body``, notification has no title, the body will be used as title. Terminal
  218. ``close``, emulators should ignore payloads of unknown type to allow for future
  219. ``?``, ``alive`` expansion of this protocol.
  220. ``t`` :ref:`base64` ``unset`` The type of the notification. Can be used to filter out notifications.
  221. encoded UTF-8
  222. notification type
  223. ``u`` ``0, 1 or 2`` ``unset`` The *urgency* of the notification. ``0`` is low, ``1`` is normal and ``2`` is critical.
  224. If not specified normal is used.
  225. ``w`` ``>=-1`` ``-1`` The number of milliseconds to auto-close the notification after.
  226. ======= ==================== ========== =================
  227. .. versionadded:: 0.35.0
  228. Support for the ``u`` key to specify urgency
  229. .. versionadded:: 0.31.0
  230. Support for the ``o`` key to prevent notifications from focused windows
  231. .. note::
  232. |kitty| also supports the `legacy OSC 9 protocol developed by iTerm2
  233. <https://iterm2.com/documentation-escape-codes.html>`__ for desktop
  234. notifications.
  235. .. _base64:
  236. Base64
  237. ---------------
  238. The base64 encoding used in the this specification is the one defined in
  239. :rfc:`4648`. When a base64 payload is chunked, either the chunking should be
  240. done before encoding or after. When the chunking is done before encoding, no
  241. more than 2048 bytes of data should be encoded per chunk and the encoded data
  242. **must** include the base64 padding bytes, if any. When the chunking is done
  243. after encoding, each encoded chunk must be no more than 4096 bytes in size.
  244. There may or may not be padding bytes at the end of the last chunk, terminals
  245. must handle either case.
  246. .. _safe_utf8:
  247. Escape code safe UTF-8
  248. --------------------------
  249. This must be valid UTF-8 as per the spec in :rfc:`3629`. In addition, in order
  250. to make it safe for transmission embedded inside an escape code, it must
  251. contain none of the C0 and C1 control characters, that is, the unicode
  252. characters: U+0000 (NUL) - U+1F (Unit separator), U+7F (DEL) and U+80 (PAD) - U+9F
  253. (APC). Note that in particular, this means that no newlines, carriage returns,
  254. tabs, etc. are allowed.