Selkies

lib/input

Keyboard, pointer, touch, wheel, and gamepad capture on the stream element, sent to the server as the text messages of the input protocol.

Keyboard: every event resolves to an X11 keysym through noVNC's key tables and KeyboardUtil, and what is held server-side is tracked per physical code so a keyup releases what its keydown pressed. While anything is held a kh heartbeat repeats the held keysyms so the server can release keys whose keyup was lost, and modifiers a trusted event reports up are healed. IME composition streams the preedit as momentary presses diffed per codepoint; a shortcut chord pressed mid-composition is held until the commit lands so it applies after the text. A soft keyboard types into the off-screen assist field, whose value is mirrored to the server by the same diff and emptied once nothing composes in it. Chords on non-Latin layouts resolve from the physical key position, and a chord whose modifier keydown never reached the server is sent self-contained, wrapped in the missing modifiers. macOS Command is remapped onto Control, and Windows defers a ControlLeft keydown briefly to tell AltGr apart.

Pointer: absolute positions map through the presenting sink (the canvas or <video> box) where the stream has a fixed size, and through the element's window math otherwise; motion goes out as it arrives, from pointerrawupdate where the engine fires it, no closer together than MOTION_SEND_INTERVAL_MS apart. Under pointer lock the payload is a relative delta, scaled to server pixels and quantized with a carried remainder. Gaming mode is document fullscreen plus pointer and keyboard lock. Touch is direct (tap, drag, long-press right click, two-finger scroll and pinch) or a trackpad emulation. Wheel events are classified as discrete wheel or trackpad and accumulated in fractional notches so no distance is lost; a macOS wheel, whose deltas the system accelerates past any notch size, is one notch a detent (_isDetentWheel), and a WebKitGTK wheel, whose notch shrinks with the view, goes by the notches it reports (_webKitGtkWheelNotches). A pinch, on the touchscreen or a touchpad, reaches the session as Ctrl+wheel. The server-drawn cursor is painted on a page canvas or applied as a CSS cursor; in trackpad mode the canvas is drawn where the server echoes the pointer, moved on by the deltas sent since (onPointerEcho).

Wire messages: kd,<keysym>, ku,<keysym>, kh,<keysym>,..., kr; m,<x>,<y>,<mask>,<magnitude> (absolute) and m2,<dx>,<dy>,<mask>,<magnitude> (relative; scroll pulses ride mask bits 3 to 7); p,<0|1> and SET_NATIVE_CURSOR_RENDERING,<0|1> on pointer lock changes, the latter also where trackpad mode gets no pointer echo; js,c, js,d, js,b, js,a, and js,h for gamepads, whose rumble comes back as the system action rumble,<slot>,<strong>,<weak>,<ms> (rumble); _pointer_echo,<0|1> in trackpad mode, answered by the system action pointer,<display>,<x>,<y>,<scale>,<seq> or pointer,none; and, where the session takes a touchpad's scroll as a finger's, sf,<dx>,<dy> in stream pixels and sfe at its end (setFingerScroll).

Classes

Input

Defined in: lib/input.js:1511

Captures input on the stream element and sends it to the server.

One instance is live per page: attach detaches any previous one. Hotkeys: Ctrl+Shift+M opens the dashboard menu (onmenuhotkey), Ctrl+Shift+F enters plain fullscreen (onfullscreenhotkey, enterFullscreen by default), Ctrl+Shift+X toggles gaming mode (ongaminghotkey, toggleGamingMode by default), Ctrl+Shift+G toggles the gamepad overlay (ongamepadhotkey), and Ctrl+Shift+Click takes pointer lock; shortcutsEnabled false passes every one of them to the session instead. Three quick Escape presses in a row also leave gaming mode (_escapeHatch), whatever that flag says. Elements carrying the allow-native-input class keep native keyboard and touch handling.

Constructors

Constructor
new Input(
   element, 
   send, 
   isSharedMode?, 
   playerIndex?, 
   useCssScaling?, 
   initialSlot?
): Input;

Defined in: lib/input.js:1521

