Skip to content

Drop the Shokz dongle phantom power key with a libinput quirk - #9850

Open
xymbol wants to merge 1 commit into
omacom:quattrofrom
xymbol:shokz-libinput-quirk
Open

Drop the Shokz dongle phantom power key with a libinput quirk#9850
xymbol wants to merge 1 commit into
omacom:quattrofrom
xymbol:shokz-libinput-quirk

Conversation

@xymbol

@xymbol xymbol commented Sep 2, 2026

Copy link
Copy Markdown

What

Ships a libinput quirk that drops the phantom KEY_POWER events Shokz USB headset dongles emit, so the system menu stops opening by itself.

Requires the companion PR in omarchy-pkgs: omacom/omarchy-pkgs#279. Without it the file ships only under /usr/share/omarchy/default/ and has no effect.

Why

Shokz dongles (3511:2B1E/2EF2/2F06) declare their proprietary control channel inside the Consumer Control collection using a single Consumer page usage 0x30, which means "Power". The kernel duplicates that lone usage across every byte position of the three 511-byte and one 128-byte input reports (1661 usages) and hid-input maps Consumer 0x30 to KEY_POWER unconditionally. Ordinary headset telemetry therefore arrives as power-key presses, a few seconds after plug-in and again on later link or battery state changes.

Omarchy binds XF86PowerOff to the system menu (default/hypr/bindings/utilities.lua), so each phantom press opens it. The dongles have no host power button, so dropping KEY_POWER for them loses nothing; volume and media keys on the same node are untouched.

A hwdb keycode remap cannot fix this: udev issues one EVIOCSKEYCODE per entry and hidinput_setkeycode() reaches only the first of the 1661 duplicated usages. Filtering the event code in libinput is unaffected by the duplication.

Placement

default/libinput/50-omarchy.quirks, installed package-owned at /usr/share/libinput/50-omarchy.quirks, per the quick reference in docs/file-layout.md and matching default/fontconfig/conf.avail/50-omarchy.conf.

Deliberately not /etc/libinput/local-overrides.quirks: that is the single admin override path libinput reads, and a package owning it would conflict with users who already applied the manual workaround.

No migration. Package-owned files reach existing installs through pacman on the next omarchy update, which is how every other default/** system file ships. It takes effect at the next Hyprland start.

Device coverage

0x2F06 (Loop120) is verified by full HID descriptor decode and on-hardware testing. 0x2EF2 (Loop120) and 0x2B1E (OpenComm2 UC) come from public reports of the same symptom; 0x2B1E is corroborated by the existing USB_ID(0x3511, 0x2b1e) entry in sound/usb/quirks.c. The quirk is an exact VID:PID match and inert on anything else.

Upstream

Reported to libinput as libinput#1333 with a libinput record capture attached and the same quirk offered as a patch. Once it ships in a libinput release and reaches Arch, this file becomes redundant and can be deleted with no migration.

Tests

  • ./test/cli — pass
  • ./test/shell — 226 of 227. The single failure is runtime-smoke-test.sh, which fails identically on pristine quattro on the same machine.
  • New test/shell.d/libinput-quirks-test.sh — pass. Validates the file through libinput quirks validate, pins the three PIDs, and asserts KEY_POWER is the only event code touched. Negative-tested against a deliberately broken section.
  • Live device: with the dongle attached, libinput quirks list against the shipped file prints AttrEventCode=-KEY_POWER;. Confirmed behaviorally on 4.0.2 with the same rule installed as a local override: after a Hyprland restart the menu no longer opens on headset power-cycle, and the dongle's volume keys still work.

Shokz USB headset dongles (3511:2B1E/2EF2/2F06) declare their
proprietary control channel as a single Consumer "Power" usage spanning
511- and 128-byte input reports. The kernel duplicates that usage across
every byte position and maps each one to KEY_POWER, so ordinary headset
telemetry synthesizes phantom power-key presses that open the system
menu whenever the dongle is plugged in or the headset changes state.

Ship the quirk source at default/libinput/50-omarchy.quirks for
omarchy-settings to install package-owned at
/usr/share/libinput/50-omarchy.quirks, leaving
/etc/libinput/local-overrides.quirks free for local overrides.
@xymbol
xymbol force-pushed the shokz-libinput-quirk branch from 0ad145d to 860eb3b Compare September 2, 2026 17:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant