A COSMIC desktop panel applet that displays the active layer of any Vial-based QMK keyboard in real time, using raw HID communication.
This project has two components:
- Firmware patch — adds raw HID layer reporting to your vial-qmk keymap
- Panel applet — reads the active layer every 100 ms and shows it in the COSMIC panel
Run the interactive setup script from the repo root:
./quickstart.shIt walks through every step below, offering to install missing prerequisites along the way.
# Patch your vial-qmk checkout (set KEYBOARD/KEYMAP to match your board)
KEYBOARD=beekeeb/piantor KEYMAP=vial firmware/apply.sh
# Compile and flash (left, right, or both halves)
./flash.sh bothapply.sh enables RAW_ENABLE and installs the layer reporting callback (layer_report.c).
It is idempotent — safe to run again after updates.
Back up your Vial layout first (File → Save Current Layout in the Vial app). Flashing can reset EEPROM on first boot, wiping keymap customisations.
./find_keyboard.shPrints the vendor ID, product ID, and device path of connected Vial HID devices.
Requires Python 3 and the hidapi package (pip install hidapi), or use quickstart.sh to install them automatically into a local venv.
KBD_VID=0x3A3B KBD_PID=0x0001 ./install-applet.shThe script:
- Builds the Rust binary and installs it to
~/.local/bin/vial-layer - Installs the
.desktopfile to/usr/share/applications/(requires sudo) - Persists
KBD_VID/KBD_PIDin~/.config/environment.d/vial-layer.conf
# Edit the file first to fill in your VID and PID (without 0x prefix)
sudo cp udev/99-vial-hid.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules && sudo udevadm triggerThis allows the applet to open the HID device without root.
quickstart.sh fills in the VID/PID automatically.
Right-click the panel → Edit Panel → Add Applet → Vial Layer Indicator.
Log out and back in first if the applet doesn't appear (the environment variables need a fresh session).
Create ~/.config/vial-layer/config.toml to name your layers:
layers = [
"Base", # 0
"Nav", # 1
"Sym", # 2
"Fn", # 3
]Layers without a name fall back to Layer N. See applet/data/config.toml.example for a full example.
Tip: After editing the config file, reload it instantly via the right-click menu (Reload Config) — no restart required.
| Variable | Default | Description |
|---|---|---|
KBD_VID |
— | USB vendor ID (required) |
KBD_PID |
— | USB product ID (required) |
VIAL_LAYER_CONFIG |
~/.config/vial-layer/config.toml |
Path to config file |
- Right-click menu — pause/resume polling and reload the config file without restarting
- Vial compatibility — polling should be automatically suspended while the Vial app is open, preventing HID command conflicts
Note: If you need to open the Vial app while the applet is running, pause polling first via the right-click menu (Pause Polling) to avoid HID conflicts. Resume once you are done in Vial.
- Display states —
disconnected(keyboard not found),no firmware support(layer query unhandled by firmware),paused(polling paused by user)
vial-gui issue #310 tracks a feature request to expose the active layer (and other host-side data) natively over the Vial protocol. If that lands, the firmware patch in this repo would become unnecessary — the applet could query the layer without any custom layer_report.c. Until then, firmware/apply.sh is required.
apply.sh adds RAW_ENABLE = yes and layer_report.c to the vial-qmk keymap.
The firmware implements raw_hid_receive_kb(): when the applet sends command byte 0x42, the keyboard responds with the current layer index from get_highest_layer(layer_state).
The applet polls every 100 ms via the Vial raw HID interface (usage page 0xFF60, usage 0x61).
├── applet/ # COSMIC panel applet (Rust + libcosmic + hidapi)
│ ├── src/main.rs
│ ├── Cargo.toml
│ └── data/
│ ├── vial-layer.desktop
│ └── config.toml.example
├── firmware/
│ ├── layer_report.c # QMK raw HID callback
│ └── apply.sh # Patches vial-qmk to enable layer reporting
├── udev/
│ └── 99-vial-hid.rules
├── find_keyboard.sh # Discover keyboard VID/PID
├── flash.sh # Compile and flash firmware
├── install-applet.sh # Build and install the applet
└── quickstart.sh # Interactive end-to-end setup