Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions src/routes/trackpad.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,28 @@ function TrackpadPage() {
setTimeout(() => send({ type: "click", button, press: false }), 50)
}

const handleCopy = () => {
send({ type: "copy" })
const handleCopy = async () => {
try {
let text = ""

if (navigator.clipboard && window.isSecureContext) {
text = await navigator.clipboard.readText()
} else {
// fallback → use selected text
text = window.getSelection()?.toString() || ""
}

send({
type: "clipboard-push",
text,
})
} catch (err) {
console.error("Copy failed", err)
}
}

const handlePaste = async () => {
send({ type: "paste" })
send({ type: "clipboard-pull" })
}

const handleInput = (e: React.ChangeEvent<HTMLInputElement>) => {
Expand Down
37 changes: 36 additions & 1 deletion src/server/InputHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export interface InputMessage {
| "move"
| "paste"
| "copy"
| "clipboard-push"
| "clipboard-pull"
| "click"
| "scroll"
| "key"
Expand All @@ -34,7 +36,10 @@ export class InputHandler {
private throttleMs: number
private modifier: Key

constructor(throttleMs = 8) {
constructor(
private sendToClient: (msg: any) => void,
throttleMs = 8
) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Verify all InputHandler constructor call sites
rg -nP --type=ts 'new\s+InputHandler\s*\(' src/server

# Verify explicit-any usage in constructor callback typing
rg -nP --type=ts '\(\s*msg\s*:\s*any\s*\)\s*=>\s*void' src/server/InputHandler.ts

Repository: AOSSIE-Org/Rein

Length of output: 187


🏁 Script executed:

# Find all InputHandler instantiation sites
rg -nP --type=ts 'new\s+InputHandler' src/server

# Find clipboard-pull references to understand potential failures
rg -nP --type=ts 'clipboard-pull' src/server

# Check the full InputHandler class to understand the constructor and usage
head -60 src/server/InputHandler.ts

Repository: AOSSIE-Org/Rein

Length of output: 1709


🏁 Script executed:

# Get full context around the InputHandler instantiation in websocket.ts
sed -n '40,70p' src/server/websocket.ts

# Check if the clipboard-pull handler uses sendToClient
sed -n '212,230p' src/server/InputHandler.ts

# Verify the type signature of sendToClient and how it's used
rg -nP --type=ts 'this\.sendToClient' src/server/InputHandler.ts | head -20

Repository: AOSSIE-Org/Rein

Length of output: 1717


🏁 Script executed:

# Check if there are any other InputHandler instantiations we might have missed
rg -nP --type=ts 'InputHandler' src/server --type-list | grep -v node_modules

# Verify the exact error that would occur by checking how clipboard-pull calls sendToClient
sed -n '212,240p' src/server/InputHandler.ts

Repository: AOSSIE-Org/Rein

Length of output: 1449


Fix constructor signature mismatch—InputHandler instantiation in src/server/websocket.ts will fail at runtime.

The constructor at lines 39-42 now requires a callback function as the first parameter (sendToClient), but src/server/websocket.ts:50 instantiates it with only new InputHandler(inputThrottleMs), passing a number as the first argument. This causes this.sendToClient to be a number instead of a function. When the clipboard-pull handler at line 227 calls this.sendToClient(...), it will throw a runtime error (TypeError: this.sendToClient is not a function).

Additionally, replace the any type for the msg parameter with an explicit type based on the InputMessage interface to comply with coding guidelines.

🧰 Tools
🪛 GitHub Actions: CI

[error] 39-41: no-explicit-any: Unexpected any. Specify a different type.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/server/InputHandler.ts` around lines 39 - 42, The constructor signature
of InputHandler is wrong for existing instantiation: change the constructor to
accept throttleMs first and a sendToClient callback second (e.g.,
constructor(throttleMs = 8, sendToClient?: (msg: InputMessage) => void)), set
this.sendToClient to the provided function or a safe noop to avoid runtime
TypeError, and replace the msg parameter type from any to the explicit
InputMessage interface everywhere (e.g., in the clipboard-pull handler and other
handlers) so types align and websocket.ts can continue to call new
InputHandler(inputThrottleMs) without breaking.

mouse.config.mouseSpeed = 1000
this.modifier = os.platform() === "darwin" ? Key.LeftSuper : Key.LeftControl
this.throttleMs = throttleMs
Expand Down Expand Up @@ -196,6 +201,36 @@ export class InputHandler {
break
}

case "clipboard-push": {
if (msg.text) {
// TEMP: fallback using typing instead of real clipboard
await keyboard.type(msg.text)
}
break
}

case "clipboard-pull": {
// simulate Ctrl+C to get current clipboard
try {
await keyboard.pressKey(this.modifier, Key.C)
} finally {
await Promise.allSettled([
keyboard.releaseKey(Key.C),
keyboard.releaseKey(this.modifier),
])
}

// small delay to allow clipboard update
await new Promise((r) => setTimeout(r, 100))

// ❗ send back to client (IMPORTANT)
this.sendToClient({
type: "clipboard-text",
text: "TEMP_CLIPBOARD_DATA", // ⚠️ temporary (we’ll improve later)
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

clipboard-pull currently returns fake data.

This always sends "TEMP_CLIPBOARD_DATA" instead of actual copied content, so copy-to-client is functionally broken.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/server/InputHandler.ts` around lines 226 - 230, The handler is sending
the hardcoded string "TEMP_CLIPBOARD_DATA" instead of the real clipboard
contents; update the clipboard-pull handling code in InputHandler (the part that
calls this.sendToClient) to retrieve the actual text (e.g., await
getClipboardText() or call the existing method that reads system clipboard like
readClipboard()/clipboardReadFromSystem()/this.getClipboardText()) and pass that
value as the text field to this.sendToClient({ type: "clipboard-text", text:
actualText }); ensure the retrieval is awaited if async and fallback to an empty
string or error logging if reading the clipboard fails.

break
}

case "scroll": {
const MAX_SCROLL = 100
const promises: Promise<unknown>[] = []
Expand Down
Loading