Files
mesh-catalog/modules/openrazer/README.md
T
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

6.1 KiB

openrazer

The Razer peripherals' kernel driver and the account's daemon that drives it, on the workstations, as a module (novox/hq ADR 0208: one module per piece of software). The tray that shows the devices is the polychromatic module's. This module needs no display: the daemon speaks to the driver and to its clients on the session bus.

Owns

what where
the kernel driver's source, built by DKMS for each installed kernel (razerkbd, razermouse, razerkraken, razeraccessory) package openrazer-driver-dkms
the daemon (org.razer on the session bus) and its user unit package openrazer-daemon
the client library every front end speaks to the daemon through package python-openrazer

All three from the official repositories (extra). On both workstations they are installed today as dependencies of the AUR tray, and become the mesh's here.

Why two modules and not one razer: the driver and the daemon are one project, in the official repositories, and any front end uses them. The tray is another project, outside the official repositories. That is the line between bluetooth and blueman too. A machine can hold the stack without the tray, for a front end of the operator's own or for the daemon's persistence of the devices' lighting and DPI.

Not this module's:

  • The kernel headers DKMS builds against (linux-headers). They are the kernel's, and every DKMS driver on a machine needs them (the laptop also builds nvidia, the desktop vboxhost and xone). No module declares them yet. openrazer_check says when the driver is not built for the running kernel.
  • dkms itself, which the driver package depends on.
  • The account's membership of the openrazer group (below).

The group: a step for the operator, once

The driver's udev rules give each device's files to the group openrazer, which the driver package creates (sysusers). The daemon refuses to start for an account outside that group: User is not a member of the openrazer group.

On both workstations the account is not in it today, so the daemon has failed at every start since openrazer moved from plugdev to its own group. The tray runs, and shows no devices. The account is still in plugdev, which openrazer no longer uses. Another device's rules may (the laptop has a Logitech receiver rule that does), so it stays.

The module cannot declare the membership. The host's user resource takes groups, additively, but the zsh module already declares the operator's account as its user resource. A second module declaring the same account is refused at composition, as two owners of one name. Until the mesh can add a group to the account from a second module, this is the operator's step (below), and openrazer_check holds it.

How it starts: D-Bus activation, and nothing else

The package installs org.razer as a D-Bus service whose SystemdService is the user unit openrazer-daemon.service. The first client that asks for org.razer starts the daemon through that unit: at login, the tray's helper (polychromatic-helper --autostart). That activation is the daemon's one start. One unit, so it is never two daemons.

  • The unit is not enabled on either workstation, and the module does not enable it. Enabling it would start the same unit at login a moment earlier, with nothing gained.
  • Asked by a tool, the bus is always called with --auto-start=no, so asking never starts it.

Tools

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

tool does
openrazer_status (r)
  • the three packages' versions
  • the driver: the running kernel, DKMS's state for it, the modules loaded, the devices bound (USB id, driver, interfaces)
  • the group: whether the account is in it, and whether the account's running service manager has it
  • the daemon: its unit's active and enabled states, its process, its version, and, when its unit failed, the reason it gave
  • each device the daemon sees: name, type, firmware, battery and charging where the device has them. Never its serial
openrazer_restart (a) restarts openrazer-daemon.service in the account's service manager and answers the devices it then sees. When it fails, the answer carries the daemon's own reason
openrazer_check (r)
  • the packages are installed
  • the driver is built for the running kernel, and loaded
  • a device is bound
  • the account is in openrazer, and its service manager has the group (a group added after login needs a new login)
  • one start: the activation file is present, no window-manager exec
  • one daemon runs, from its unit, and answers
  • it sees every device the driver holds
Each finding says what to do

Every command has a timeout and capped output. Everything runs through an injected runner and a fake root in the tests.

What changes when it is assigned

laptop desktop
packages none: the three are installed, 3.12.4, as dependencies of the tray the same
driver none: built for the running kernel, razermouse loaded, a Basilisk V3 Pro bound the same, a Basilisk V2 bound
daemon none: the unit stays disabled; it failed at login (not in the group) the same

Migration (ADR 0182)

On each workstation, once:

  1. sudo gpasswd -a $USER openrazer
  2. Log out of every session, or reboot. The account's service manager takes its groups when it starts, and the daemon runs under it.
  3. openrazer_check answers ok, and the tray shows the devices.

plugdev stays. Nothing else is required.

Leaves as found

  • The daemon's settings and persistence under ~/.config/openrazer/, and its log under ~/.local/share/openrazer/.
  • plugdev and every other group of the account.
  • The kernel headers and DKMS.

Relies on

  • The account in openrazer, by hand (above).
  • A client to start the daemon. At login that is the polychromatic module's tray helper. Without a client nothing asks, and nothing needs it to run.
  • The kernel headers of every installed kernel, for DKMS.