mirror of https://github.com/jetkvm/kvm.git
Merge eb22ff2ab9 into 703625d59a
This commit is contained in:
commit
d1885d2625
10
hidrpc.go
10
hidrpc.go
|
|
@ -65,15 +65,17 @@ func handleHidRPCMessage(message hidrpc.Message, session *Session) {
|
||||||
|
|
||||||
func onHidMessage(msg hidQueueMessage, session *Session) {
|
func onHidMessage(msg hidQueueMessage, session *Session) {
|
||||||
data := msg.Data
|
data := msg.Data
|
||||||
|
dataLen := len(data)
|
||||||
|
|
||||||
scopedLogger := hidRPCLogger.With().
|
scopedLogger := hidRPCLogger.With().
|
||||||
Str("channel", msg.channel).
|
Str("channel", msg.channel).
|
||||||
Bytes("data", data).
|
Int("data_len", dataLen).
|
||||||
|
Bytes("data", data[:min(dataLen, 32)]).
|
||||||
Logger()
|
Logger()
|
||||||
scopedLogger.Debug().Msg("HID RPC message received")
|
scopedLogger.Debug().Msg("HID RPC message received")
|
||||||
|
|
||||||
if len(data) < 1 {
|
if dataLen < 1 {
|
||||||
scopedLogger.Warn().Int("length", len(data)).Msg("received empty data in HID RPC message handler")
|
scopedLogger.Warn().Msg("received empty data in HID RPC message handler")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,7 +98,7 @@ func onHidMessage(msg hidQueueMessage, session *Session) {
|
||||||
r <- nil
|
r <- nil
|
||||||
}()
|
}()
|
||||||
select {
|
select {
|
||||||
case <-time.After(1 * time.Second):
|
case <-time.After(30 * time.Second):
|
||||||
scopedLogger.Warn().Msg("HID RPC message timed out")
|
scopedLogger.Warn().Msg("HID RPC message timed out")
|
||||||
case <-r:
|
case <-r:
|
||||||
scopedLogger.Debug().Dur("duration", time.Since(t)).Msg("HID RPC message handled")
|
scopedLogger.Debug().Dur("duration", time.Since(t)).Msg("HID RPC message handled")
|
||||||
|
|
|
||||||
|
|
@ -153,6 +153,16 @@ func (u *UsbGadget) SetOnKeysDownChange(f func(state KeysDownState)) {
|
||||||
u.onKeysDownChange = &f
|
u.onKeysDownChange = &f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var suspendedKeyDownMessages bool = false
|
||||||
|
|
||||||
|
func (u *UsbGadget) SuspendKeyDownMessages() {
|
||||||
|
suspendedKeyDownMessages = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UsbGadget) ResumeSuspendKeyDownMessages() {
|
||||||
|
suspendedKeyDownMessages = false
|
||||||
|
}
|
||||||
|
|
||||||
func (u *UsbGadget) SetOnKeepAliveReset(f func()) {
|
func (u *UsbGadget) SetOnKeepAliveReset(f func()) {
|
||||||
u.onKeepAliveReset = &f
|
u.onKeepAliveReset = &f
|
||||||
}
|
}
|
||||||
|
|
@ -169,9 +179,9 @@ func (u *UsbGadget) scheduleAutoRelease(key byte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: make this configurable
|
// TODO: make this configurable
|
||||||
// We currently hardcode the duration to 100ms
|
// We currently hardcode the duration to the default of 100ms
|
||||||
// However, it should be the same as the duration of the keep-alive reset called baseExtension.
|
// However, it should be the same as the duration of the keep-alive reset called baseExtension.
|
||||||
u.kbdAutoReleaseTimers[key] = time.AfterFunc(100*time.Millisecond, func() {
|
u.kbdAutoReleaseTimers[key] = time.AfterFunc(DefaultAutoReleaseDuration, func() {
|
||||||
u.performAutoRelease(key)
|
u.performAutoRelease(key)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -353,7 +363,7 @@ func (u *UsbGadget) UpdateKeysDown(modifier byte, keys []byte) KeysDownState {
|
||||||
u.keysDownState = state
|
u.keysDownState = state
|
||||||
u.keyboardStateLock.Unlock()
|
u.keyboardStateLock.Unlock()
|
||||||
|
|
||||||
if u.onKeysDownChange != nil {
|
if u.onKeysDownChange != nil && !suspendedKeyDownMessages {
|
||||||
(*u.onKeysDownChange)(state) // this enques to the outgoing hidrpc queue via usb.go → currentSession.enqueueKeysDownState(...)
|
(*u.onKeysDownChange)(state) // this enques to the outgoing hidrpc queue via usb.go → currentSession.enqueueKeysDownState(...)
|
||||||
}
|
}
|
||||||
return state
|
return state
|
||||||
|
|
|
||||||
|
|
@ -1132,7 +1132,11 @@ func isClearKeyStep(step hidrpc.KeyboardMacroStep) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func rpcDoExecuteKeyboardMacro(ctx context.Context, macro []hidrpc.KeyboardMacroStep) error {
|
func rpcDoExecuteKeyboardMacro(ctx context.Context, macro []hidrpc.KeyboardMacroStep) error {
|
||||||
logger.Debug().Interface("macro", macro).Msg("Executing keyboard macro")
|
logger.Debug().Int("macro_steps", len(macro)).Msg("Executing keyboard macro")
|
||||||
|
|
||||||
|
// don't report keyboard state changes while executing the macro
|
||||||
|
gadget.SuspendKeyDownMessages()
|
||||||
|
defer gadget.ResumeSuspendKeyDownMessages()
|
||||||
|
|
||||||
for i, step := range macro {
|
for i, step := range macro {
|
||||||
delay := time.Duration(step.Delay) * time.Millisecond
|
delay := time.Duration(step.Delay) * time.Millisecond
|
||||||
|
|
@ -1153,7 +1157,8 @@ func rpcDoExecuteKeyboardMacro(ctx context.Context, macro []hidrpc.KeyboardMacro
|
||||||
case <-time.After(delay):
|
case <-time.After(delay):
|
||||||
// Sleep completed normally
|
// Sleep completed normally
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
// make sure keyboard state is reset
|
// make sure keyboard state is reset and the client gets notified
|
||||||
|
gadget.ResumeSuspendKeyDownMessages()
|
||||||
err := rpcKeyboardReport(0, keyboardClearStateKeys)
|
err := rpcKeyboardReport(0, keyboardClearStateKeys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Warn().Err(err).Msg("failed to reset keyboard state")
|
logger.Warn().Err(err).Msg("failed to reset keyboard state")
|
||||||
|
|
|
||||||
|
|
@ -188,18 +188,18 @@ export default function PasteModal() {
|
||||||
type="number"
|
type="number"
|
||||||
label="Delay between keys"
|
label="Delay between keys"
|
||||||
placeholder="Delay between keys"
|
placeholder="Delay between keys"
|
||||||
min={50}
|
min={0}
|
||||||
max={65534}
|
max={65534}
|
||||||
value={delayValue}
|
value={delayValue}
|
||||||
onChange={e => {
|
onChange={e => {
|
||||||
setDelayValue(parseInt(e.target.value, 10));
|
setDelayValue(parseInt(e.target.value, 10));
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{delayValue < 50 || delayValue > 65534 && (
|
{delayValue < defaultDelay || delayValue > 65534 && (
|
||||||
<div className="mt-2 flex items-center gap-x-2">
|
<div className="mt-2 flex items-center gap-x-2">
|
||||||
<ExclamationCircleIcon className="h-4 w-4 text-red-500 dark:text-red-400" />
|
<ExclamationCircleIcon className="h-4 w-4 text-red-500 dark:text-red-400" />
|
||||||
<span className="text-xs text-red-500 dark:text-red-400">
|
<span className="text-xs text-red-500 dark:text-red-400">
|
||||||
Delay must be between 50 and 65534
|
Delay should be between 20 and 65534
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue