glorious: fix classic-line connection on a real Model O 2 Wired (settings still unsupported) - #104
Merged
snekxs merged 4 commits intoSep 16, 2026
Conversation
onyxhq-dev
force-pushed
the
fix/glorious-classic-report-id
branch
from
September 14, 2026 10:00
22640b3 to
48e9af5
Compare
…ng 0 A real 0x320f:0x823a (Model O V2 Wired) carried its config channel as numbered report 7, not the unnumbered report every other classic-family device uses - isSupported() rejected it outright since the check was hardcoded to report id 0. Now discovered per device at connect time and used for every send/ receive call. WebHID takes the report id separately from the payload bytes, so existing devices (report id 0) are unaffected.
Connecting to the real 0x320f:0x823a unit worked after the report-id fix, but every write then failed with "Failed to write the feature report.": its numbered report 7 declares a shorter byte length than the 64-byte buffer every payload builder in glorious-classic/index.ts assumes, and WebHID rejects a feature report whose length does not match the device's own descriptor. Same fix shape as the report-id discovery: read the declared length off the same collection at connect time and resize (truncate or zero-pad) every payload to fit before sending. The actual command bytes are always well under the shortest length seen in practice, so truncating never touches meaningful data.
…ad of guessing A diagnostic showed the previous fix was wrong in a way that looked right: resizing the driver's 64-byte payload to the real 0x320f:0x823a unit's 263-byte declared report stopped WebHID's write from erroring, but the mouse silently ignores the zero-padded result - DPI and polling rate diagnostics confirmed nothing on the mouse actually changes. Every payload in glorious-classic/index.ts is only reverse-engineered against the 64-byte case. Guessing a byte layout for 263 bytes and padding to fit was worse than doing nothing: it looked successful (no error, state cached as if applied) while doing nothing. Now any report length other than the confirmed 64 refuses every write with a clear 'not confirmed' error, the same shape already used for the core2 generation, until a real capture of the device's own official software gives an actual byte layout to build against.
Same VID (gloriousClassicIWired, 0x320f) as three product-table entries that share the 'core1' generation label with every other 64-byte classic-line device, despite a real 0x823a unit's feature report declaring 263 bytes and doing nothing when sent core1's 64-byte payloads. The label itself isn't what gates writes at runtime - isConfirmedReportLength() in classic-hid.ts checks the live descriptor - but leaving 'core1' undocumented here reads as confirmed when it never was; only VID-proximity reasoning put it there originally.
onyxhq-dev
force-pushed
the
fix/glorious-classic-report-id
branch
from
September 15, 2026 09:08
48e9af5 to
7274ac7
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the connection failure for a real 0x320f:0x823a ("Model O 2 Wired Mouse") - it could not connect at all before this.
Connecting now works. Changing settings does not yet - that part needs more reverse-engineering than this PR does, see below.
Two bugs, found from user-submitted diagnostics:
Connection failure. The driver assumed the config channel is always the unnumbered feature report (id 0), but this unit carries it as numbered report 7.
isSupported()/the constructor now discover the real report id from the device's own collections at connect time instead of assuming.Every write then failed with "Failed to write the feature report." This unit's report 7 declares a 263-byte length, not the 64 bytes every other classic-line device (and the community tools this protocol was ported from) uses. A first attempt resized the payload to fit, which stopped the WebHID error - but a follow-up diagnostic showed the mouse just silently ignores it: no error, but DPI/polling rate never actually change. The 263-byte unit's real byte layout is unknown; guessing at it isn't safe.
So instead: DPI, polling rate, lift-off distance, RGB, and debounce all now refuse cleanly with a "not confirmed on this unit's 263-byte feature report yet" error, the same shape already used for the existing core2 generation gate, rather than silently no-op.
vendors.ts's product table is annotated to flag this PID (and its two same-VID siblings) as unconfirmed rather than implying they share the 64-byte protocol.Getting settings working needs a real USB capture of Glorious's own official software talking to this exact model - nothing we have reverse-engineers a 263-byte report.