detached a47a416

docs(readme): document interactive modules and tray clicks

commit
a47a41621e86a9d909f58686a9deb8a089dd441d
author
brice · · 2026-10-09 03:41 UTC
parent
debad97
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
1 file · +43 -1
M README.md +43 -1
@@ -189,6 +189,40 @@ done
189189
190190 neferbar draws at most as often as your monitor refreshes. If a script prints faster than that, only the latest frame is drawn. A script that prints nothing costs nothing.
191191
192+### Clicks and scrolling
193+
194+A module that sets `interactive = true` receives the pointer on its **standard input**, one line per event. Without the key, the module is click-through and its stdin is empty, as before.
195+
196+```toml
197+[[module]]
198+name = "volume"
199+zone = "right"
200+exec = "~/.config/neferbar/volume.sh"
201+interactive = true
202+```
203+
204+Only the cells the module shows take the pointer; the rest of the bar stays click-through. Columns count cells from the module's first cell, starting at 0.
205+
206+| Line | Sent when |
207+|---|---|
208+| `hover <col>` | the pointer moves to another cell of the module |
209+| `leave` | the pointer leaves the module |
210+| `click <left\|middle\|right> <col> <token>` | a button is pressed. `token` counts presses from 1 |
211+| `scroll <up\|down\|left\|right> <steps> <col>` | the wheel or touchpad scrolls. `steps` is at least 1 |
212+
213+Lines are ASCII and at most 127 bytes. A script that does not read its stdin loses the newest lines once 32 are waiting; it is never blocked or slowed down. A restarted script starts with an empty queue.
214+
215+```sh
216+#!/bin/sh
217+echo "vol"
218+while read -r event button col token; do
219+ case "$event $button" in
220+ "click left") pactl set-sink-mute @DEFAULT_SINK@ toggle ;;
221+ "scroll up") pactl set-sink-volume @DEFAULT_SINK@ +5% ;;
222+ esac
223+done
224+```
225+
192226 ### The bundled bar
193227
194228 `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.
@@ -268,6 +302,7 @@ A line is empty when no window has the focus. Control characters are removed fro
268302 name = "tray"
269303 zone = "right"
270304 exec = '"$NEFERBAR_BIN" tray'
305+interactive = true
271306 ```
272307
273308 Each icon is chosen without a list to maintain, from what the system already knows:
@@ -278,7 +313,14 @@ Each icon is chosen without a list to maintain, from what the system already kno
278313 4. a glyph for the category of the application's `.desktop` file: a gamepad for a game, a globe for a browser;
279314 5. the first letter of its name, in a circle.
280315
281-The icon takes the main color of the application's own icon, moved toward the bar's text color if it would not show on the bar. Hidden items are left out, and an item that asks for attention turns bold, in the accent color. Icons only show: clicks and menus are not supported.
316+The icon takes the main color of the application's own icon, moved toward the bar's text color if it would not show on the bar. Hidden items are left out, and an item that asks for attention turns bold, in the accent color. With `interactive = true`, the icons react to the pointer:
317+
318+- a left click calls the application's `Activate` (for an application that only offers a menu, it asks for the menu instead);
319+- a middle click calls `SecondaryActivate`;
320+- a right click calls `ContextMenu`, so the application shows its own menu;
321+- the wheel calls `Scroll`: down and right are positive.
322+
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.
282324
283325 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:
284326
@@ -189,6 +189,40 @@ done
189 189
190 neferbar draws at most as often as your monitor refreshes. If a script prints faster than that, only the latest frame is drawn. A script that prints nothing costs nothing.190 neferbar draws at most as often as your monitor refreshes. If a script prints faster than that, only the latest frame is drawn. A script that prints nothing costs nothing.
191 191
192+### Clicks and scrolling
193+
194+A module that sets `interactive = true` receives the pointer on its **standard input**, one line per event. Without the key, the module is click-through and its stdin is empty, as before.
195+
196+```toml
197+[[module]]
198+name = "volume"
199+zone = "right"
200+exec = "~/.config/neferbar/volume.sh"
201+interactive = true
202+```
203+
204+Only the cells the module shows take the pointer; the rest of the bar stays click-through. Columns count cells from the module's first cell, starting at 0.
205+
206+| Line | Sent when |
207+|---|---|
208+| `hover <col>` | the pointer moves to another cell of the module |
209+| `leave` | the pointer leaves the module |
210+| `click <left\|middle\|right> <col> <token>` | a button is pressed. `token` counts presses from 1 |
211+| `scroll <up\|down\|left\|right> <steps> <col>` | the wheel or touchpad scrolls. `steps` is at least 1 |
212+
213+Lines are ASCII and at most 127 bytes. A script that does not read its stdin loses the newest lines once 32 are waiting; it is never blocked or slowed down. A restarted script starts with an empty queue.
214+
215+```sh
216+#!/bin/sh
217+echo "vol"
218+while read -r event button col token; do
219+ case "$event $button" in
220+ "click left") pactl set-sink-mute @DEFAULT_SINK@ toggle ;;
221+ "scroll up") pactl set-sink-volume @DEFAULT_SINK@ +5% ;;
222+ esac
223+done
224+```
225+
192 ### The bundled bar226 ### The bundled bar
193 227
194 `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.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.
@@ -268,6 +302,7 @@ A line is empty when no window has the focus. Control characters are removed fro
268 name = "tray"302 name = "tray"
269 zone = "right"303 zone = "right"
270 exec = '"$NEFERBAR_BIN" tray'304 exec = '"$NEFERBAR_BIN" tray'
305+interactive = true
271 ```306 ```
272 307
273 Each icon is chosen without a list to maintain, from what the system already knows:308 Each icon is chosen without a list to maintain, from what the system already knows:
@@ -278,7 +313,14 @@ Each icon is chosen without a list to maintain, from what the system already kno
278 4. a glyph for the category of the application's `.desktop` file: a gamepad for a game, a globe for a browser;313 4. a glyph for the category of the application's `.desktop` file: a gamepad for a game, a globe for a browser;
279 5. the first letter of its name, in a circle.314 5. the first letter of its name, in a circle.
280 315
281-The icon takes the main color of the application's own icon, moved toward the bar's text color if it would not show on the bar. Hidden items are left out, and an item that asks for attention turns bold, in the accent color. Icons only show: clicks and menus are not supported.316+The icon takes the main color of the application's own icon, moved toward the bar's text color if it would not show on the bar. Hidden items are left out, and an item that asks for attention turns bold, in the accent color. With `interactive = true`, the icons react to the pointer:
317+
318+- a left click calls the application's `Activate` (for an application that only offers a menu, it asks for the menu instead);
319+- a middle click calls `SecondaryActivate`;
320+- a right click calls `ContextMenu`, so the application shows its own menu;
321+- the wheel calls `Scroll`: down and right are positive.
322+
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.
282 324
283 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: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:
284 326

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