From 6892eeba42ab51dac25452e6975c57b170069d89 Mon Sep 17 00:00:00 2001 From: Siyuan Miao Date: Wed, 17 Sep 2025 18:41:47 +0200 Subject: [PATCH] chore: use dynamic duration for scheduleAutoRelease --- internal/usbgadget/hid_keyboard.go | 17 +++++++++--- internal/usbgadget/usbgadget.go | 42 ++++++++++++++++-------------- 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/internal/usbgadget/hid_keyboard.go b/internal/usbgadget/hid_keyboard.go index 37502190..8335966d 100644 --- a/internal/usbgadget/hid_keyboard.go +++ b/internal/usbgadget/hid_keyboard.go @@ -157,6 +157,9 @@ func (u *UsbGadget) SetOnKeepAliveReset(f func()) { u.onKeepAliveReset = &f } +// DefaultAutoReleaseDuration is the default duration for auto-release of a key. +const DefaultAutoReleaseDuration = 100 * time.Millisecond + func (u *UsbGadget) scheduleAutoRelease(key byte) { u.kbdAutoReleaseLock.Lock() defer unlockWithLog(&u.kbdAutoReleaseLock, u.log, "autoRelease scheduled") @@ -165,10 +168,14 @@ func (u *UsbGadget) scheduleAutoRelease(key byte) { u.kbdAutoReleaseTimers[key].Stop() } - // TODO: This shouldn't use the global autoReleaseKeyboardStartInterval - // but rather the baseExtension from the keepalive jitter compensation logic. - // Make them global as they will in the future likely be variable. - u.kbdAutoReleaseTimers[key] = time.AfterFunc(100*time.Millisecond, func() { + duration := u.kbdAutoReleaseTimerExtension + if duration == 0 { + duration = DefaultAutoReleaseDuration + } + + u.log.Debug().Dur("duration", duration).Msg("autoRelease scheduled with duration") + + u.kbdAutoReleaseTimers[key] = time.AfterFunc(duration, func() { u.performAutoRelease(key) }) } @@ -197,6 +204,8 @@ func (u *UsbGadget) DelayAutoReleaseWithDuration(resetDuration time.Duration) { return } + u.kbdAutoReleaseTimerExtension = resetDuration + u.log.Debug().Dur("reset_duration", resetDuration).Msg("delaying auto-release with dynamic duration") for _, timer := range u.kbdAutoReleaseTimers { diff --git a/internal/usbgadget/usbgadget.go b/internal/usbgadget/usbgadget.go index 17abd9eb..36d54a2c 100644 --- a/internal/usbgadget/usbgadget.go +++ b/internal/usbgadget/usbgadget.go @@ -68,8 +68,9 @@ type UsbGadget struct { keyboardState byte // keyboard latched state (NumLock, CapsLock, ScrollLock, Compose, Kana) keysDownState KeysDownState // keyboard dynamic state (modifier keys and pressed keys) - kbdAutoReleaseLock sync.Mutex - kbdAutoReleaseTimers map[byte]*time.Timer + kbdAutoReleaseLock sync.Mutex + kbdAutoReleaseTimers map[byte]*time.Timer + kbdAutoReleaseTimerExtension time.Duration keyboardStateLock sync.Mutex keyboardStateCtx context.Context @@ -122,24 +123,25 @@ func newUsbGadget(name string, configMap map[string]gadgetConfigItem, enabledDev keyboardCtx, keyboardCancel := context.WithCancel(context.Background()) g := &UsbGadget{ - name: name, - kvmGadgetPath: path.Join(gadgetPath, name), - configC1Path: path.Join(gadgetPath, name, "configs/c.1"), - configMap: configMap, - customConfig: *config, - configLock: sync.Mutex{}, - keyboardLock: sync.Mutex{}, - absMouseLock: sync.Mutex{}, - relMouseLock: sync.Mutex{}, - txLock: sync.Mutex{}, - keyboardStateCtx: keyboardCtx, - keyboardStateCancel: keyboardCancel, - keyboardState: 0, - keysDownState: KeysDownState{Modifier: 0, Keys: []byte{0, 0, 0, 0, 0, 0}}, // must be initialized to hidKeyBufferSize (6) zero bytes - kbdAutoReleaseTimers: make(map[byte]*time.Timer), - enabledDevices: *enabledDevices, - lastUserInput: time.Now(), - log: logger, + name: name, + kvmGadgetPath: path.Join(gadgetPath, name), + configC1Path: path.Join(gadgetPath, name, "configs/c.1"), + configMap: configMap, + customConfig: *config, + configLock: sync.Mutex{}, + keyboardLock: sync.Mutex{}, + absMouseLock: sync.Mutex{}, + relMouseLock: sync.Mutex{}, + txLock: sync.Mutex{}, + keyboardStateCtx: keyboardCtx, + keyboardStateCancel: keyboardCancel, + keyboardState: 0, + keysDownState: KeysDownState{Modifier: 0, Keys: []byte{0, 0, 0, 0, 0, 0}}, // must be initialized to hidKeyBufferSize (6) zero bytes + kbdAutoReleaseTimers: make(map[byte]*time.Timer), + kbdAutoReleaseTimerExtension: 0, + enabledDevices: *enabledDevices, + lastUserInput: time.Now(), + log: logger, strictMode: config.strictMode,