Files
mesh-catalog/modules/polychromatic
jochen d0d5546088 Give the remaining tray applets their modules, each with one start
openrazer (the official driver, daemon and library), polychromatic (the
AUR tray, kept as found; its i3 line moves out of the i3 module into its
own node-display-session contribution), forticlient (the AUR VPN client:
its service declared, its configuration never read) and nm-applet (the
desktop half of NetworkManager, apart from the server-side module).

The openrazer daemon fails on both workstations because the account is
not in the openrazer group; openrazer_check names it and the README
carries the one-off step, since the account's user resource is zsh's.

desktop.go learns to tell a program from another sharing its 15-character
command name, so polychromatic's tools never count or end themselves, and
a copies test holds the six carriers to one text.
2026-10-05 15:10:30 +02:00
..

polychromatic

The Razer peripherals' tray on the workstations, as a module (novox/hq ADR 0208). It requires x11-display, so it is assigned only where a display server is held on the same machine. The driver and the daemon it drives are the openrazer module's.

Owns

what where
the tray's one start a contribution to node-display-session (ADR 0212): exec --no-startup-id polychromatic-tray-applet, placed by the i3 module among the other modules' lines

Nothing else. It declares no package, holds no seat and writes no file.

  • The application is kept as found. polychromatic (0.9.8) is not in the official repositories: on both workstations it is a foreign (AUR) package, installed explicitly. The host installs from the official repositories only, so the module cannot declare it. ADR 0205's pinned archive does not fit either: it is a Qt application with a helper, a tray and a controller, not a set of plain files. Like snapd and the laptop's triggerhappy, it waits for the mesh's package repository (research 027 question 1, option P2). Until then a fresh workstation installs it by hand, and polychromatic_check says when it is missing.
  • Its dependencies are the openrazer module's (python-openrazer, the daemon, the driver). The tray brings them when installed by hand; the module does not declare them twice.
  • The application's settings stay the operator's. ~/.config/polychromatic/ (preferences, presets, effects, device states) is the application's own, rewritten by it. The tools read only the tray's two keys of preferences.json.

How it starts: the module's window-manager line, and nothing else

The tray had two starts on both workstations:

  1. the window-manager line exec --no-startup-id polychromatic-tray-applet, in the i3 module's section Until their modules carry them;
  2. the package's XDG autostart entry polychromatic-autostart.desktop, which dex runs at login. It runs polychromatic-helper --autostart, which waits for the daemon, resumes each device's software effect, and starts the tray too while the application's setting Start the tray applet when I log on is ticked. It is ticked on both.

The tray takes a lock file at its start and stops an earlier instance, so two starts end as one tray, in a race. On the laptop both ran at the login of 2026-10-04 16:26, and one tray was left; which start it came from is not recorded anywhere. On the desktop only the window-manager line ran (that session began before dex was installed).

This module takes over the window-manager line as its contribution, and the i3 module drops it in the same change. That line is the tray's one start:

  • it starts the tray with the session, once (exec, so a reload of i3 starts nothing);
  • it is the mesh's, so it is in the composed configuration only where the module is assigned.

The helper stays, for its other work: the effects it resumes at login. The package's entry is not the module's to hide, and hiding it would need a file in the account's autostart directory. So the operator unticks the tray setting once (migration, below), and polychromatic_check names the helper's tray start as a second start for as long as the setting is ticked. The module never writes the setting: the application rewrites its preferences file itself.

Tools

They are served by the node's runtime as the operator account (ADR 0175).

tool does
polychromatic_status (r)
  • whether the tray runs: pid, since, and the scope or unit it runs in
  • the installed version, and that it is from outside the official repositories
  • what starts it: the window-manager lines, and the helper while the setting is on
  • the helper's entry, and the tray setting with its delay
  • whether the openrazer daemon answers, and how many devices it has (asked with --auto-start=no: never starts it)
polychromatic_restart (a) asks the tray to end (SIGTERM), forces it after 5 s, and starts polychromatic-tray-applet in the operator's session as a transient user unit mesh-polychromatic-tray, so it outlives the tools runtime. Refused plainly when nobody is logged in to the desktop
polychromatic_check (r)
  • the package is installed
  • exactly one start: one window-manager line; the helper does not start the tray too; no autostart entry of the account for it
  • one tray runs in a desktop session
  • the openrazer daemon answers
Each finding says what to do

The kernel keeps 15 characters of a command name, and polychromatic-tray-applet and this bundle's polychromatic-tools share them. The tools match the tray by its full program name, so they never count or end themselves.

What changes when it is assigned

laptop desktop
package none: polychromatic 0.9.8, explicit, foreign the same
~/.config/i3/config the tray's line moves from the i3 module's section to this module's contribution: the same line, and i3's reload starts nothing the same
tray none: one runs, left by the two starts' race none: one runs, from the predecessor's window-manager line (a child of i3, since the session of 2026-10-04 16:00, before dex ran)

Migration (ADR 0182)

On each workstation, once: in Polychromatic, untick Preferences → Tray → Start the tray applet when I log on. From the next login the module's line is the tray's one start, and polychromatic_check answers ok once the daemon answers too (the openrazer module's migration).

Leaves as found

  • ~/.config/polychromatic/: preferences, presets, custom effects, device states.
  • /etc/xdg/autostart/polychromatic-autostart.desktop, the package's.
  • The package itself, installed by hand.

Relies on

  • The openrazer module for the daemon and the driver. The tray without them shows no devices. polychromatic_check reports it.
  • The i3 module to place the contribution (ADR 0212 §4: the contribution depends on node-display-session), and to run dex for the helper.
  • A display server on the same machine (x11-display, ADR 0208 §3).