Skip to content

Commit

Permalink
fix: add 'disconnect' event for the webHID device
Browse files Browse the repository at this point in the history
  • Loading branch information
nytamin committed Aug 13, 2024
1 parent e9d925e commit 44179d3
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 0 deletions.
8 changes: 8 additions & 0 deletions packages/webhid-demo/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ async function openDevice(device: HIDDevice): Promise<void> {

appendLog(`Connected to "${xkeys.info.name}"`)

xkeys.on('disconnected', () => {
appendLog(`${xkeys.info.name} was disconnected`)
// Clean up stuff:
xkeys.removeAllListeners()
})
xkeys.on('error', (...errs) => {
appendLog('X-keys error:' + errs.join(','))
})
xkeys.on('down', (keyIndex: number) => {
appendLog(`Button ${keyIndex} down`)
xkeys.setBacklight(keyIndex, 'blue')
Expand Down
34 changes: 34 additions & 0 deletions packages/webhid/src/globalDisconnectListener.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export class GlobalDisconnectListener {
private static listeners = new Map<HIDDevice, () => void>()
private static isSetup = false

/** Add listener for disconnect event, for a HIDDevice. The callback will be fired once. */
static listenForDisconnect(device: HIDDevice, callback: () => void) {
this.setup()
this.listeners.set(device, callback)
}

private static setup() {
if (this.isSetup) return
navigator.hid.addEventListener('disconnect', this.handleDisconnect)
this.isSetup = true
}
private static handleDisconnect = (ev: HIDConnectionEvent) => {
this.listeners.forEach((callback, device) => {
if (device === ev.device) {
callback()
// Also remove the listener:
this.listeners.delete(device)
}
})
if (this.listeners.size === 0) {
// If there are not listeners, we can teardown the global listener:
this.teardown()
}
}
private static teardown() {
navigator.hid.removeEventListener('disconnect', this.handleDisconnect)
this.listeners.clear()
this.isSetup = false
}
}
6 changes: 6 additions & 0 deletions packages/webhid/src/methods.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { XKeys, XKEYS_VENDOR_ID } from '@xkeys-lib/core'
import { WebHIDDevice } from './web-hid-wrapper'
import { GlobalDisconnectListener } from './globalDisconnectListener'

/** Prompts the user for which X-keys panel to select */
export async function requestXkeysPanels(): Promise<HIDDevice[]> {
Expand Down Expand Up @@ -58,6 +59,11 @@ export async function setupXkeysPanel(browserDevice: HIDDevice): Promise<XKeys>
undefined
)

// Setup listener for disconnect:
GlobalDisconnectListener.listenForDisconnect(browserDevice, () => {
xkeys._handleDeviceDisconnected()
})

// Wait for the device to initialize:
try {
await xkeys.init()
Expand Down

0 comments on commit 44179d3

Please sign in to comment.