diff --git a/package-lock.json b/package-lock.json index 7ab1367d..0d53e21a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "2.0.0", "license": "AGPL-3.0-or-later", "dependencies": { - "@openmouse/protocol": "0.29.0", + "@openmouse/protocol": "0.30.0", "lucide-react": "^1.43.0", "preact": "^10.29.8" }, @@ -481,9 +481,9 @@ } }, "node_modules/@openmouse/protocol": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/@openmouse/protocol/-/protocol-0.29.0.tgz", - "integrity": "sha512-0YcCdBZigRZlfJgVWxe9iGUQChilgUX/9J3lwHACRJ9goGQVw16IRW7DnSQ5R93NaMxVTMaOCIiloCGDbGR1Kw==", + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/@openmouse/protocol/-/protocol-0.30.0.tgz", + "integrity": "sha512-gIRoMJF3y0qzXPut8sRTvg/4pmOP0EQG2DwtD4aHZL5iPT76IzDC0fI45902yFVTDRfpzrOo4VCCfP+XXMd2cA==", "license": "AGPL-3.0-or-later", "engines": { "node": ">=20" diff --git a/package.json b/package.json index 9d30af44..b70d791b 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "preview": "vite preview" }, "dependencies": { - "@openmouse/protocol": "0.29.0", + "@openmouse/protocol": "0.30.0", "lucide-react": "^1.43.0", "preact": "^10.29.8" }, diff --git a/src/app/cards/availability.test.ts b/src/app/cards/availability.test.ts index 4835206b..3894c0c4 100644 --- a/src/app/cards/availability.test.ts +++ b/src/app/cards/availability.test.ts @@ -596,3 +596,28 @@ test("the Incott card follows the fields the device reported, not a brand trait" })); assert.equal(silent.incott, false); }); + +test("the Glorious Model O2 Pro 4K/8K opens debounce, Motion Sync and the profile card, but not sleep or signal", () => { + const cards = cardAvailability(snapshot({ + status: { + brand: "Glorious", + ui: { + family: "glorious-core2", + showAdvancedSection: true, + hideAngleSnapping: true, + hideRippleControl: true, + hideSleepCard: true, + hideSignalCard: true, + }, + debounceMs: 10, + motionSync: true, + activeProfile: 1, + profileCount: 3, + }, + })); + assert.equal(cards.debounce, true); + assert.equal(cards.processing, true); + assert.equal(cards.onboardProfiles, true); + assert.equal(cards.sleep, false); + assert.equal(cards.signal, false); +}); diff --git a/src/device/controller.ts b/src/device/controller.ts index f8938399..b737e76a 100644 --- a/src/device/controller.ts +++ b/src/device/controller.ts @@ -162,6 +162,7 @@ import { Keychron8kNordicHidClient } from "@openmouse/protocol/drivers/keychron/ import type { GloriousLighting } from "@openmouse/protocol/glorious"; import { GloriousHidClient } from "@openmouse/protocol/drivers/glorious/hid"; import { GloriousClassicHidClient } from "@openmouse/protocol/drivers/glorious/classic-hid"; +import { GloriousCore2HidClient } from "@openmouse/protocol/drivers/glorious/core2-hid"; import { MchoseHidClient } from "@openmouse/protocol/drivers/mchose/hid"; import { MchoseDockHidClient } from "@openmouse/protocol/drivers/mchose/dock-hid"; import { MchoseA5ProMaxHidClient } from "@openmouse/protocol/drivers/mchose/a5-gen1-hid"; @@ -270,7 +271,7 @@ function activeAs(...classes: ClientClass[]): T | null { const DM_CLASSES = [WLMouseHidClient, LamzuHidClient, LamzuAtlantisHidClient, AtkHidClient, AtkBitmouseHidClient, NinjutsoHidClient] as const; const RAZER_CLASSES = [RazerHidClient, RazerViperMiniHidClient, RazerViperHidClient, RazerCobraHidClient] as const; -const NEEDS_OPEN = [LamzuAtlantisHidClient, TeevolutionHidClient, VgnF2HidClient, KeychronNapeHidClient, Keychron8kNordicHidClient, WLMouseBeastX4kHidClient, ModdoHidClient, ZaunkoenigHidClient, CorsairHidClient, CorsairBragiHidClient, FantechHidClient, WallhackMouseHidClient, WallhackKeyboardHidClient, GloriousHidClient, GloriousClassicHidClient, MchoseHidClient, MchoseDockHidClient, MchoseA5ProMaxHidClient, MchoseV3HidClient, MicrosoftHidClient, DareuHidClient, IncottHidClient, BytechHidClient, RapooHidClient, FaterHidClient, CoolerMasterHidClient, RedragonM690ProHidClient, AjazzHidClient] as const; +const NEEDS_OPEN = [LamzuAtlantisHidClient, TeevolutionHidClient, VgnF2HidClient, KeychronNapeHidClient, Keychron8kNordicHidClient, WLMouseBeastX4kHidClient, ModdoHidClient, ZaunkoenigHidClient, CorsairHidClient, CorsairBragiHidClient, FantechHidClient, WallhackMouseHidClient, WallhackKeyboardHidClient, GloriousHidClient, GloriousClassicHidClient, GloriousCore2HidClient, MchoseHidClient, MchoseDockHidClient, MchoseA5ProMaxHidClient, MchoseV3HidClient, MicrosoftHidClient, DareuHidClient, IncottHidClient, BytechHidClient, RapooHidClient, FaterHidClient, CoolerMasterHidClient, RedragonM690ProHidClient, AjazzHidClient] as const; const PULSAR_CLASSES = [PulsarHidClient, PulsarProHidClient, PulsarXs1HidClient] as const; const logitechClient = (): LogitechHidppClient | null => activeAs(LogitechHidppClient); diff --git a/src/device/traits.ts b/src/device/traits.ts index 35cc25a7..a2c07c80 100644 --- a/src/device/traits.ts +++ b/src/device/traits.ts @@ -79,6 +79,9 @@ const BY_FAMILY: Readonly>> = { // it publishes its own sleep and debounce option lists. "mchose-v3": { advancedSection: true, sleep: true, debounce: true }, dareu: { advancedSection: true, sleep: true }, + // The Model O2 Pro 4K/8K writes a debounce block and a motion sync flag; it + // has no sleep command wired in, so no sleep flag. + "glorious-core2": { advancedSection: true, debounce: true }, // Incott supports a 0-30 ms debounce and a 1-900 s sleep timer over its own // vendor protocol, not the CompX direct-mode transport, so it takes the // plain flags rather than DIRECT_MODE (its advancedSection already comes diff --git a/src/supported-devices-data.ts b/src/supported-devices-data.ts index 1c6e7e4a..5e6cd181 100644 --- a/src/supported-devices-data.ts +++ b/src/supported-devices-data.ts @@ -231,7 +231,7 @@ export const SUPPORTED_DEVICES: readonly SupportedDeviceEntry[] = [ { brand: "Glorious", model: "Model O", status: "supported", pids: [0x2011, 0x2022] }, { brand: "Glorious", model: "Model D Wireless", status: "supported", pids: [0x2012, 0x2023] }, { brand: "Glorious", model: "Model D", status: "supported", pids: [0x2012] }, - { brand: "Glorious", model: "Model O2 Pro 4K/8K", status: "likely", pids: [0x201b, 0x2035] }, + { brand: "Glorious", model: "Model O2 Pro 4K/8K", status: "pr", pids: [0x201b, 0x2035] }, { brand: "Glorious", model: "Model O Pro", status: "supported", pids: [0x2015, 0x2027] }, { brand: "Glorious", model: "Model D2 Pro Wireless 8K", status: "likely", pids: [0x201c, 0x2036] }, { brand: "Glorious", model: "Model O3 Wireless", status: "likely", pids: [0xa312, 0xa300] },