6.3 KiB
Executable File
Keyboard inputs
This all comes from the fact that a "key press" isn't one thing — it's a stack of specs and translations from keyboard hardware → USB/HID → Linux kernel → userspace (XKB/Wayland) → Hyprland binds.
1. Big picture: what happens when you press a key?
When you hit a key (like your "lock" key), roughly this happens:
Physical switch on keyboard
↓
Keyboard firmware → USB HID "usage" (e.g. 0x07:0xE3 = Left GUI)
↓
Linux kernel input subsystem (evdev) → KEY_LEFTMETA (code 125)
↓
libinput / xkbcommon → keysyms (like Super_L, L, etc.)
↓
Hyprland → your `bind = SUPER, L, exec, ...`
The "topic" we've been poking at is basically understanding each layer in that stack.
2. USB HID: where 700e3 comes from
Modern USB keyboards follow the USB HID (Human Interface Device) specification. This spec defines Usage Tables: numerical codes for things like keys, buttons, axes, etc.
-
The keyboard page is Usage Page 0x07 (Keyboard/Keypad).
-
In your
evtestoutput,MSC_SCAN value 700e3means:0x07(Keyboard page)0xE3(Left GUI / "Windows/Super" key)
You can see the official tables here (PDF):
- HID Usage Tables (includes Keyboard/Keypad page 0x07) https://usb.org/sites/default/files/hut1_21.pdf (USB Implementers Forum)
If you scroll to the Keyboard/Keypad Page (0x07) section, it lists all the key usages: A, B, C, modifiers, function keys, etc. There's also a standalone Keyboard/Keypad-page extract people mirror, like this PDF snippet: (d1.amobbs.com)
So:
700e3= Page0x07, Usage0xE3→ Keyboard Left GUI7000f= Page0x07, Usage0x0F→ Keyboard L key
That's how we knew your lock key was sending Super + L.
3. Linux input subsystem: EV_MSC, EV_KEY, KEY_LEFTMETA
Linux has a dedicated input subsystem in the kernel (drivers/input,
drivers/hid etc.) that takes those HID usages and turns them into a
unified stream of input events.
(Linux Kernel Documentation)
Key ideas:
-
Devices expose
/dev/input/eventXnodes. -
Each event is a struct with:
type(e.g. =EVKEY=,EV_MSC,EV_REL,EV_SYN)code(e.g. =KEYL=,KEY_LEFTMETA)value(pressed = 1, released = 0, repeat = 2)
Docs worth bookmarking:
-
Linux input subsystem overview https://docs.kernel.org/input/input.html (Linux Kernel Documentation)
-
Input event types and codes (
event-codes.txt) https://www.kernel.org/doc/Documentation/input/event-codes.txt (Kernel.org)
The keycode definitions (KEY_L, KEY_LEFTMETA, etc.) live in:
include/uapi/linux/input-event-codes.hin the kernel source Example mirror: https://raw.githubusercontent.com/torvalds/linux/master/include/uapi/linux/input-event-codes.h (GitHub)
When evtest prints:
type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e3
type 1 (EV_KEY), code 125 (KEY_LEFTMETA), value 0
that means:
EV_MSC / MSC_SCAN→ "Here is the raw hardware scancode" (from USB HID).EV_KEY / KEY_LEFTMETA→ "Linux mapped that scancode to logical key LEFTMETA".
4. XKB / xkbcommon: mapping to actual characters & modifiers
Above the kernel, you've got an extra mapping layer that says:
For keycode N, with this layout, when Shift is held, produce this character/symbol.
On X11 this is handled by XKB (X Keyboard Extension); on Wayland compositors (including Hyprland) the same ideas are implemented via xkbcommon.
Docs:
-
X Keyboard Extension (XKB) protocol spec https://www.x.org/releases/X11R7.7/doc/kbproto/xkbproto.html (X.Org)
-
Arch Wiki: X keyboard extension (good high-level intro) https://wiki.archlinux.org/title/X_keyboard_extension (ArchWiki)
-
A nice "practical" walkthrough of XKB concepts: [https://medium.com/[cite/t:@damko/a-simple-humble-but-comprehensive-guide-to-xkb-for-linux-6f1ad5e13450](https://medium.com/@damko/a-simple-humble-but-comprehensive-guide-to-xkb-for-linux-6f1ad5e13450)] (Medium)
Hyprland, Sway, etc. all use libinput + xkbcommon under the hood to interpret those keycodes and translate them into keysyms and modifiers.
5. Hyprland / your config: where the bindings fit in
Hyprland sits at the top of this stack:
- It listens to the input events (via libinput).
- It sees keysyms/modifiers (e.g. =Super=,
L). - It matches them against your config:
bind = SUPER, L, exec, hyprlock
So your keyboard's "lock" key:
- Firmware sends HID usages
0xE3(Left GUI) and0x0F(L). - Linux maps them to
KEY_LEFTMETA(125) andKEY_L(38). - xkbcommon maps that to
Super+L. - Hyprland says: "Ah, SUPER+L → run
hyprlock".
The "topic" you stumbled into is just peeling back each abstraction layer.
6. Handy tools & libraries if you want to go deeper
-
evtest,libinput debug-events,showkey→ To watch what your keyboard is actually sending. -
Python-evdev – Python bindings to read
/dev/input/event*yourself: https://python-evdev.readthedocs.io/ (python-evdev.readthedocs.io) -
Linux input subsystem docs again: https://docs.kernel.org/driver-api/input.html (Linux Kernel Documentation)