Skip to content

Commit 937b6d3

Browse files
committed
Code rabbit fixes
1 parent 8b273ed commit 937b6d3

22 files changed

Lines changed: 233 additions & 184 deletions

src/hooks/useCaptureProvider.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ export function useCaptureProvider(wsRef: React.RefObject<WebSocket | null>) {
102102
}
103103

104104
const video = videoRef.current
105+
const track = stream.getVideoTracks()[0]
106+
const settings = track.getSettings()
105107
video.srcObject = stream
106108
await video.play()
107109

@@ -110,7 +112,14 @@ export function useCaptureProvider(wsRef: React.RefObject<WebSocket | null>) {
110112

111113
if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) {
112114
wsRef.current.send(
113-
JSON.stringify({ type: "start-provider", config: getConfig() }),
115+
JSON.stringify({
116+
type: "start-provider",
117+
config: {
118+
...getConfig(),
119+
screenWidth: settings.width,
120+
screenHeight: settings.height,
121+
},
122+
}),
114123
)
115124
}
116125

src/server/InputHandler.ts

Lines changed: 20 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -7,69 +7,23 @@
77
* mouse, keyboard, touch, clipboard, and gesture interactions.
88
*/
99
import os from "node:os"
10-
import path from "node:path"
1110
import { applyMotion } from "./drivers/utils"
12-
import { WindowsInputInjector } from "./drivers/windows/index"
13-
export interface InputMessage {
14-
type:
15-
| "move"
16-
| "paste"
17-
| "copy"
18-
| "click"
19-
| "scroll"
20-
| "key"
21-
| "text"
22-
| "zoom"
23-
| "combo"
24-
| "touch"
25-
| "update-settings"
26-
dx?: number
27-
dy?: number
28-
config?: Partial<InputConfig>
29-
button?: "left" | "right" | "middle"
30-
press?: boolean
31-
key?: string
32-
keys?: string[]
33-
text?: string
34-
delta?: number
35-
contacts?: Array<{
36-
id: number
37-
x: number
38-
y: number
39-
state: "down" | "move" | "up"
40-
}>
41-
}
42-
43-
export interface InputConfig {
44-
sensitivity: number
45-
invertScroll: boolean
46-
acceleration: boolean
47-
}
48-
49-
type PlatformInjector = {
50-
updateConfig(config: Partial<InputConfig>): void
51-
injectMouseMove(dx: number, dy: number): void
52-
injectMouseButton(button: "left" | "right" | "middle", isDown: boolean): void
53-
injectMouseWheel(dx: number, dy: number): void
54-
injectKey(key: string): void
55-
injectCombo(keys: string[]): void
56-
injectText(text: string): void
57-
injectTouch(contacts: NonNullable<InputMessage["contacts"]>): void
58-
destroy(): void
59-
}
11+
import {
12+
DEFAULT_SCREEN_HEIGHT,
13+
DEFAULT_SCREEN_WIDTH,
14+
MAX_TEXT_LENGTH,
15+
MAX_COMBO_KEYS,
16+
MAX_COORD,
17+
MAX_KEY_LENGTH,
18+
} from "./constants.ts"
19+
import type { InputConfig, InputMessage, PlatformInjector } from "./types.ts"
6020

6121
const VALID_BUTTONS = ["left", "right", "middle"] as const
6222
type MouseButton = (typeof VALID_BUTTONS)[number]
6323

