Media keys working again

This commit is contained in:
2026-10-18 03:50:33 +02:00
parent 726a7ae92d
commit 798708b3e7
20 changed files with 590 additions and 112 deletions

View File

@@ -78,7 +78,14 @@ Supported languages: German, English, Spanish, French.
The footer of the window shows the daemon state (`Daemon: running · Device: …`
plus the last G key that fired, or `Daemon: not reachable`) and follows it live:
start or stop the daemon while the GUI is open and the line updates itself.
start or stop the daemon while the GUI is open and the line updates itself. Two
more states are reported explicitly: `Device: not found` (the daemon is up but
has no keyboard) and `Configuration error` (a reload failed, so the daemon kept
the mappings it had).
The window starts from the saved mappings: it loads
`~/.config/gKeyMapper/mappings.conf` when it opens, so `Save mappings` in a fresh
window rewrites the same content instead of emptying the file.
## Running the daemon
@@ -95,9 +102,12 @@ The daemon reads G1–G9 from the keyboard and replays the configured action
`make install` ships a udev rule (`TAG+="uaccess"`) for that. On Linux Mint the
device already has such an ACL, otherwise install the rule or add your user to
the `input`/`uinput` group.
- While it runs, the kernel driver is detached from the vendor interface, so the
media keys (mute / volume / play) may stop working until it exits — it
reattaches the driver on shutdown.
- The media keys (mute / volume / play / next / previous / stop) keep working
while it runs. The keyboard delivers them on the vendor interface — as a second
kernel input device (`…/input1`, the "… G910 Keyboard" consumer device) when the
daemon is *not* running — so the daemon picks those reports up and forwards them
unchanged through its virtual keyboard. There is nothing to configure; they
behave exactly as they do without the daemon.
- The mappings file is **watched**: save in the GUI and the daemon picks the
change up by itself (within about half a second), no restart and no signal.
`SIGHUP`/`SIGUSR1` reload it on demand, which is also the fallback on systems
@@ -110,7 +120,15 @@ The daemon reads G1–G9 from the keyboard and replays the configured action
Note: the kernel truncates the process name to 15 characters, so
`pgrep -x gkeymapper-daemon` does **not** match.
- A failed reload keeps the previous mappings, so a transient read error never
silently disables every key.
silently disables every key. The GUI shows it as `Configuration error` in the
footer.
- It does **not** need the keyboard to be present: when it is unplugged (or not
there yet when the session starts) the daemon keeps running, reports
`Device: not found` and looks for it again every 2 s. A re-plug needs no
restart and keeps the GUI connection.
- A G key fires when its report first shows it as pressed: holding it down does
not repeat the action, and two G keys held at once both fire (the report
carries the state of all nine keys, not one key per report).
- Only one instance may run: a second one prints why it cannot get the bus name
and exits, instead of fighting over the keyboard and creating a second virtual
keyboard.
@@ -123,6 +141,14 @@ The daemon reads G1–G9 from the keyboard and replays the configured action
layout.
- `command:...` is run through the shell, so arguments work
(`command:/usr/bin/firefox --new-window`); a plain program path is also fine.
It inherits the environment of the user service, i.e. of your desktop session —
`DISPLAY`, `XAUTHORITY` and `PATH` are already there on a normal setup. If a
command cannot reach the display, export them into the user manager:
```bash
systemctl --user import-environment DISPLAY WAYLAND_DISPLAY XAUTHORITY
systemctl --user show-environment | grep DISPLAY
```
Stop it with Ctrl+C or `kill`; it reattaches the kernel driver on the way out.
@@ -294,7 +320,10 @@ export PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/share/pkgconfig:
## Planned next steps
- Support the media keys and the M1–M3 / MR keys of the G910.
- Make the media keys remappable (they are forwarded unchanged today, see above)
and support the M1–M3 / MR keys of the G910.
- `typeout`: type out a fixed text, like the reference project's action of that
name (the daemon would resolve the text through the active layout).
- Profiles: swap mapping sets on the fly (the G910's M keys), which is what the
reserved `SetProfile` D-Bus method was meant for.
- Key sequence timing: per-step delays for recorded macros.