A super-simple keyboard layer monitor.
  • Rust 96.2%
  • C 1.7%
  • NSIS 1.4%
  • PowerShell 0.7%
Find a file
2026-04-25 22:06:19 +09:00
docs Windows support 2026-04-24 23:53:28 +09:00
packaging Windows support 2026-04-24 23:53:28 +09:00
protocol Remove unneeded readme 2026-04-25 22:06:19 +09:00
src Windows support 2026-04-24 23:53:28 +09:00
.gitignore Initial commit 2026-04-22 22:17:29 +09:00
build.rs Windows support 2026-04-24 23:53:28 +09:00
Cargo.lock Windows support 2026-04-24 23:53:28 +09:00
Cargo.toml Add protocol docs & example 2026-04-25 20:30:15 +09:00
LICENSE Add support for RPM installation, man files, config generation 2026-04-23 13:46:17 +09:00
README.md Add protocol docs & example 2026-04-25 20:30:15 +09:00

kb-layerd

kb-layerd is a small daemon that reads layer telemetry from a QMK keyboard using a custom protocol and makes the current state available locally. For those looking for more information on this protocol and how to implement it in their own keyboard's firmware, see the protocol directory.

This package builds two shared and one Windows-specific binary:

  • kb-layerd: the daemon
  • kb-layerctl: a CLI for checking status and watching updates
  • kb-layerui: a Windows-only per-user supervisor process

Configuration

By default, kb-layerd looks for a config file at:

  • Linux: $XDG_CONFIG_HOME/kb-layerd/config.toml
  • Linux fallback: ~/.config/kb-layerd/config.toml
  • Windows: %APPDATA%\kb-layerd\config.toml
  • Windows fallback: %LOCALAPPDATA%\kb-layerd\config.toml

Windows UI-specific settings live in a separate file beside the main config:

  • Windows UI config: %APPDATA%\kb-layerd\ui.toml
  • Windows UI fallback: %LOCALAPPDATA%\kb-layerd\ui.toml

Example:

[device]
vid = 0x1234
pid = 0xabcd
# serial = "EXAMPLE0000000001"

[polling]
interval_ms = 10
read_timeout_ms = 100

[runtime]
ipc_path = "$XDG_RUNTIME_DIR/kb-layerd/socket"

[logging]
level = "warn"

You must set either:

  • device.serial
  • or both device.vid and device.pid

You can also let kb-layerctl create or update the config file for you. After changing the config file, restart the daemon so it picks up the new settings. The exact restart command depends on how you installed or launched the daemon. If you run it as a Linux user unit, that is typically:

systemctl --user restart kb-layerd

[logging]:

  • default: warn
  • verbose file logging: debug

On Windows, kb-layerd writes to %LOCALAPPDATA%\kb-layerd\logs\kb-layerd.log and kb-layerui writes to %LOCALAPPDATA%\kb-layerd\logs\kb-layerui.log.

The Windows UI config file is separate from the daemon config and is created on first kb-layerui startup. Example:

label_prefix = "L"
label_suffix = ""
popup_enabled = true

[animation]
fade_in_ms = 120
hold_ms = 700
fade_out_ms = 180
slide_offset_px = 18
slide_direction = "up"

Build

cargo build --release

A release build also generates the kb-layerctl man pages and shell completions in:

target/release/package-assets/man/
target/release/package-assets/completions/

On Windows this also builds kb-layerui.exe.

Linux Installation

Install via RPM with:

sudo dnf install kb-layerd-0.1.2-1.x86_64.rpm

After installing the RPM, the expected setup flow is:

kb-layerctl --human discover
kb-layerctl set-device --serial EXAMPLE0000000001
systemctl --user daemon-reload
systemctl --user enable --now kb-layerd.service

This will create the systemd unit, but it does not create per-user config or start the service automatically.

After installing the RPM, man pages are available with:

man kb-layerctl

Subcommand manuals are also installed, for example:

man kb-layerctl-set-device

Shell completions are also installed for bash, fish, and zsh. Open a new shell after installing the RPM so your shell can load the new completion files. Bash users also need the distro bash-completion package installed and enabled.

Upgrade

Install with dnf:

sudo dnf install ./kb-layerd-0.1.0-1.x86_64.rpm

If kb-layerd is already running as a user service, reload the user systemd manager and restart the daemon after the package upgrade:

systemctl --user daemon-reload
systemctl --user restart kb-layerd.service

The upgrade replaces package-owned files such as the binaries, user unit, man pages, and license. It does not overwrite the user's own config file.

Uninstall

If the daemon is running as a user service, stop and disable it first:

systemctl --user disable --now kb-layerd.service

Then remove the package:

sudo dnf remove kb-layerd

Removing the RPM deletes only package-owned files. It does not remove ~/.config/kb-layerd/config.toml, runtime sockets under $XDG_RUNTIME_DIR, or any udev rule that you created manually.

Windows Installation

The repository includes an NSIS installer script at:

packaging/windows/kb-layerd.nsi

To build an installer on Windows:

  1. Install NSIS so makensis is on PATH.
  2. From the repo root, run:
powershell -ExecutionPolicy Bypass -File .\packaging\windows\build-installer.ps1

This:

  • builds the release binaries
  • packages kb-layerd.exe, kb-layerctl.exe, kb-layerui.exe
  • builds docs/windows-help.html
  • builds docs/THIRD-PARTY-NOTICES.txt
  • puts the installer under target/windows-installer/

The installer will install into:

%LOCALAPPDATA%\Programs\kb-layerd\

by default.

The installer:

  • creates a Startup-folder shortcut for kb-layerui.exe
  • registers an uninstall entry under the current user
  • launches kb-layerui.exe after install

The installer does not modify the user PATH. If you want to run kb-layerctl directly from PowerShell or Command Prompt, either:

  • call it by full path:
& "$env:LOCALAPPDATA\Programs\kb-layerd\kb-layerctl.exe" --help
  • or add this directory to your user PATH manually:
%LOCALAPPDATA%\Programs\kb-layerd\

After editing PATH, close any open terminal windows and start a new one.

Troubleshooting

  • If the daemon cannot find your keyboard, double-check the configured vid/pid or serial.

  • If daemon status shows reason=hid_open_failed, or the logs show a HID open permission error, your user may not have access to the keyboard's hidraw node on Linux. In that case, create a udev rule such as:

    KERNEL=="hidraw*", SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="1234", ATTRS{idProduct}=="abcd", TAG+="uaccess"
    

    Save it as /etc/udev/rules.d/70-kb-layerd.rules, then reload udev rules and re-apply them:

    sudo udevadm control --reload-rules
    sudo udevadm trigger
    

    After that, unplug and reconnect the keyboard if needed, then restart the daemon using whatever process manager or launch method you installed it with. If you run it as a Linux user unit, use:

    systemctl --user restart kb-layerd
    
  • If startup fails on Linux with an IPC-path error, either set runtime.ipc_path explicitly or make sure XDG_RUNTIME_DIR is set.

  • On Windows, kb-layerctl shutdown asks the daemon to exit cleanly over its per-user named pipe.