64-
const MAX_COORD = 2000
65-
const MAX_TEXT_LENGTH = 500
66-
const MAX_COMBO_KEYS = 10
67-
const MAX_KEY_LENGTH = 50
68-
6924
export class InputHandler {
7025
private injector: PlatformInjector
7126
private platform: "win32" | "linux" | "darwin" | "other"
72-
7327
private lastMoveTime = 0
7428
private lastScrollTime = 0
7529
private pendingMove: InputMessage | null = null
@@ -82,6 +36,8 @@ export class InputHandler {
8236
sensitivity: 1.0,
8337
invertScroll: false,
8438
acceleration: true,
39+
screenWidth: DEFAULT_SCREEN_WIDTH,
40+
screenHeight: DEFAULT_SCREEN_HEIGHT,
8541
}
8642

8743
constructor(config: Partial<InputConfig> = {}, throttleMs = 8) {
@@ -92,22 +48,15 @@ export class InputHandler {
9248

9349
if (plat === "win32") {
9450
this.platform = "win32"
51+
const { WindowsInputInjector } = require("./drivers/windows")
9552
this.injector = new WindowsInputInjector(this.config) as PlatformInjector
9653
} else if (plat === "linux") {
9754
this.platform = "linux"
98-
const linuxPath = path.join(
99-
process.cwd(),
100-
"src/server/drivers/linux/index.ts",
101-
)
102-
const { LinuxInputInjector } = require(linuxPath)
55+
const { LinuxInputInjector } = require("./drivers/linux")
10356
this.injector = new LinuxInputInjector(this.config) as PlatformInjector
10457
} else if (plat === "darwin") {
10558
this.platform = "darwin"
106-
const macPath = path.join(
107-
process.cwd(),
108-
"src/server/drivers/mac/index.ts",
109-
)
110-
const { MacInputInjector } = require(macPath)
59+
const { MacInputInjector } = require("./drivers/mac")
11160
this.injector = new MacInputInjector(this.config) as PlatformInjector
11261
} else {
11362
this.platform = "other"
@@ -293,7 +242,12 @@ export class InputHandler {
293242
}
294243

295244
case "text": {
296-
if (!msg.text || typeof msg.text !== "string") break
245+
if (
246+
!msg.text ||
247+
typeof msg.text !== "string" ||
248+
msg.text.length > MAX_TEXT_LENGTH
249+
)
250+
break
297251
this.injector.injectText(msg.text)
298252
break
299253
}

src/server/constants.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import type { InputConfig } from "./types.ts"
2+
3+
export const INPUT_MOUSE = 0
4+
export const INPUT_KEYBOARD = 1
5+
export const DEFAULT_SCREEN_WIDTH = 1920
6+
export const DEFAULT_SCREEN_HEIGHT = 1080
7+
export const WHEEL_SCALE = 3
8+
export const PINCH_PAN_THRESHOLD = 2
9+
export const DEFAULT_CONFIG: InputConfig = {
10+
sensitivity: 1.0,
11+
invertScroll: false,
12+
acceleration: true,
13+
screenWidth: DEFAULT_SCREEN_WIDTH,
14+
screenHeight: DEFAULT_SCREEN_HEIGHT,
15+
}
16+
export const MAX_TEXT_LENGTH = 10000
17+
export const MAX_COORD = 2000
18+
export const MAX_COMBO_KEYS = 10
19+
export const MAX_KEY_LENGTH = 50
20+
21+
//used by utils for applying motion
22+
export const ACCEL_THRESHOLD = 1
23+
export const ACCEL_FACTOR = 0.8
24+
export const ACCEL_EXPONENT = 1.2

src/server/drivers/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,4 @@ Implements input injection using **SendInput** and the **Synthetic Pointer API**
5151
* Text injection
5252
* Multi-touch input
5353
* Pinch and zoom gestures
54-
* Clipboard shortcuts (copy/paste)
54+
* Clipboard shortcuts (copy/paste)

src/server/drivers/constants.ts

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/server/drivers/keyMap.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,6 @@ export const MAC_KEY_MAP: Record<string, number> = {
212212
fn: 0x3f,
213213
capslock: 0x39,
214214

215-
216215
f1: 0x7a,
217216
f2: 0x78,
218217
f3: 0x63,
@@ -234,7 +233,6 @@ export const MAC_KEY_MAP: Record<string, number> = {
234233
f19: 0x50,
235234
f20: 0x5a,
236235

237-
238236
arrowup: 0x7e,
239237
arrowdown: 0x7d,
240238
arrowleft: 0x7b,
@@ -243,11 +241,10 @@ export const MAC_KEY_MAP: Record<string, number> = {
243241
end: 0x77,
244242
pageup: 0x74,
245243
pagedown: 0x79,
246-
insert: 0x72,
244+
insert: 0x72,
247245
delete: 0x75,
248246
forwarddelete: 0x75,
249247

250-
251248
backspace: 0x33,
252249
tab: 0x30,
253250
enter: 0x24,

src/server/drivers/linux/index.ts

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,13 @@ import {
5454
KEY_PRESS,
5555
KEY_RELEASE,
5656
} from "./constants.ts"
57-
import {
58-
DEFAULT_SCREEN_WIDTH,
59-
DEFAULT_SCREEN_HEIGHT,
60-
WHEEL_SCALE,
61-
} from "../constants.ts"
57+
import { WHEEL_SCALE } from "../../constants.ts"
6258
import { LinuxKeyboard } from "./keyboard.ts"
6359
import { LinuxTouch } from "./touch.ts"
6460
import { LINUX_KEY_MAP } from "../keyMap.ts"
65-
import type { InputConfig, TouchContact } from "../types.ts"
66-
import { DEFAULT_CONFIG } from "../constants.ts"
61+
import type { InputConfig, TouchContact } from "../../types.ts"
62+
import { DEFAULT_CONFIG } from "../../constants.ts"
6763

68-
if (process.platform !== "linux") {
69-
throw new Error("LinuxInputInjector can only be used on Linux")
70-
}
7164
const BUS_USB = 0x03
7265

7366
class UinputDevice {
@@ -170,11 +163,12 @@ export class LinuxInputInjector {
170163
private touchDev = new UinputDevice("Touch")
171164
private keyboard: LinuxKeyboard | null = null
172165
private touch: LinuxTouch | null = null
173-
private screenWidth = DEFAULT_SCREEN_WIDTH
174-
private screenHeight = DEFAULT_SCREEN_HEIGHT
175166
private initialized = false
176167

177168
constructor(config: Partial<InputConfig> = {}) {
169+
if (process.platform !== "linux") {
170+
throw new Error("LinuxInputInjector can only be used on Linux")
171+
}
178172
this.config = { ...DEFAULT_CONFIG, ...config }
179173
this.initialize()
180174
}
@@ -336,12 +330,12 @@ export class LinuxInputInjector {
336330
// Abs ranges
337331
this.touchDev.setupAbs(ABS_MT_SLOT, 0, MAX_CONTACTS - 1)
338332
this.touchDev.setupAbs(ABS_MT_TRACKING_ID, -1, 0x7fffffff)
339-
this.touchDev.setupAbs(ABS_MT_POSITION_X, 0, this.screenWidth)
340-
this.touchDev.setupAbs(ABS_MT_POSITION_Y, 0, this.screenHeight)
333+
this.touchDev.setupAbs(ABS_MT_POSITION_X, 0, this.config.screenWidth)
334+
this.touchDev.setupAbs(ABS_MT_POSITION_Y, 0, this.config.screenHeight)
341335
this.touchDev.setupAbs(ABS_MT_TOUCH_MAJOR, 0, 255)
342336
this.touchDev.setupAbs(ABS_MT_PRESSURE, 0, 255)
343-
this.touchDev.setupAbs(ABS_X, 0, this.screenWidth)
344-
this.touchDev.setupAbs(ABS_Y, 0, this.screenHeight)
337+
this.touchDev.setupAbs(ABS_X, 0, this.config.screenWidth)
338+
this.touchDev.setupAbs(ABS_Y, 0, this.config.screenHeight)
345339

346340
return this.touchDev.create("Virtual Touchpad")
347341
}

src/server/drivers/linux/keyboard.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,21 @@ export class LinuxKeyboard {
7171
}
7272

7373
if (shifted) {
74+
const shiftCode = LINUX_KEY_MAP.shift
75+
if (shiftCode === undefined) {
76+
console.warn("[LinuxKeyboard] Shift key code not defined in key map")
77+
continue
78+
}
7479
this.sendKeyEvent(LINUX_KEY_MAP.shift ?? 0, KEY_PRESS)
7580
}
7681
this.sendKeyEvent(code, KEY_PRESS)
7782
this.sendKeyEvent(code, KEY_RELEASE)
7883
if (shifted) {
84+
const shiftCode = LINUX_KEY_MAP.shift
85+
if (shiftCode === undefined) {
86+
console.warn("[LinuxKeyboard] Shift key code not defined in key map")
87+
continue
88+
}
7989
this.sendKeyEvent(LINUX_KEY_MAP.shift ?? 0, KEY_RELEASE)
8090
}
8191
this.sync()

src/server/drivers/linux/structs.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,11 @@ export function openUinput(path: string): number {
6666
if (!_open) {
6767
throw new Error("libc not initialized")
6868
}
69-
return _open(path, O_WRONLY | O_NONBLOCK) as number
69+
const fd = _open(path, O_WRONLY | O_NONBLOCK) as number
70+
if (fd < 0) {
71+
throw new Error(`Failed to open ${path}, got fd ${fd} (check permissions and /dev/uinput availability)`)
72+
}
73+
return fd
7074
}
7175

7276
export function closeUinput(fd: number): void {
@@ -91,7 +95,10 @@ export function writeEvent(
9195
const written = _write(fd, ev, INPUT_EVENT_SIZE) as number
9296
return written === INPUT_EVENT_SIZE
9397
}
94-
98+
/**
99+
* Perform an ioctl call with an integer argument.
100+
* `@returns` 0 on success, -1 on error (check errno via native means if needed)
101+
*/
95102
export function ioctlInt(fd: number, request: number, value: number): number {
96103
ensureLibc()
97104
if (!_ioctl) {

src/server/drivers/linux/touch.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ import {
2727
MAX_CONTACTS,
2828
MT_TRACKING_ID_RELEASED,
2929
} from "./constants.ts"
30-
import type { TouchContact } from "../types.ts"
30+
import type { TouchContact } from "../../types.ts"
3131

3232
export class LinuxTouch {
3333
private fd: number
34-
// slot :tracking id
34+
// slot :tracking id
3535
private slotTrackingIds: Int32Array
3636
// sourceId :slot index
3737
private contactSlotMap = new Map<number, number>()

0 commit comments

Comments
 (0)