Skip to content

feat(razer): add DeathAdder V2 support with macOS Input Monitoring hint - #58

Merged
snekxs merged 5 commits into
OpenMouse-Project:devfrom
jazzstack:feat/razer-deathadder-v2
Aug 9, 2026
Merged

snekxs merged 5 commits into
OpenMouse-Project:devfrom
jazzstack:feat/razer-deathadder-v2

Conversation

@jazzstack

Copy link
Copy Markdown
Contributor

Summary

Adds support for the Razer DeathAdder V2, plus a macOS fix that turns the browser’s opaque “Failed to open the device.” error into an actionable Input Monitoring hint for every Razer driver.

Changes

1. DeathAdder V2 driver

The V2 keeps the Essential family’s legacy transaction id (0x3f) and interface layout, so it reuses the existing Razer driver. It differs in two ways, both taken from OpenRazer’s driver:

  • DPI ceiling of 20,000 (OpenRazer’s DPI_MAX for this model), instead of the Essential’s 6,400.
  • No-store DPI reads/writes — the V2 generation reads and writes DPI through the NOSTORE byte (0x00) rather than the storage byte (0x01) the Essential and the V3 Pro use. The store byte is now a per-product field (dpiStorageByte); the default preserves the V3 family’s behavior. A wrong store fails loudly (implausible DPI read-back) rather than silently, because DPI is read before and after every write.

2. Device picker

Like the Essential family, the V2’s configuration channel lives on a separate HID interface, so a single-collection filter never matches it. The picker now requests the whole device and lets the driver reject interfaces that cannot answer.

3. macOS Input Monitoring hint

Razer’s configuration channel lives on a Generic Desktop Mouse collection, which macOS reserves for its own input stack. Without the Input Monitoring TCC permission the browser’s IOHIDDeviceOpen fails with kIOReturnNotPermitted, which WebHID surfaces as a generic error. The new openRazerDevice() wraps the open for all Razer drivers and appends an actionable hint pointing to System Settings → Privacy & Security → Input Monitoring. Nothing in the app can grant that permission — it is a system permission on the browser itself.

Testing

  • npm run build passes.
  • npm test passes — 206 tests, 0 failures.
  • New tests cover the store-byte-parameterized DPI read and the V2’s no-store path.

Hardware verification

Not yet hardware-tested. The driver is derived from OpenRazer’s DeathAdder V2 configuration (transaction id, interface layout, DPI ceiling, and store byte). A step-by-step checklist is in src/devices/razer/TESTING.md; step 6 (read DPI against Synapse before writing anything) is what separates a store-byte problem from a write problem.

The V2 keeps the Essential family's legacy transaction id (0x3f) and
interface layout, but reads and writes DPI through the no-store byte
(0x00) instead of the storage byte (0x01). The store byte is now a
per-product field; the default preserves the V3 family's behavior.
The V2's configuration channel lives on a separate interface like the
Essential family, so a single-collection filter would never match it.
Request the whole device the same way, letting the browser offer every
interface and the driver reject the ones that cannot answer.
Comment thread src/devices/razer/hid.test.ts Fixed
@IndoRexian

Copy link
Copy Markdown

Sorry, I approved this by accident, could someone with write access dismiss my review?

@snekxs
snekxs merged commit 710464d into OpenMouse-Project:dev Aug 9, 2026
3 checks passed
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.

4 participants