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
| Parameter | Type | Default value | Description |
|---|---|---|---|
element | HTMLElement | undefined | Overlay element the stream input lands on; it also hosts IME composition. |
send | (message) => void | undefined | Sends one input protocol message to the server. |
isSharedMode? | boolean | false | Viewer-only session: listeners are limited to suppressing touch defaults. |
playerIndex? | number | 0 | Gamepad slot used while the server has assigned no controller slot. |
useCssScaling? | boolean | false | Whether the stream is realized in CSS pixels, so no device pixel ratio applies. |
initialSlot? | number | number[] | null | One-based controller slot assigned by the server, or the list of them a token holding several names. |
Returns
Properties
element
element: HTMLElement;Defined in: lib/input.js:1522
send
send: (message) => void;Defined in: lib/input.js:1523
Parameters
| Parameter | Type |
|---|---|
message | string |
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
| Parameter | Type |
|---|---|
message | string |
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
| Parameter | Type |
|---|---|
enabled | any |
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
| Parameter | Type | Description |
|---|---|---|
newSlot | number | 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
| Parameter | Type | Description |
|---|---|---|
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.handle | string | 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
| Parameter | Type |
|---|---|
isSynth | any |
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
| Parameter | Type |
|---|---|
newUseCssScalingValue | any |
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
| Parameter | Type | Description |
|---|---|---|
speed | number | Clamped 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
| Parameter | Type | Description |
|---|---|---|
layouts | { } | - |
ownId | string | Display 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
| Parameter | Type | Description |
|---|---|---|
density | number | Stream 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
| Parameter | Type |
|---|---|
enabled | any |
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
| Parameter | Type | Description |
|---|---|---|
action | string | - |
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
| Parameter | Type | Description |
|---|---|---|
enabled | boolean | - |
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
| Parameter | Type |
|---|---|
enabled | any |
Returns
void
setMacCmdAsCtrl()
setMacCmdAsCtrl(enabled): void;Defined in: lib/input.js:4220
Parameters
| Parameter | Type |
|---|---|
enabled | any |
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
| Parameter | Type |
|---|---|
enabled | any |
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
| Parameter | Type | Description |
|---|---|---|
enabled | boolean | - |
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
| Parameter | Type | Description |
|---|---|---|
slot | number | Zero-based server slot. |
strong | number | Strong motor level, 0 to 1. |
weak | number | Weak motor level, 0 to 1. |
durationMs | number | How 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
| Parameter | Type | Description |
|---|---|---|
on | boolean | - |
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
| Parameter | Type | Description |
|---|---|---|
speed | number | CSS 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
| Parameter | Type | Description |
|---|---|---|
slot | number | 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
| Parameter | Type | Default value |
|---|---|---|
obj | any | undefined |
name | any | undefined |
func | any | undefined |
ctx | any | undefined |
useCapture? | boolean | false |
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
| Parameter | Type |
|---|---|
listeners | any |
Returns
void