Sofle Layer — Omarchy bar widget
Live keyboard layer indicator for the Omarchy (Quattro) bar. Shows a keyboard icon on the base layer, icon + layer name when a layer is active, and opens a per-layer keymap diagram on click.
Works with any QMK keyboard that prints its active layer on the debug console (ships tuned for a Sofle v2 split board).
Requirements
- Omarchy Quattro (Quickshell bar) with a Nerd Font as
monospace(the default JetBrainsMono Nerd Font is what the label/icon are designed for) - A flashing-capable QMK keyboard whose firmware reports layer changes:
with#include "print.h" layer_state_t layer_state_set_user(layer_state_t state) { uprintf("sofle layer=%u\n", (unsigned int)get_highest_layer(state)); return state; }CONSOLE_ENABLE = yesin rules.mk. Console output only flows on the USB-connected half of a split board; the other half's layer state arrives over TRRS via split sync.
Install
omarchy plugin add https://github.com/alvarosaavedra/omarchy-sofle-layer.git --enable
Then install and start the watcher daemon:
PLUGIN="$HOME/.config/omarchy/plugins/alvarosaavedra.sofle-layer"
cp "$PLUGIN/sofle-layer.service" ~/.config/systemd/user/
# If your daemon flags differ, edit ExecStart there, e.g.
# ExecStart=%h/.config/omarchy/plugins/alvarosaavedra.sofle-layer/sofle-layerd --usb fc32:0287 --state-file /run/user/1000/sofle-layer
systemctl --user daemon-reload
systemctl --user enable --now sofle-layer.service
Generate the layer diagram data the popup shows. For a Sofle-style keymap
(one visual row per source line inside each LAYOUT(...) block):
python3 "$PLUGIN/tools/gen-layout-json.py" /path/to/keymap.c \
-o ~/.local/share/sofle/layers.json
Re-run that command whenever your keymap changes; the popup hot-reloads.
For other keyboards, adapt ROW_SHAPES in the script to your LAYOUT macro.
Optional: bind the popup to a key:
-- ~/.config/hypr/bindings.lua
o.bind("SUPER + SHIFT + K", "Keyboard layout map",
"omarchy-shell shell toggle alvarosaavedra.sofle-layer")
Configure
Settings live on the widget's entry in ~/.config/omarchy/shell.json
(puted there by the plugin's barWidget.defaults; edit as needed):
{
"id": "alvarosaavedra.sofle-layer",
"stateFile": "/run/user/1000/sofle-layer",
"layersFile": "~/.local/share/sofle/layers.json",
"icon": ""
}
| Setting | Default | Meaning |
|---|---|---|
stateFile |
$XDG_RUNTIME_DIR/sofle-layer |
File the daemon publishes the layer to. Keep it in sync with the daemon's --state-file. |
layersFile |
~/.local/share/sofle/layers.json |
Diagram data produced by the generator. |
icon |
Keyboard glyph (U+F11C) | Any Nerd Font glyph for the bar label. |
stateFile and layersFile default to the standard locations when left
empty; a per-OS or per-daemon path just goes here.
Remove
systemctl --user disable --now sofle-layer.service
rm ~/.config/systemd/user/sofle-layer.service
systemctl --user daemon-reload
omarchy plugin remove alvarosaavedra.sofle-layer
Troubleshooting
- Widget never leaves the base layer: the keyboard's debug console
isn't found. With the keyboard connected, check
journalctl --user -u sofle-layerdfor "reading /dev/hidrawN", or confirm the firmware printssofle layer=N(hid_listen works too). - Right half of a split OLED/popup stale: enable the split sync defines in config.h as in the docs — layer state reaches the slave over TRRS that way too.
- Edits to the plugin don't seem to apply: QML documents are cached per
URL;
omarchy restart shellflushes them.