Parameters
ParameterTypeDefault valueDescription
elementHTMLElementundefinedOverlay element the stream input lands on; it also hosts IME composition.
send(message) => voidundefinedSends one input protocol message to the server.
isSharedMode?booleanfalseViewer-only session: listeners are limited to suppressing touch defaults.
playerIndex?number0Gamepad slot used while the server has assigned no controller slot.
useCssScaling?booleanfalseWhether the stream is realized in CSS pixels, so no device pixel ratio applies.
initialSlot?number | number[]nullOne-based controller slot assigned by the server, or the list of them a token holding several names.
Returns

Input

Properties

element
element: HTMLElement;

Defined in: lib/input.js:1522

send
send: (message) => void;

Defined in: lib/input.js:1523

Parameters
ParameterType
messagestring
Returns

void

sendMotion
sendMotion: (message) => void;

Defined in: lib/input.js:1530

Sends coalesced pointer motion where the transport has a channel that keeps no order for it, so a lost sample holds nothing behind it; null sends motion through send like every other message.

Parameters
ParameterType
messagestring
Returns

void

motionBacklog
motionBacklog: () => number;

Defined in: lib/input.js:1536

Bytes the transport still holds ahead of the next pointer motion message, or null where it cannot say.

Returns

number

isSharedMode
isSharedMode: boolean;

Defined in: lib/input.js:1539

controllerSlots
controllerSlots: number[];

Defined in: lib/input.js:1541

The one-based slots the server assigned, in the order the pads take them, or null (slotList).

playerIndex
playerIndex: number;

Defined in: lib/input.js:1542

cursorDiv
cursorDiv: HTMLCanvasElement;

Defined in: lib/input.js:1543

cursorImg
cursorImg: CanvasRenderingContext2D;

Defined in: lib/input.js:1552

cursorHotspot
cursorHotspot: object;

Defined in: lib/input.js:1554

x
x: number = 0;
y
y: number = 0;
use_browser_cursors
use_browser_cursors: boolean;

Defined in: lib/input.js:1558

displayId
displayId: string;

Defined in: lib/input.js:1562

The display this page renders, which the pointer echo names (onPointerEcho).

fingerScroll
fingerScroll: boolean;

Defined in: lib/input.js:1572

Whether the session takes a touchpad's scroll as a finger's (setFingerScroll).

useCssScaling
useCssScaling: boolean;

Defined in: lib/input.js:1576

m
m: object;

Defined in: lib/input.js:1578

mouseMultiX
mouseMultiX: number;
mouseMultiY
mouseMultiY: number;
mouseOffsetX
mouseOffsetX: number = offsetX;
mouseOffsetY
mouseOffsetY: number = offsetY;
elementClientX
elementClientX: number = elementRect.left;
elementClientY
elementClientY: number = elementRect.top;
frameW
frameW: number;
frameH
frameH: number;
buttonMask
buttonMask: number;

Defined in: lib/input.js:1591

gamepadManager
gamepadManager: GamepadManager;

Defined in: lib/input.js:1592

gamepadRumble
gamepadRumble: boolean;

Defined in: lib/input.js:1596

Pads play the rumble the server relays (setGamepadRumble).

x
x: number;

Defined in: lib/input.js:1597

y
y: number;

Defined in: lib/input.js:1598

onmenuhotkey
onmenuhotkey: any;

Defined in: lib/input.js:1608

gamingMode
gamingMode: boolean;

Defined in: lib/input.js:1609

shortcutsEnabled
shortcutsEnabled: boolean;

Defined in: lib/input.js:1612

ongamingmode
ongamingmode: any;

Defined in: lib/input.js:1615

onnotice
onnotice: any;

Defined in: lib/input.js:1616

onfullscreenhotkey
onfullscreenhotkey: () => void;

Defined in: lib/input.js:1617

Fullscreen with no lock, leaving the pointer and the keyboard to the browser: the dashboard button and the Ctrl+Shift+F chord land here. The whole document goes fullscreen, not the stream container: the dashboard overlay is a body-level sibling, which container fullscreen would hide.

Returns

void

ongaminghotkey
ongaminghotkey: () => void;

Defined in: lib/input.js:1618

Gaming mode on the Ctrl+Shift+X chord. Leaving it drops fullscreen, which is what releases both locks through the fullscreenchange handler; a mode left set without fullscreen (a refused request) is cleared directly.

Returns

void

ongamepadhotkey
ongamepadhotkey: any;

Defined in: lib/input.js:1619

ongamepadconnected
ongamepadconnected: any;

Defined in: lib/input.js:1620

