Skip to content

Make the HID interface selectable, defaulting away from interface 0 - #95

Open
dwaycik wants to merge 2 commits into
strodgers:mainfrom
dwaycik:fix/selectable-hid-interface
Open

Make the HID interface selectable, defaulting away from interface 0#95
dwaycik wants to merge 2 commits into
strodgers:mainfrom
dwaycik:fix/selectable-hid-interface

Conversation

@dwaycik

@dwaycik dwaycik commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Follows #94 — thanks for the context about the unfinished Windows work, that shaped how this is built.

_open_device() opens by vendor/product id, taking whichever interface enumerates first. On an RT100 that's interface 0, the one the README warns interferes with typing. 0.0.8 avoided it via the DEVICE_DESCRIPTION_REGEX lookup, which landed on interface 1; that lookup went away in 0.0.9.

Adds an INTERFACE config key defaulting to 1, restoring the pre-0.0.9 behaviour rather than picking a new number. Setting it to null falls back to opening by id — which is what Windows needs, since hidapi reports interface_number as -1 there. A configured interface that isn't present logs a warning and falls back rather than failing.

The second commit is optional. While testing the first, it became clear the correct interface is device-specific and editing config.json to try one is awkward — so it exposes the same setting as --interface. It wasn't part of what we discussed and came out of doing the work. It's a separate commit so it's easy to ignore; say the word and I'll drop it.

On my RT100 (3151:4010): interface 0 is the keyboard, 1 carries Consumer Control — holding it takes the volume knob and media keys offline until released — and 2 has no input collections at all. So 2 may suit start-daemon better, since that holds the device continuously. That's one board though, which is why the default restores 0.0.8's behaviour rather than generalising from mine.

dwaycik added 2 commits August 7, 2026 14:35
_open_device() opens with hid.device().open(vendor_id, product_id), which
takes whichever interface the backend enumerates first. On an RT100 that is
interface 0 -- the one carrying key input, which the README warns against
using.

0.0.8 did not have this problem: _find_device_path() matched
DEVICE_DESCRIPTION_REGEX against /sys/class/input and opened by path, which
landed on interface 1. That lookup was removed in 0.0.9.

Adds an INTERFACE config key, defaulting to 1 to restore the pre-0.0.9
behaviour rather than pick a new number. Setting it to null falls back to
opening by vendor/product id, which is what Windows needs -- hidapi reports
interface_number as -1 there, so path-based selection cannot work. If the
configured interface is not present the code logs a warning and falls back
rather than failing.

Measured on an RT100 (3151:4010), for whoever picks the default later:
interface 0 carries the keyboard, 1 carries Consumer Control -- holding it
takes the volume knob and media keys offline until released -- and 2 carries
no input collections at all. 2 may therefore suit start-daemon better, which
holds the device continuously, but that is one board and the default here
deliberately restores what 0.0.8 did rather than generalising from it.
Not part of the fix, and kept as its own commit so it is easy to leave out.

Which interface is correct turned out to be device-specific, and editing
config.json to try one is awkward, so this exposes the same setting as a
flag for troubleshooting. The config key remains the way to set it.
self.use_wireless = config_main["USE_WIRELESS"]
# Which HID interface to open. None falls back to opening by
# vendor/product id, which takes whichever the backend enumerates
# first -- on Windows that is the only option available.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code should be self-documenting, so no need in this comment

@kbrddestroyer

Copy link
Copy Markdown
Collaborator

Also you should fix pylint warning

help="HID interface to open, overriding INTERFACE in config.json. "
"Try another value if the keyboard misbehaves while a command runs.",
)
def cli(interface: int | None) -> None:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a pylint error somewhere related to this function call

@kbrddestroyer

Copy link
Copy Markdown
Collaborator

Was that code AI-generated by any chance?

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.

2 participants