Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/drivers/razer/devices.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ test("the wired DeathAdder V3 writes polling on the extended command", () => {
const wired = RAZER_PRODUCTS.get(0x00b2);
assert.equal(wired?.wireless, false);
assert.equal(wired?.highRatePolling, true);
// Both writes stay on 0x1f. The dongle's commit uses 0xff; copying that
// here would address a transaction this mouse does not use for the commit.
assert.equal(wired?.extendedPollingCommitTransactionId, RAZER_TRANSACTION_ID);
// The rate the hardware was found at has to survive the round trip, or the
// picker offers a value the mouse is already sitting at and cannot be set to.
assert.ok(wired?.pollingRates.includes(2000));
Expand Down
17 changes: 17 additions & 0 deletions src/drivers/razer/hid.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,23 @@ test("Mouse Dock Pro with a HyperPolling mouse unlocks the 8 kHz ladder", async
assert.deepEqual(status.supportedPollingRates, [...RATES_8K]);
});

test("the wired DeathAdder V3 commits polling with selector 0x01 on the same transaction id", async () => {
// Issue #222: selector 0x00 alone is acknowledged and the read-back stays
// at the old rate. OpenRazer follows it with selector 0x01, still on 0x1f.
const { client, sent } = fakeMouse(
{ tracking: 0, liftOff: 2, landing: 1, asymmetric: false },
{ productId: 0x00b2 },
);

const confirmed = await client.setPollingRate(2000);

assert.equal(confirmed, 2000);
const writes = sent.filter((packet) => packet[6] === 0x00 && packet[7] === 0x40);
assert.equal(writes.length, 2);
assert.deepEqual([writes[0][1], writes[0][8], writes[0][9]], [0x1f, 0x00, 0x04]);
assert.deepEqual([writes[1][1], writes[1][8], writes[1][9]], [0x1f, 0x01, 0x04]);
});

test("HyperPolling dongle commits an 8 kHz change through both selectors", async () => {
const { client, sent } = fakeMouse(
{ tracking: 0, liftOff: 2, landing: 1, asymmetric: false },
Expand Down
14 changes: 10 additions & 4 deletions src/razer/devices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,10 @@ export interface RazerProduct {
*/
highRatePolling: boolean;
/**
* Some early HyperPolling devices commit an extended polling change with a
* second write: selector `0x01` on a different transaction id. OpenRazer
* does this for the standalone HyperPolling dongle after the ordinary
* selector-`0x00` write. Omitted for devices that need only one write.
* Commit an extended polling change with a second write, selector `0x01`,
* on this transaction id. OpenRazer sends the ordinary selector-`0x00`
* write first. The HyperPolling dongle puts the commit on `0xff`; the wired
* DeathAdder V3 keeps both writes on `0x1f`. Omitted when one write is enough.
*/
extendedPollingCommitTransactionId?: number;
/**
Expand Down Expand Up @@ -497,12 +497,18 @@ const PRODUCT_DEFINITIONS: ReadonlyArray<[number, Omit<RazerProduct, "transactio
// already sitting at 2000 Hz while this row still offered a 1000 Hz ceiling.
// Wired, like the Viper 8KHz above, but HyperPolling is the point of the
// model and the legacy command cannot encode it.
//
// The extended write alone does not stick. Issue #222: an 8000 → 2000
// write was acknowledged and the read-back stayed at 8000. OpenRazer
// (`razer_attr_write_poll_rate`) follows selector `0x00` with selector
// `0x01`, both on transaction `0x1f` — not the dongle's `0xff` commit.
[0x00b2, {
model: "DeathAdder V3",
...STANDARD,
maxDpi: DPI_FOCUS_PRO,
pollingRates: RATES_8K,
highRatePolling: true,
extendedPollingCommitTransactionId: RAZER_TRANSACTION_ID_1F,
}],
// Standalone HyperPolling Wireless Dongle. OpenRazer reads extended polling
// with transaction 0x1f and commits a change with two writes: selector 0x00
Expand Down
Loading