ongamepaddisconnected
ongamepaddisconnected: any;

Defined in: lib/input.js:1621

listeners
listeners: any[];

Defined in: lib/input.js:1622

listeners_context
listeners_context: any[];

Defined in: lib/input.js:1623

cursorScaleFactor
cursorScaleFactor: any;

Defined in: lib/input.js:1658

isComposing
isComposing: boolean;

Defined in: lib/input.js:1680

compositionString
compositionString: string;

Defined in: lib/input.js:1681

keyboardInputAssist
keyboardInputAssist: HTMLElement;

Defined in: lib/input.js:1695

trackpadSpeed
trackpadSpeed: number;

Defined in: lib/input.js:1716

The dashboards' trackpad speed, scaling the accelerated travel (setTrackpadSpeed).

inputAttached
inputAttached: boolean;

Defined in: lib/input.js:1717

rawPointerMotion
static rawPointerMotion: boolean;

Defined in: lib/input.js:1765

Whether pointer lock asks for raw movement: the raw_pointer_motion setting, which the core resolves and pushes through setRawPointerMotion. Until it does, the platform decides: off on macOS, where the engine grants the option instead of refusing it and nothing replaces the acceleration curve it takes away. The client scales a locked delta by the stream box and quantizes it (_relativeToServer), but that gain is the same at every speed, so the slow motion the curve used to expand now covers far less of the remote screen and the pointer feels heavy. Windows grants it as well and is left on it: raw deltas are what pointer lock is for, and nobody has reported the same there.

macCmdAsCtrl
static macCmdAsCtrl: boolean = true;

Defined in: lib/input.js:1776

Whether a macOS Command chord reaches the session as its Control chord: the mac_cmd_as_ctrl setting, which the core pushes through setMacCmdAsCtrl. On by default, so Cmd+C copies in the remote application the way it does locally. Off sends Command as the Super it physically is, which is what a session whose window manager takes Super as its own modifier needs: remapped, its Cmd+Return arrives as Ctrl+Return and its Cmd+C interrupts the foreground program.

Methods

setSharedMode()
setSharedMode(enabled): void;

Defined in: lib/input.js:1721

Sets whether this is a viewer-only session.

Parameters
ParameterType
enabledany
Returns

void

updateControllerSlot()
updateControllerSlot(newSlot): void;

Defined in: lib/input.js:1732

Assigns the one-based controller slot the server gave this client, or the list of them, and announces the pads that drive them there: a js,c sent before the slot was known was refused by the server's slot gate, which left the pad unassociated.

Parameters
ParameterTypeDescription
newSlotnumber | number[]-
Returns

void

updateServerCursor()
updateServerCursor(cursorData): Promise<void>;

Defined in: lib/input.js:1910

Applies a cursor update from the server; an empty or null-handle update hides the cursor. A new PNG invalidates the cached canvas bitmap even while CSS renders it, so changing modes retains the current shape and size. Trackpad mode always paints the canvas, at the pointer echo, since no local pointer shows where the remote one is.

Parameters
ParameterTypeDescription
cursorData{ curdata?: string; handle: string | number; hotx?: string | number; hoty?: string | number; }Base64 PNG and hotspot as the server sends them.
cursorData.curdata?string-
cursorData.handlestring | number-
cursorData.hotx?string | number-
cursorData.hoty?string | number-
Returns

Promise<void>

setSynth()
setSynth(isSynth): void;

Defined in: lib/input.js:1946

Marks input as synthetic (tests), which disables the keydown stuck-modifier heal.

Parameters
ParameterType
isSynthany
Returns

void

updateCssScaling()
updateCssScaling(newUseCssScalingValue): void;

Defined in: lib/input.js:1952

Switches CSS-pixel scaling and re-derives the window math and cursor.

Parameters
ParameterType
newUseCssScalingValueany
Returns

void

resetKeyboard()
resetKeyboard(): void;

Defined in: lib/input.js:2110

Releases every held key and stops the heartbeat. The armed Windows AltGr timer is canceled so it cannot synthesize a Control keydown after the reset, while the page is hidden or detached.

Returns

void

releaseInput()
releaseInput(): void;

Defined in: lib/input.js:2129

