From fd7e4361dcde4504eae55738320ecbbf2b7cc446 Mon Sep 17 00:00:00 2001 From: yanhenrique-dev Date: Sat, 5 Sep 2026 14:12:11 -0300 Subject: [PATCH 1/2] feat: detect K-snake X11 in Mouse Check (VID 0xA8A4/0xA8A5) --- src/check-scan.ts | 2 ++ src/supported-mice.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/check-scan.ts b/src/check-scan.ts index 65c4691..a774a0c 100644 --- a/src/check-scan.ts +++ b/src/check-scan.ts @@ -31,6 +31,8 @@ export const BRANDS: Record = { 0x0C45: "Redragon", 0x1BCF: "Alienware", 0x3151: "Fantech", + 0xA8A4: "K-snake", + 0xA8A5: "K-snake", }; const OPENMOUSE_SUPPORTED = new Set([ diff --git a/src/supported-mice.ts b/src/supported-mice.ts index 0086164..3d5cc71 100644 --- a/src/supported-mice.ts +++ b/src/supported-mice.ts @@ -552,6 +552,8 @@ export const MICE: Mouse[] = [ note: "CM protocol — not implemented" }, { brand: "Cooler Master", model: "MM711", status: "driver", req: 1, note: "CM protocol — not implemented" }, + { brand: "K-snake", model: "X11", status: "driver", req: 1, + note: "VID 0xA8A4 (USB) / 0xA8A5 (2.4G) PID 0x2255 — 0x55-framed output-report protocol, vendor panel reverse-engineered, driver in progress in mouse-protocol" }, // UNKNOWNS ──────────────────────────────────────────────────────────── { brand: "Hitscan", model: "Hyperlight", status: "unknown", req: 5, From 645d6f0b48dd8dc4830070b53e1133687a3dad0a Mon Sep 17 00:00:00 2001 From: yanhenrique-dev Date: Sat, 5 Sep 2026 15:12:20 -0300 Subject: [PATCH 2/2] feat: map K-snake X11 artwork (a8a4/a8a5:2255 -> ksnake-x11.png) --- src/ui/device-images.test.ts | 8 ++++++++ src/ui/device-images.ts | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/src/ui/device-images.test.ts b/src/ui/device-images.test.ts index 4ce8535..f2b4a59 100644 --- a/src/ui/device-images.test.ts +++ b/src/ui/device-images.test.ts @@ -200,3 +200,11 @@ test("test-needed and unsupported models are not given new artwork", () => { assert.equal(deviceImage(null, "VGN Dragonfly R1 Pro"), CDN + "unknown-device.png"); assert.equal(deviceImage(null, "Razer Viper 8KHz"), CDN + "unknown-device.png"); }); + +test("K-snake X11 wired and dongle share the same artwork", () => { + const wired = { vendorId: 0xa8a4, productId: 0x2255 } as HIDDevice; + const dongle = { vendorId: 0xa8a5, productId: 0x2255 } as HIDDevice; + assert.equal(deviceImage(wired), CDN + "ksnake-x11.png"); + assert.equal(deviceImage(dongle), CDN + "ksnake-x11.png"); + assert.equal(deviceImage(null, "K-snake X11"), CDN + "ksnake-x11.png"); +}); diff --git a/src/ui/device-images.ts b/src/ui/device-images.ts index fba11c1..a84a08e 100644 --- a/src/ui/device-images.ts +++ b/src/ui/device-images.ts @@ -123,6 +123,9 @@ const DEVICE_IMAGES: ReadonlyMap = new Map([ ["1532:00b8", "razer-viper-v3-hyperspeed.png"], ["1532:00e5", "razer-viper-v4-pro.png"], ["1532:00e6", "razer-viper-v4-pro.png"], + // K-snake X11 wired / 2.4 GHz dongle share the same shell. + ["a8a4:2255", "ksnake-x11.png"], + ["a8a5:2255", "ksnake-x11.png"], ]); function deviceKey(device: HIDDevice): string { @@ -183,6 +186,8 @@ function resolveDeviceImageFilename(device: HIDDevice | null | undefined, displa if (/\bsword\s*x\b/i.test(displayName)) return "wlmouse-sword-x.png"; if (/\bdragonfly\s*f2\b/i.test(displayName)) return "vgn-dragonfly-f2.png"; if (/\bmaya\s*x\b/i.test(displayName)) return "lamzu-maya-x.png"; + if (/\bk-snake\b/i.test(displayName)) return "ksnake-x11.png"; + if (/\bx11\b/i.test(displayName)) return "ksnake-x11.png"; if (/\bf1\s*v2\b/i.test(displayName)) return "atk-f1-v2-ultra-max.png"; if (/\b(finalmouse|starlight|ulx)\b/i.test(displayName)) return "finalmouse-ulx.png"; if (/\borbital\b/i.test(displayName)) return "unknown-device.png";