detached a4dc00a

docs(readme): popups and tray tooltips

commit
a4dc00aed7cc5039e889bf77dcd43d80b6c9da70
author
brice · · 2026-10-09 05:21 UTC
parent
3dcb344
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
1 file · +27 -1
M README.md +27 -1
@@ -223,6 +223,30 @@ while read -r event button col token; do
223223 done
224224 ```
225225
226+### Popups
227+
228+An interactive module can ask the bar for a **tooltip** or a **menu** by printing a *control line* instead of a frame. The bar draws it as a popup under the module (above it when `position = "bottom"`), with your theme's colors and font. Only modules with `interactive = true` can open popups, and there is one popup at a time.
229+
230+A control line is the escape sequence `ESC ] 777 ; neferbar ; <json> BEL`, then a newline:
231+
232+```sh
233+printf '\033]777;neferbar;{"type":"tooltip","col":0,"width":1,"title":"Volume","body":"42%%"}\007\n'
234+```
235+
236+`col` and `width` are the cells the popup points at, counted from the module's first cell, as in the lines the module reads. The JSON objects:
237+
238+| `type` | Fields | Effect |
239+|---|---|---|
240+| `tooltip` | `col`, `width`, `title`, `body` | shown only while the pointer is on the module; `body` may hold newlines |
241+| `menu` | `col`, `width`, `click`, `items` | opens a menu; `click` is the token of the `click` line it answers |
242+| `close` | none | closes the module's tooltip |
243+
244+A menu item is `{"id": 3, "label": "Mute", "kind": "check", "enabled": true, "checked": true, "items": [...]}`. `id` is a number you choose (0 or more), `kind` is `normal` (default), `separator`, `check` or `radio`, `enabled` defaults to true, and `items` makes it a submenu, which opens in place with a "‹ Back" entry. When the user picks an item the module reads `menu-activate <token> <id>`; when the menu closes any other way (Escape, a click elsewhere) it reads `menu-closed <token>`. The token is the `click` value of the menu.
245+
246+The bar opens a menu only for the latest click on the same module, at most 5 seconds old, and only once per click. A tooltip appears only while the module is hovered, and closes when the pointer leaves the module or a button is pressed.
247+
248+Limits: a control line is at most 64 KiB, a menu has at most 512 items in 8 levels, labels and titles are cut at 256 bytes, a tooltip body at 1024 bytes. Control characters are removed from the texts. A control line that breaks a rule is ignored, logged once per module, and never shown as text. A line that starts like a control line but has no BEL is an ordinary frame.
249+
226250 ### The bundled bar
227251
228252 `examples/bundle` is a ready-made bar: workspaces on the left, the focused app in the middle, the clock on the right, in your terminal's colors.
@@ -320,7 +344,9 @@ The icon takes the main color of the application's own icon, moved toward the ba
320344 - a right click calls `ContextMenu`, so the application shows its own menu;
321345 - the wheel calls `Scroll`: down and right are positive.
322346
323-Without `interactive = true` the icons only show. The tray talks to each application on a second connection and gives up on a call after 2 seconds, so a frozen application never blocks the other icons. Tooltips and the bar's own menus are not supported yet.
347+Without `interactive = true` the icons only show. The tray talks to each application on a second connection and gives up on a call after 2 seconds, so a frozen application never blocks the other icons.
348+
349+Resting the pointer on an icon for half a second shows the application's **tooltip** (its title in bold, its description below, markup removed; the item's title when it has no tooltip). Leaving the icon or clicking closes it.
324350
325351 Pick another icon with `[tray.icons]`. The key is the item's id or application name, in any case; the value is a glyph name, the text to show, or `""` to hide the item:
326352
@@ -223,6 +223,30 @@ while read -r event button col token; do
223 done223 done
224 ```224 ```
225 225
226+### Popups
227+
228+An interactive module can ask the bar for a **tooltip** or a **menu** by printing a *control line* instead of a frame. The bar draws it as a popup under the module (above it when `position = "bottom"`), with your theme's colors and font. Only modules with `interactive = true` can open popups, and there is one popup at a time.
229+
230+A control line is the escape sequence `ESC ] 777 ; neferbar ; <json> BEL`, then a newline:
231+
232+```sh
233+printf '\033]777;neferbar;{"type":"tooltip","col":0,"width":1,"title":"Volume","body":"42%%"}\007\n'
234+```
235+
236+`col` and `width` are the cells the popup points at, counted from the module's first cell, as in the lines the module reads. The JSON objects:
237+
238+| `type` | Fields | Effect |
239+|---|---|---|
240+| `tooltip` | `col`, `width`, `title`, `body` | shown only while the pointer is on the module; `body` may hold newlines |
241+| `menu` | `col`, `width`, `click`, `items` | opens a menu; `click` is the token of the `click` line it answers |
242+| `close` | none | closes the module's tooltip |
243+
244+A menu item is `{"id": 3, "label": "Mute", "kind": "check", "enabled": true, "checked": true, "items": [...]}`. `id` is a number you choose (0 or more), `kind` is `normal` (default), `separator`, `check` or `radio`, `enabled` defaults to true, and `items` makes it a submenu, which opens in place with a "‹ Back" entry. When the user picks an item the module reads `menu-activate <token> <id>`; when the menu closes any other way (Escape, a click elsewhere) it reads `menu-closed <token>`. The token is the `click` value of the menu.
245+
246+The bar opens a menu only for the latest click on the same module, at most 5 seconds old, and only once per click. A tooltip appears only while the module is hovered, and closes when the pointer leaves the module or a button is pressed.
247+
248+Limits: a control line is at most 64 KiB, a menu has at most 512 items in 8 levels, labels and titles are cut at 256 bytes, a tooltip body at 1024 bytes. Control characters are removed from the texts. A control line that breaks a rule is ignored, logged once per module, and never shown as text. A line that starts like a control line but has no BEL is an ordinary frame.
249+
226 ### The bundled bar250 ### The bundled bar
227 251
228 `examples/bundle` is a ready-made bar: workspaces on the left, the focused app in the middle, the clock on the right, in your terminal's colors.252 `examples/bundle` is a ready-made bar: workspaces on the left, the focused app in the middle, the clock on the right, in your terminal's colors.
@@ -320,7 +344,9 @@ The icon takes the main color of the application's own icon, moved toward the ba
320 - a right click calls `ContextMenu`, so the application shows its own menu;344 - a right click calls `ContextMenu`, so the application shows its own menu;
321 - the wheel calls `Scroll`: down and right are positive.345 - the wheel calls `Scroll`: down and right are positive.
322 346
323-Without `interactive = true` the icons only show. The tray talks to each application on a second connection and gives up on a call after 2 seconds, so a frozen application never blocks the other icons. Tooltips and the bar's own menus are not supported yet.347+Without `interactive = true` the icons only show. The tray talks to each application on a second connection and gives up on a call after 2 seconds, so a frozen application never blocks the other icons.
348+
349+Resting the pointer on an icon for half a second shows the application's **tooltip** (its title in bold, its description below, markup removed; the item's title when it has no tooltip). Leaving the icon or clicking closes it.
324 350
325 Pick another icon with `[tray.icons]`. The key is the item's id or application name, in any case; the value is a glyph name, the text to show, or `""` to hide the item:351 Pick another icon with `[tray.icons]`. The key is the item's id or application name, in any case; the value is a glyph name, the text to show, or `""` to hide the item:
326 352

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 5

Tags 4

↑↓ moveenter openesc close