diff --git a/cloud.go b/cloud.go index 39b7683c..fb138508 100644 --- a/cloud.go +++ b/cloud.go @@ -476,7 +476,7 @@ func handleSessionRequest( cloudLogger.Info().Interface("session", session).Msg("new session accepted") cloudLogger.Trace().Interface("session", session).Msg("new session accepted") - // Cancel any ongoing keyboard report multi when session changes + // Cancel any ongoing keyboard macro when session changes cancelKeyboardMacro() currentSession = session diff --git a/hidrpc.go b/hidrpc.go index 055c07ad..7ed5f1c4 100644 --- a/hidrpc.go +++ b/hidrpc.go @@ -140,7 +140,7 @@ func reportHidRPC(params any, session *Session) { message, err = hidrpc.NewKeyboardLedMessage(params).Marshal() case usbgadget.KeysDownState: message, err = hidrpc.NewKeydownStateMessage(params).Marshal() - case hidrpc.KeyboardMacroStateReport: + case hidrpc.KeyboardMacroState: message, err = hidrpc.NewKeyboardMacroStateMessage(params.State, params.IsPaste).Marshal() default: err = fmt.Errorf("unknown HID RPC message type: %T", params) @@ -179,7 +179,7 @@ func (s *Session) reportHidRPCKeysDownState(state usbgadget.KeysDownState) { reportHidRPC(state, s) } -func (s *Session) reportHidRPCKeyboardMacroState(state hidrpc.KeyboardMacroStateReport) { +func (s *Session) reportHidRPCKeyboardMacroState(state hidrpc.KeyboardMacroState) { if !s.hidRPCAvailable { writeJSONRPCEvent("keyboardMacroState", state, s) } diff --git a/internal/hidrpc/hidrpc.go b/internal/hidrpc/hidrpc.go index dc49965a..5d02d9ec 100644 --- a/internal/hidrpc/hidrpc.go +++ b/internal/hidrpc/hidrpc.go @@ -20,7 +20,7 @@ const ( TypeCancelKeyboardMacroReport MessageType = 0x08 TypeKeyboardLedState MessageType = 0x32 TypeKeydownState MessageType = 0x33 - TypeKeyboardMacroStateReport MessageType = 0x34 + TypeKeyboardMacroState MessageType = 0x34 ) const ( @@ -32,7 +32,7 @@ func GetQueueIndex(messageType MessageType) int { switch messageType { case TypeHandshake: return 0 - case TypeKeyboardReport, TypeKeypressReport, TypeKeyboardMacroReport, TypeKeyboardLedState, TypeKeydownState, TypeKeyboardMacroStateReport: + case TypeKeyboardReport, TypeKeypressReport, TypeKeyboardMacroReport, TypeKeyboardLedState, TypeKeydownState, TypeKeyboardMacroState: return 1 case TypePointerReport, TypeMouseReport, TypeWheelReport: return 2 @@ -116,7 +116,7 @@ func NewKeyboardMacroStateMessage(state bool, isPaste bool) *Message { } return &Message{ - t: TypeKeyboardMacroStateReport, + t: TypeKeyboardMacroState, d: data, } } diff --git a/internal/hidrpc/message.go b/internal/hidrpc/message.go index 942382cb..d1cc9536 100644 --- a/internal/hidrpc/message.go +++ b/internal/hidrpc/message.go @@ -102,7 +102,8 @@ type KeyboardMacroReport struct { Steps []KeyboardMacroStep } -const hidKeyBufferSize = 6 +// HidKeyBufferSize is the size of the keys buffer in the keyboard report. +const HidKeyBufferSize = 6 // KeyboardMacroReport returns the keyboard macro report from the message. func (m *Message) KeyboardMacroReport() (KeyboardMacroReport, error) { @@ -128,7 +129,7 @@ func (m *Message) KeyboardMacroReport() (KeyboardMacroReport, error) { Delay: binary.BigEndian.Uint16(m.d[offset+7 : offset+9]), }) - offset += 1 + hidKeyBufferSize + 2 + offset += 1 + HidKeyBufferSize + 2 } return KeyboardMacroReport{ @@ -186,18 +187,18 @@ func (m *Message) MouseReport() (MouseReport, error) { }, nil } -type KeyboardMacroStateReport struct { +type KeyboardMacroState struct { State bool IsPaste bool } -// KeyboardMacroStateReport returns the keyboard macro state report from the message. -func (m *Message) KeyboardMacroStateReport() (KeyboardMacroStateReport, error) { - if m.t != TypeKeyboardMacroStateReport { - return KeyboardMacroStateReport{}, fmt.Errorf("invalid message type: %d", m.t) +// KeyboardMacroState returns the keyboard macro state report from the message. +func (m *Message) KeyboardMacroState() (KeyboardMacroState, error) { + if m.t != TypeKeyboardMacroState { + return KeyboardMacroState{}, fmt.Errorf("invalid message type: %d", m.t) } - return KeyboardMacroStateReport{ + return KeyboardMacroState{ State: m.d[0] == uint8(1), IsPaste: m.d[1] == uint8(1), }, nil diff --git a/jsonrpc.go b/jsonrpc.go index f65e6429..a445a277 100644 --- a/jsonrpc.go +++ b/jsonrpc.go @@ -1082,7 +1082,7 @@ func rpcExecuteKeyboardMacro(macro []hidrpc.KeyboardMacroStep) (usbgadget.KeysDo ctx, cancel := context.WithCancel(context.Background()) setKeyboardMacroCancel(cancel) - s := hidrpc.KeyboardMacroStateReport{ + s := hidrpc.KeyboardMacroState{ State: true, IsPaste: true, } @@ -1107,7 +1107,7 @@ func rpcCancelKeyboardMacro() { cancelKeyboardMacro() } -var keyboardClearStateKeys = make([]byte, 6) +var keyboardClearStateKeys = make([]byte, hidrpc.HidKeyBufferSize) func isClearKeyStep(step hidrpc.KeyboardMacroStep) bool { return step.Modifier == 0 && bytes.Equal(step.Keys, keyboardClearStateKeys) diff --git a/ui/src/components/InfoBar.tsx b/ui/src/components/InfoBar.tsx index 62759d17..ce444d85 100644 --- a/ui/src/components/InfoBar.tsx +++ b/ui/src/components/InfoBar.tsx @@ -27,7 +27,7 @@ export default function InfoBar() { const { rpcDataChannel } = useRTCStore(); const { debugMode, mouseMode, showPressedKeys } = useSettingsStore(); - const { isPasteModeEnabled } = useHidStore(); + const { isPasteInProgress } = useHidStore(); useEffect(() => { if (!rpcDataChannel) return; @@ -109,7 +109,7 @@ export default function InfoBar() { {rpcHidStatus} )} - {isPasteModeEnabled && ( + {isPasteInProgress && (
Paste Mode: Enabled diff --git a/ui/src/components/popovers/PasteModal.tsx b/ui/src/components/popovers/PasteModal.tsx index b96eb3e5..9f270527 100644 --- a/ui/src/components/popovers/PasteModal.tsx +++ b/ui/src/components/popovers/PasteModal.tsx @@ -17,7 +17,7 @@ import { TextAreaWithLabel } from "@components/TextArea"; export default function PasteModal() { const TextAreaRef = useRef(null); - const { isPasteModeEnabled } = useHidStore(); + const { isPasteInProgress } = useHidStore(); const { setDisableVideoFocusTrap } = useUiStore(); const { send } = useJsonRpc(); @@ -133,7 +133,8 @@ export default function PasteModal() {
e.stopPropagation()} - onKeyDown={e => e.stopPropagation()} + onKeyDown={e => e.stopPropagation()} onKeyDownCapture={e => e.stopPropagation()} + onKeyUpCapture={e => e.stopPropagation()} > diff --git a/ui/src/hooks/hidRpc.ts b/ui/src/hooks/hidRpc.ts index 26383f96..2606770d 100644 --- a/ui/src/hooks/hidRpc.ts +++ b/ui/src/hooks/hidRpc.ts @@ -1,4 +1,4 @@ -import { KeyboardLedState, KeysDownState } from "./stores"; +import { hidKeyBufferSize, KeyboardLedState, KeysDownState } from "./stores"; export const HID_RPC_MESSAGE_TYPES = { Handshake: 0x01, @@ -11,7 +11,7 @@ export const HID_RPC_MESSAGE_TYPES = { CancelKeyboardMacroReport: 0x08, KeyboardLedState: 0x32, KeysDownState: 0x33, - KeyboardMacroStateReport: 0x34, + KeyboardMacroState: 0x34, } export type HidRpcMessageType = typeof HID_RPC_MESSAGE_TYPES[keyof typeof HID_RPC_MESSAGE_TYPES]; @@ -31,7 +31,7 @@ const fromInt32toUint8 = (n: number) => { (n >> 24) & 0xFF, (n >> 16) & 0xFF, (n >> 8) & 0xFF, - (n >> 0) & 0xFF, + n & 0xFF, ]); }; @@ -42,7 +42,7 @@ const fromUint16toUint8 = (n: number) => { return new Uint8Array([ (n >> 8) & 0xFF, - (n >> 0) & 0xFF, + n & 0xFF, ]); }; @@ -55,7 +55,7 @@ const fromUint32toUint8 = (n: number) => { (n >> 24) & 0xFF, (n >> 16) & 0xFF, (n >> 8) & 0xFF, - (n >> 0) & 0xFF, + n & 0xFF, ]); }; @@ -64,7 +64,7 @@ const fromInt8ToUint8 = (n: number) => { throw new Error(`Number ${n} is not within the int8 range`); } - return (n >> 0) & 0xFF; + return n & 0xFF; }; const keyboardLedStateMasks = { @@ -222,7 +222,7 @@ export class KeyboardMacroReportMessage extends RpcMessage { stepCount: number; steps: KeyboardMacroStep[]; - KEYS_LENGTH = 6; + KEYS_LENGTH = hidKeyBufferSize; constructor(isPaste: boolean, stepCount: number, steps: KeyboardMacroStep[]) { super(HID_RPC_MESSAGE_TYPES.KeyboardMacroReport); @@ -284,7 +284,7 @@ export class KeyboardMacroStateMessage extends RpcMessage { isPaste: boolean; constructor(state: boolean, isPaste: boolean) { - super(HID_RPC_MESSAGE_TYPES.KeyboardMacroStateReport); + super(HID_RPC_MESSAGE_TYPES.KeyboardMacroState); this.state = state; this.isPaste = isPaste; } @@ -417,7 +417,7 @@ export const messageRegistry = { [HID_RPC_MESSAGE_TYPES.KeypressReport]: KeypressReportMessage, [HID_RPC_MESSAGE_TYPES.KeyboardMacroReport]: KeyboardMacroReportMessage, [HID_RPC_MESSAGE_TYPES.CancelKeyboardMacroReport]: CancelKeyboardMacroReportMessage, - [HID_RPC_MESSAGE_TYPES.KeyboardMacroStateReport]: KeyboardMacroStateMessage, + [HID_RPC_MESSAGE_TYPES.KeyboardMacroState]: KeyboardMacroStateMessage, } export const unmarshalHidRpcMessage = (data: Uint8Array): RpcMessage | undefined => { diff --git a/ui/src/hooks/stores.ts b/ui/src/hooks/stores.ts index 9ec961e8..bb4b8dd1 100644 --- a/ui/src/hooks/stores.ts +++ b/ui/src/hooks/stores.ts @@ -470,7 +470,7 @@ export interface HidState { isVirtualKeyboardEnabled: boolean; setVirtualKeyboardEnabled: (enabled: boolean) => void; - isPasteModeEnabled: boolean; + isPasteInProgress: boolean; setPasteModeEnabled: (enabled: boolean) => void; usbState: USBStates; @@ -487,8 +487,8 @@ export const useHidStore = create(set => ({ isVirtualKeyboardEnabled: false, setVirtualKeyboardEnabled: (enabled: boolean): void => set({ isVirtualKeyboardEnabled: enabled }), - isPasteModeEnabled: false, - setPasteModeEnabled: (enabled: boolean): void => set({ isPasteModeEnabled: enabled }), + isPasteInProgress: false, + setPasteModeEnabled: (enabled: boolean): void => set({ isPasteInProgress: enabled }), // Add these new properties for USB state usbState: "not attached",