Files
orca/src/main/browser/cdp-pointer-input.ts
T
OrcaWin 2847bbe9e8 [comment audit] Consolidate completed code comment cleanup
Combine the completed comment cleanup from 319 stacked PRs into one change against `main`, so the full CI suite validates the combined result once. This replaces the previous audit stack; no additional audit work is included.

The change shortens redundant comments across 2,753 source and shell-snapshot files (25,235 net lines removed). Conflicts preserve current-main executable code. Runtime behavior, test assertions, directives, licenses, generated notices, SAFETY rationales, and compatibility markers are preserved. The audit tracker remains local, outside the repository.

Validation:
- Equivalent source/emitted AST and executable tokens across all 2,750 source files, with separate checks for embedded shell, SQL, JavaScript, CSS, and generated fixtures.
- Identical executable lines in the three shell snapshots; protected comments unchanged.
- Changed-code quality gate passed with no new findings.
- 358 tests passed, 2 skipped across 23 focused test files.
- `git diff --check` passed.
2026-10-23 13:15:45 -07:00

85 lines
2.5 KiB
TypeScript

import type { WebContents } from 'electron'
import { BrowserError } from './cdp-bridge'
import {
type CdpPointerButton,
cdpPointerButtonMask,
cdpPointerButtonFromMask
} from './agent-browser-bridge-mouse'
const MULTI_CLICK_INTERVAL_MS = 500
const MULTI_CLICK_SLOP_PX = 2
type LastPointerClick = {
button: CdpPointerButton
x: number
y: number
at: number
count: number
}
export type CdpPointerState = {
x: number
y: number
button: CdpPointerButton | 'none'
buttons: number
clickCount: number
lastClick: LastPointerClick | null
}
const pointerStates = new WeakMap<WebContents, CdpPointerState>()
export function cdpPointerStateFor(webContents: WebContents): CdpPointerState {
let state = pointerStates.get(webContents)
if (!state) {
state = {
x: 0,
y: 0,
button: 'none',
buttons: 0,
clickCount: 1,
lastClick: null
}
pointerStates.set(webContents, state)
}
return state
}
// Chromium needs clickCount 2 on the second press to emit dblclick.
export function trackCdpClickCount(state: CdpPointerState, button: CdpPointerButton): number {
const now = Date.now()
const previous = state.lastClick
const repeated =
previous !== null &&
previous.button === button &&
Math.abs(previous.x - state.x) <= MULTI_CLICK_SLOP_PX &&
Math.abs(previous.y - state.y) <= MULTI_CLICK_SLOP_PX &&
now - previous.at <= MULTI_CLICK_INTERVAL_MS
const count = repeated ? (previous.count >= 3 ? 1 : previous.count + 1) : 1
state.lastClick = { button, x: state.x, y: state.y, at: now, count }
return count
}
export function assertFinitePointerValues(values: Record<string, number>): void {
for (const [name, value] of Object.entries(values)) {
if (!Number.isFinite(value)) {
throw new BrowserError('browser_error', `Pointer input requires a finite ${name}`)
}
}
}
export function pressCdpPointerButton(state: CdpPointerState, button: CdpPointerButton): void {
state.button = button
state.buttons |= cdpPointerButtonMask(button)
state.clickCount = trackCdpClickCount(state, button)
}
export function releaseCdpPointerButton(state: CdpPointerState, button: CdpPointerButton): void {
state.buttons &= ~cdpPointerButtonMask(button)
// An unqualified mouseUp must still release a held button after a chorded release.
state.button = cdpPointerButtonFromMask(state.buttons)
}
export function resolveCdpPointerReleaseButton(state: CdpPointerState): string | undefined {
return state.button === 'none' ? undefined : state.button
}