Files
mesh-catalog/modules/rofi
jochen 4b9558f195
mesh/merge-gate pass: builds rofi → g14, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery delivered
rofi: the desk's secret prompt names who asked (hq ADR 0277)
The controller's secret-ask verb opens the launcher's hidden prompt from anywhere on the mesh, so the
operator must know whose ask they are typing into. The prompt takes an optional asked_by, the
controller's word on the bus's caller held to a name's characters and spaces, and says it; a sentence,
markup or a line break is refused, so the prompt's words stay the launcher's.
2026-10-10 15:17:57 +02:00
..

rofi

The launcher as a module (novox/hq ADR 0208, research 026/04 and 05).

  • Installs rofi, claims the mesh's node-launcher seat and serves its verb menu. Requires x11-display on its own machine.
  • A value nobody sees (node-launcher.secret, novox/hq ADR 0259 §10): a prompt that shows nothing of what is typed (rofi -dmenu -password), whose answer is sealed to the key the asker gives before it leaves this process — never in the clear on the bus, in the runtime's log or in a call's record. The controller's give asks it to take a module's own secret, such as a bot token, at the desk. It waits at most 25 seconds. The prompt is written here from the module, the secret and the machine — names, checked as names — and says the mesh's controller asks: the bus denies the verb to every principal but the controller, however wide its grant. A caller's own words (prompt, message) are refused. On X11 any program of the operator's account can still read the keys as they are typed (ADR 0234's accepted residual risk), so the operator types only into a prompt they started with give.
  • The seat's dmenu-compatible command. It places ~/.local/bin/dmenu: choices on standard input, the chosen one on standard output, exit 1 when nothing was chosen. It runs rofi -dmenu, passing on dmenu's -p, -l and -i and dropping its look options. A script, a notifier or a clipboard manager calls dmenu and works whichever module holds the seat. On a node where the dmenu module holds node-launcher instead, the real dmenu answers the same calls.
  • Owns ~/.config/rofi/config.rasi and the themes mesh and mesh-powermenu in ~/.config/rofi/themes/. The faces are JetBrains Mono Nerd Font for the list and the input, and Inter for messages. Both are packages of the fonts module.
  • Places its key bindings as its own i3 drop-in, ~/.config/i3/config.d/50-rofi.conf. The i3 module's configuration includes that directory after it sets $mod.
  • Starts nothing. rofi runs when a key is pressed.
key runs
$mod+d applications (rofi-launch drun)
$mod+t a command (rofi-launch run)
$mod+Shift+t a command with sudo, in the terminal (rofi-launch sudo)
$mod+Shift+w the window switcher (rofi-launch window)
$mod+Escape the power menu (rofi-powermenu)

The power menu is here

The power menu belongs to the session. It is still the launcher's, because all of it is rofi: its theme, its buttons and its confirmation. Every action it takes is a verb of logind or the service manager, so it names no window manager and no locker:

  • lock is loginctl lock-session, which the holder of node-lock-screen answers;
  • log out is loginctl terminate-session;
  • suspend, reboot and shut down are systemctl's.

A Wayland session gets the same menu from whichever launcher holds the seat there.

Tools

tool does
node-launcher.menu show a list in the operator's session and answer the chosen line and its index, or cancelled (also when nobody answers within the timeout, 20 s by default, 25 s at most)
rofi_applications the desktop entries the launcher offers, the account's own winning an id; filter by words, hidden ones on request
rofi_themes every theme (the mesh's, the account's, the distribution's) and the one configured
rofi_run start a desktop entry or a command in the session, under the account's service manager

What it improves on what was found

  • Plain dmenu calls work again. The one found on 2026-10-04 is the notifier's context menu: on both workstations it called /usr/bin/dmenu, which neither had installed. The dunst module now calls dmenu, and this module answers it. The operator's own scripts all call rofi -dmenu, which keeps working.
  • The theme is one file per face. There is no colour file imported from a cloned theme repository. The faces are the decided ones (research 026/04): Iosevka and Hack are gone.
  • The retry after resume no longer reopens a closed menu. The found launchers retried rofi -dmenu on any failure, so pressing Escape in the sudo prompt reopened it four times. rofi-launch retries only a failure within half a second, which is a failed keyboard grab.
  • The power menu locks through logind, so it goes through the one locker. The found one ran i3lock directly and bypassed it. Log out no longer names four window managers.
  • icon-theme and window-command are gone. They named an icon theme and a program (wmctrl) that nothing installs. rofi's defaults serve.

What it leaves as found

  • ~/.config/rofi/themes-repo/ (a cloned theme repository), the five symbolic links into it (applets, images, launchers, powermenu, scripts), colors/, theme.rasi and powermenu.rasi.
  • The predecessor's scripts in ~/scripts: rofi-launcher-normal, rofi-launcher-terminal, rofi-launcher-terminal-sudo and powermenu (replaced here), and theme-picker with its modes (settings, once issue 168 closes).

Migration (ADR 0182)

Once the i3 module carries the main i3 configuration:

  1. Delete ~/.config/rofi/theme.rasi, powermenu.rasi, colors/, the five links and themes-repo/. Nothing reads them any more.
  2. Delete the four scripts above from ~/scripts.
  3. Your scripts that call rofi -dmenu keep working. Calling dmenu instead lets them follow the seat, for example to a Wayland launcher later.

Blockers

  • node-launcher, x11-display and the i3 drop-in directory are ADR 0208's and the i3 module's. Until the controller knows the seat, mctl reads the claim as unknown.
  • ~/.local/bin is on PATH through the zsh module's environment contribution (ADR 0203). The key bindings name ~/.local/bin/… in full, so they do not depend on it. Callers of dmenu do.

Its i3 lines are a contribution (changed 2026-10-05, novox/hq ADR 0212)

The module no longer writes a file into i3's config.d. Its window-manager lines (the source is still under files/i3/ where it had one) are a contribution to node-display-session. The i3 module places them in its own configuration under a # <module> line, so this module depends on a window manager being assigned beside it.