Releases every held key and pointer button, and a trackpad tap's pending release. A press whose release goes to another tab or app (a tab switched mid-press, a touch the system took for a gesture) left the remote button down: every motion after it dragged, and the next press went to a button already down and did nothing, until a motion over the stream stated the buttons again.

Returns

void

setTrackpadSpeed()
setTrackpadSpeed(speed): void;

Defined in: lib/input.js:3436

Sets how far the trackpad moves the pointer for a finger's travel, as a factor on the accelerated gain; the dashboards' setting, persisted by the core as trackpad_speed.

Parameters
ParameterTypeDescription
speednumberClamped to TRACKPAD_SPEED_MIN-TRACKPAD_SPEED_MAX.
Returns

void

setDisplayLayouts()
setDisplayLayouts(layouts, ownId): void;

Defined in: lib/input.js:3695

Sets the extended-desktop layout the mapping above uses: display rectangles in remote pixels, keyed by display id, each carrying the owning page's CSS-to-remote scale where known, and its stream box in desktop coordinates where that page has published one. Fewer than two valid rectangles (or no entry for ownId) disables cross-display mapping.

Parameters
ParameterTypeDescription
layouts{ }-
ownIdstringDisplay id this page renders.
Returns

void

setStreamDensity()
setStreamDensity(density): void;

Defined in: lib/input.js:3922

Sets the density the core streams this page at, or null to derive it from the page's own; the window math and cursor follow it.

Parameters
ParameterTypeDescription
densitynumberStream pixels per CSS pixel.
Returns

void

setTrackpadMode()
setTrackpadMode(enabled): void;

Defined in: lib/input.js:4031

Switches trackpad emulation, clearing touch state and any held button.

Parameters
ParameterType
enabledany
Returns

void

resumePointerEcho()
resumePointerEcho(): void;

Defined in: lib/input.js:4063

The transport connected again: a trackpad page asks the new connection for the pointer echo, since the last one's ended with it.

Returns

void

onPointerEcho()
onPointerEcho(action): void;

Defined in: lib/input.js:4128

Takes a pointer echo: the system action pointer,<display>,<x>,<y>,<scale>,<seq>, the position in that display's server pixels, the physical pixels a relative one moves it there, and the last pointer message of this page the position includes; or pointer,none from a session that cannot say where its pointer is.

Parameters
ParameterTypeDescription
actionstring-
Returns

void

setRawPointerMotion()
setRawPointerMotion(enabled): void;

Defined in: lib/input.js:4195

Applies the raw pointer motion setting. A lock the stream already holds is re-requested with the new option, which switches the running lock in place on engines that allow it rather than deferring the change to the next lock; an engine that refuses the option falls back the way a first request does.

Parameters
ParameterTypeDescription
enabledboolean-
Returns

void

setShortcutsEnabled()
setShortcutsEnabled(enabled): void;

Defined in: lib/input.js:4216

Whether the client keeps its own chords rather than passing them on.

Parameters
ParameterType
enabledany
Returns

void

setMacCmdAsCtrl()
setMacCmdAsCtrl(enabled): void;

Defined in: lib/input.js:4220

Parameters
ParameterType
enabledany
Returns

void

setUseBrowserCursors()
setUseBrowserCursors(enabled): Promise<void>;

Defined in: lib/input.js:4233

Switches between the CSS cursor and the page-drawn cursor canvas.

Parameters
ParameterType
enabledany
Returns

Promise<void>

setFingerScroll()
setFingerScroll(enabled): void;

Defined in: lib/input.js:4938

Sets whether the session takes a touchpad's scroll as a finger's: the display config's finger_scroll, a Wayland session's. There a wheel classified as a touchpad sends its travel instead of notches (_isFingerScroll); a wheel's notches, line and page deltas, and X11 stay as they are.

Parameters
ParameterTypeDescription
enabledboolean-
Returns

void

rumble()
rumble(
   slot, 
   strong, 
   weak, 
   durationMs
): void;

Defined in: lib/input.js:5184

Plays the rumble the server relays for a pad slot, on this client's pads when the slot is the one they drive (GamepadManager.rumble); a client holding several slots plays it on the pad driving that one.

Parameters
ParameterTypeDescription
slotnumberZero-based server slot.
strongnumberStrong motor level, 0 to 1.
weaknumberWeak motor level, 0 to 1.
durationMsnumberHow long to hold it.
Returns

void

