Skip to content
Merged
2 changes: 1 addition & 1 deletion .npmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
allow-git=root
allow-git=all
5 changes: 4 additions & 1 deletion build/check-bundle-size.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@ const BUDGET_BYTES: Record<string, number> = {
// binding, canvas-drawn SV/hue surfaces, and hex/swatch sync.
// Raised from 427 kB for the second, dedicated Lighting-tab card: the
// render path now drives both the Advanced-tab card and the new tab.
// Raised from 429 kB for the dedicated Razer Cobra driver: the protocol
// registry now bundles the Cobra HID client, its extended-matrix lighting
// payloads, and the Cobra picker filter alongside the other Razer drivers.
// Protocol tests and preview fixtures remain unbundled.
".js": 429_000,
".js": 435_000,
};

const ASSETS = join("dist", "assets");
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added public/devices/razer-cobra.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions src/control.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ import { PulsarProHidClient } from "@openmouse/protocol/drivers/pulsar/pulsar-pr
import { OrbitalHidClient } from "@openmouse/protocol/drivers/orbital/hid";
import { RazerHidClient } from "@openmouse/protocol/drivers/razer/hid";
import { RazerViperMiniHidClient } from "@openmouse/protocol/drivers/razer/viper-mini-hid";
import { RazerCobraHidClient } from "@openmouse/protocol/drivers/razer/cobra-hid";
import { RazerViperHidClient } from "@openmouse/protocol/drivers/razer/viper-hid"
import { RazerViperV4ProHidClient } from "@openmouse/protocol/drivers/razer/viper-v4-pro-hid";
import { RAZER_PRODUCTS } from "@openmouse/protocol/razer-devices";
Expand Down Expand Up @@ -129,7 +130,7 @@ let activeEggClient: EggOp1HidClient | null = null;
let activeEggWeClient: EggWeHidClient | null = null;
let activeDmClient: WLMouseHidClient | LamzuHidClient | AtkHidClient | NinjutsoHidClient | null = null;
let activeOrbitalClient: OrbitalHidClient | null = null;
let activeRazerClient: RazerHidClient | RazerViperMiniHidClient | RazerViperHidClient | null = null;
let activeRazerClient: RazerHidClient | RazerViperMiniHidClient | RazerViperHidClient | RazerCobraHidClient | null = null;
let activeTeevolutionClient: TeevolutionHidClient | null = null;
let activeVgnClient: VgnF2HidClient | null = null;
let activeViperClient: RazerViperV4ProHidClient | null = null;
Expand Down Expand Up @@ -1949,7 +1950,7 @@ async function activateClient(client: SupportedClient): Promise<void> {
dpiOptions = client.getDpiOptions();
configureDpiControl(status.dpi);
showStatus(status);
} else if (client instanceof RazerHidClient || client instanceof RazerViperMiniHidClient || client instanceof RazerViperHidClient) {
} else if (client instanceof RazerHidClient || client instanceof RazerViperMiniHidClient || client instanceof RazerViperHidClient || client instanceof RazerCobraHidClient) {
activeRazerClient = client;
const status = await client.readStatus();
deviceStatuses.set(client.device, status);
Expand Down
17 changes: 17 additions & 0 deletions src/preview-fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,22 @@ const RAZER_VIPER_MINI: MouseStatus = {
firmware: ["Mouse 1.01"],
};

const RAZER_COBRA: MouseStatus = {
...RAZER_VIPER_MINI,
name: "Cobra",
dpi: 1600,
dpiY: 1600,
ui: {
family: "razer",
settingsReady: true,
valuesVerified: true,
hideUnsupportedPollingRates: true,
hideProcessingCard: true,
defaultDisplayName: "Cobra",
},
firmware: ["Mouse 1.00"],
};

const TEEVOLUTION: MouseStatus = {
brand: "Teevolution",
name: "Terra Pro",
Expand Down Expand Up @@ -415,6 +431,7 @@ export const PREVIEW_FIXTURES: Record<FixturePreviewMode, PreviewFixture> = {
orbital: { label: "Orbital One", status: ORBITAL },
razer: { label: "Razer Viper V3 Pro", status: RAZER },
"razer-viper-mini": { label: "Razer Viper Mini", status: RAZER_VIPER_MINI },
"razer-cobra": { label: "Razer Cobra", status: RAZER_COBRA },
"razer-viper-v4": { label: "Razer Viper V4 Pro", status: RAZER_VIPER_V4 },
teevolution: { label: "Teevolution Terra Pro", status: TEEVOLUTION },
vgn: { label: "VGN F2 Master Plus", status: VGN },
Expand Down
2 changes: 2 additions & 0 deletions src/preview-modes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const PREVIEW_KEYS = [
"orbital",
"razer",
"razer-viper-mini",
"razer-cobra",
"razer-viper-v4",
"teevolution",
"vgn",
Expand Down Expand Up @@ -45,6 +46,7 @@ export function parsePreviewMode(value: string | null): PreviewMode | null {
case "orbital": return "orbital";
case "razer": return "razer";
case "razer-viper-mini": return "razer-viper-mini";
case "razer-cobra": return "razer-cobra";
case "razer-viper-v4": return "razer-viper-v4";
case "teevolution": return "teevolution";
case "vgn": return "vgn";
Expand Down
1 change: 1 addition & 0 deletions src/ui/device-images.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const DEVICE_IMAGES: ReadonlyMap<string, string> = new Map([
["1532:00c0", "/devices/razer-viper-v3-pro.png"],
["1532:00c1", "/devices/razer-viper-v3-pro.png"],
["1532:008a", "/devices/razer-viper-mini.webp"],
["1532:00a3", "/devices/razer-cobra.webp"],
// OP1 8K, Purple Frost, and v2. XM2 models use different shells.
["3367:1964", "/devices/endgame-gear-op1-8k.png"],
["3367:1976", "/devices/endgame-gear-op1-8k.png"],
Expand Down