setGamepadRumble()
setGamepadRumble(on): void;

Defined in: lib/input.js:5201

Turns rumble on this client's pads on or off (the dashboards' toggle, persisted by the core as gamepad_rumble); off stops one playing.

Parameters
ParameterTypeDescription
onboolean-
Returns

void

stopRumble()
stopRumble(): void;

Defined in: lib/input.js:5207

Stops a rumble playing on this client's pads: its connection is gone.

Returns

void

getWindowResolution()
getWindowResolution(): number[];

Defined in: lib/input.js:5359

The page size in device pixels, rounded down to even.

Returns

number[]

Width and height.

resize()
resize(): void;

Defined in: lib/input.js:5369

Re-derives the window math after a layout change.

Returns

void

isInputAttached()
isInputAttached(): boolean;

Defined in: lib/input.js:5374

True while the full input context is attached.

Returns

boolean

attach()
attach(): void;

Defined in: lib/input.js:5388

Attaches the window and document listeners, and the input context unless this is a viewer-only session. Any previously attached instance is detached first: reconnect paths construct a fresh Input, whose predecessor's listeners and gamepad poller would otherwise keep firing alongside it. The overlay element takes focus, since browsers only run IME composition on the focused editable element, unless the user is in another field. Pads are adopted for every role, since a #playerN link grants a gamepad without the rest of the input context.

Returns

void

attach_context()
attach_context(): void;

Defined in: lib/input.js:5425

Attaches the keyboard, pointer, touch, wheel, and composition listeners and shows the cursor.

Returns

void

resyncGamepads()
resyncGamepads(): void;

Defined in: lib/input.js:5497

Adopts pads the browser already exposes: gamepadconnected fires only on physical connect (or first press), so a re-attach would otherwise leave the pad dead until re-plugged. Public because a channel that opens after attach must re-announce: the js,c it sent into a closed channel was dropped, leaving the server no association to release when the peer goes.

Returns

void

detach()
detach(): void;

Defined in: lib/input.js:5520

Removes every listener and the gamepad manager, then the input context.

Returns

void

detach_context()
detach_context(): void;

Defined in: lib/input.js:5539

Removes the input context listeners, releases every key and button, and exits pointer lock.

Returns

void

enterFullscreen()
enterFullscreen(): void;

Defined in: lib/input.js:5583

Fullscreen with no lock, leaving the pointer and the keyboard to the browser: the dashboard button and the Ctrl+Shift+F chord land here. The whole document goes fullscreen, not the stream container: the dashboard overlay is a body-level sibling, which container fullscreen would hide.

Returns

void

toggleGamingMode()
toggleGamingMode(): void;

Defined in: lib/input.js:5596

Gaming mode on the Ctrl+Shift+X chord. Leaving it drops fullscreen, which is what releases both locks through the fullscreenchange handler; a mode left set without fullscreen (a refused request) is cleared directly.

Returns

void

enterGamingMode()
enterGamingMode(): void;

Defined in: lib/input.js:5633

Enters gaming mode: fullscreen that also holds the pointer and the keyboard, so a game sees Escape, Alt+Tab, and raw motion instead of the browser. A locked keyboard delivers a short Escape to the session, so holding it is what leaves this mode.

The pointer lock is asked for first, on the gesture that asked for the mode, and fullscreen once the lock settled (_lockOnGesture): a fullscreen request spends the gesture's transient activation, and Chromium refuses a lock asked for without one, in fullscreen as well (Edge on Windows on every entry); a lock taken first survives the switch to fullscreen. Gecko goes the other way round: it grants a lock in fullscreen without a gesture, and measures the first movement of a lock taken before the switch from where the viewport was, so there the fullscreenchange handler takes it once the viewport settled. That handler also asks again wherever the first request did not take, and arms the keyboard lock. A refused fullscreen takes the mode back down with it: left set, the next transition from any source would arm the locks. From a fullscreen the page holds already, an engine without the Keyboard Lock API asks for the same element again with the gaming options: by the Fullscreen spec that sets the element's keyboard lock with no transition (Firefox 156 holds Escape after it); it comes after the pointer lock request, since a fullscreen request consumes the gesture's transient activation.

Returns

void

requestKeyboardLock()
requestKeyboardLock(): void;

Defined in: lib/input.js:5775

Locks every key the browser or the system would otherwise take, its own shortcuts (Ctrl+W, Ctrl+T) among them, for gaming mode alone: through the Keyboard Lock API where it exists, else by the fullscreen request's own keyboardLock where the engine took it (_gamingFullscreenOptions), which holds the same keys. Only where neither holds the keys does the user hear that one Escape leaves the mode. A lock the engine refuses leaves the keys to the browser and the system, and only the console says so.

Returns

void

releaseKeyboardLock()
releaseKeyboardLock(): void;

Defined in: lib/input.js:5813

Hands the system keys back; a browser that never locked them ignores it.

Returns

void

Functions

trackpadGain()

function trackpadGain(speed): number;

Defined in: lib/input.js:189

The trackpad's gain at a finger speed: 1, rising along a smoothstep to TRACKPAD_ACCEL_MAX between TRACKPAD_ACCEL_SLOW and TRACKPAD_ACCEL_FAST.

Parameters

ParameterTypeDescription
speednumberCSS pixels per millisecond.

Returns

number


slotList()

function slotList(slot): number[];

Defined in: lib/input.js:202

The one-based gamepad slots a server verdict's slot names, in the order the client's pads take them: one number, a list of them (a token holding several), or none.

Parameters

ParameterTypeDescription
slotnumber | number[]-

Returns

number[]


addListener()

function addListener(
   obj, 
   name, 
   func, 
   ctx, 
   useCapture?
): any[];

Defined in: lib/input.js:5842

Adds a listener bound to ctx, with passive: false so the handler keeps preventDefault().

Parameters

ParameterTypeDefault value
objanyundefined
nameanyundefined
funcanyundefined
ctxanyundefined
useCapture?booleanfalse

Returns

any[]

The tuple removeListeners takes, or null for an invalid target.


removeListeners()

function removeListeners(listeners): void;

Defined in: lib/input.js:5854

Removes listeners added by addListener and empties the list.

Parameters

ParameterType
listenersany

Returns

void

On this page

ClassesInputConstructorsConstructorParametersReturnsPropertieselementsendParametersReturnssendMotionParametersReturnsmotionBacklogReturnsisSharedModecontrollerSlotsplayerIndexcursorDivcursorImgcursorHotspotxyuse_browser_cursorsdisplayIdfingerScrolluseCssScalingmmouseMultiXmouseMultiYmouseOffsetXmouseOffsetYelementClientXelementClientYframeWframeHbuttonMaskgamepadManagergamepadRumblexyonmenuhotkeygamingModeshortcutsEnabledongamingmodeonnoticeonfullscreenhotkeyReturnsongaminghotkeyReturnsongamepadhotkeyongamepadconnectedongamepaddisconnectedlistenerslisteners_contextcursorScaleFactorisComposingcompositionStringkeyboardInputAssisttrackpadSpeedinputAttachedrawPointerMotionmacCmdAsCtrlMethodssetSharedMode()ParametersReturnsupdateControllerSlot()ParametersReturnsupdateServerCursor()ParametersReturnssetSynth()ParametersReturnsupdateCssScaling()ParametersReturnsresetKeyboard()ReturnsreleaseInput()ReturnssetTrackpadSpeed()ParametersReturnssetDisplayLayouts()ParametersReturnssetStreamDensity()ParametersReturnssetTrackpadMode()ParametersReturnsresumePointerEcho()ReturnsonPointerEcho()ParametersReturnssetRawPointerMotion()ParametersReturnssetShortcutsEnabled()ParametersReturnssetMacCmdAsCtrl()ParametersReturnssetUseBrowserCursors()ParametersReturnssetFingerScroll()ParametersReturnsrumble()ParametersReturnssetGamepadRumble()ParametersReturnsstopRumble()ReturnsgetWindowResolution()Returnsresize()ReturnsisInputAttached()Returnsattach()Returnsattach_context()ReturnsresyncGamepads()Returnsdetach()Returnsdetach_context()ReturnsenterFullscreen()ReturnstoggleGamingMode()ReturnsenterGamingMode()ReturnsrequestKeyboardLock()ReturnsreleaseKeyboardLock()ReturnsFunctionstrackpadGain()ParametersReturnsslotList()ParametersReturnsaddListener()ParametersReturnsremoveListeners()ParametersReturns
Edit on GitHub