Events
APIs for pointer interactions and listener-trigger payloads.
This page reflects released Web 2.42.0 -> C++ runtime-v0.1.344, with
source pins tracked in Runtime Compatibility Baseline.
The names and signatures below were revalidated through the Rive MCP against
the built-in rive/artboards and rive/interfaces references in Rive Beta
0.8.5390 build 5377. A temporary Tests script covering the complete surface
recompiled with diagnostics []; the original three runtime cases still
passed after the probe was removed. This proves Editor analyzer acceptance, not
hardware gamepad dispatch or the released Web runtime path. Those evidence
tiers remain separate in the compatibility page.
PointerEvent
Pointer interaction event data.
PointerType
The current Editor reference types PointerEvent.type with this string union:
export type PointerType =
"pointerEnter"
| "pointerExit"
| "pointerDown"
| "pointerUp"
| "pointerMove"
| "click"
| "pointerDrag"
| "unknown"
The upstream reference still labels the standalone alias "Coming soon," even
though the current Editor reference exposes it and uses it for
PointerEvent.type. It is a type alias, not a runtime enum table.
Constructor
PointerEvent.new(id, position)
Creates a new PointerEvent. Used for forwarding events to nested artboards.
PointerEvent.new(id: number, position: Vector): PointerEvent
Example:
-- Forward event to nested artboard
local childPos = transformToChildSpace(event.position)
local childEvent = PointerEvent.new(event.id, childPos)
Attributes
| Attribute | Type | Description |
|---|---|---|
position | Vector | Local coordinates |
id | number | Pointer ID (for multitouch) |
type | PointerType | Current event-kind string |
Methods
event:hit(isTranslucent?)
Marks the event as handled. If isTranslucent is true, the event may continue to propagate through translucent hit targets.
event:hit() -- Standard: stops propagation
event:hit(true) -- Translucent: may continue through
Example:
function pointerDown(self, event: PointerEvent)
if isInBounds(event.position) then
self.pressed = true
event:hit()
end
end
ListenerContext
ListenerAction scripts receive listenerContext via:
function performAction(self: MyAction, listenerContext: ListenerContext)
-- inspect event kind with is... methods
end
Type Guards
listenerContext:isPointerEvent()listenerContext:isKeyboardEvent()listenerContext:isTextInput()listenerContext:isFocus()listenerContext:isReportedEvent()listenerContext:isViewModelChange()listenerContext:isGamepadConnected()listenerContext:isGamepadEvent()listenerContext:isGamepadDisconnected()listenerContext:isNone()
Typed Accessors
listenerContext:asPointerEvent(): PointerEvent?listenerContext:asKeyboardEvent(): KeyboardEvent?listenerContext:asTextInput(): TextInput?listenerContext:asFocus(): FocusEvent?listenerContext:asReportedEvent(): ReportedEvent?listenerContext:asViewModelChange(): ViewModelChange?listenerContext:asGamepadConnected(): GamepadConnected?listenerContext:asGamepadEvent(): GamepadEvent?listenerContext:asGamepadDisconnected(): GamepadDisconnected?listenerContext:asNone(): NoneEvent?
Safe Branching Example
function performAction(self: MyAction, listenerContext: ListenerContext)
if listenerContext:isPointerEvent() then
local evt = listenerContext:asPointerEvent()
if evt then
print("pointer:", evt.type, evt.position.x, evt.position.y)
end
elseif listenerContext:isKeyboardEvent() then
local evt = listenerContext:asKeyboardEvent()
if evt then
print("keyboard:", evt.key, evt.phase)
end
elseif listenerContext:isTextInput() then
local evt = listenerContext:asTextInput()
if evt then
print("text:", evt.text)
end
elseif listenerContext:isGamepadEvent() then
local evt = listenerContext:asGamepadEvent()
if evt then
print("gamepad change:", evt.changeKind, evt.changeIndex, evt.changeValue)
end
end
end
KeyboardEvent
Keyboard payload exposed via listenerContext:asKeyboardEvent().
export type KeyPhase = "down" | "repeat" | "up"
| Field | Type | Description |
|---|---|---|
key | number | Key code |
shift | boolean | Shift modifier active |
control | boolean | Control modifier active |
alt | boolean | Alt modifier active |
meta | boolean | Meta/Command modifier active |
phase | KeyPhase | "down", "repeat", or "up" |
TextInput
Text input payload exposed via listenerContext:asTextInput().
| Field | Type | Description |
|---|---|---|
text | string | Committed text input |
alignValue (serialized key 222) and verticalAlignValue (key 1094) are
TextInput component metadata parsed from .riv files; they are not fields on
this Luau event payload. The accepted runtime also retains serialized
obscured key 1095; it is likewise not a Luau event field.
FocusEvent
Focus payload exposed via listenerContext:asFocus().
| Field | Type | Description |
|---|---|---|
isFocus | boolean | true when focus gained, false when focus lost |
The accepted target includes fixes for gamepad device indexing, root-artboard
FocusManager ownership, re-homing focus for nested instances, visibility
transitions, and destroyed focus-tree state. Those are runtime behavior fixes;
they do not add fields to FocusEvent or change callback signatures.
ReportedEvent
listenerContext:asReportedEvent() returns ReportedEvent?. The current Editor
reference declares no public fields on this type, so current-facing examples
must treat it as a presence/kind signal only.
ViewModelChange
listenerContext:asViewModelChange() returns ViewModelChange?. The current
Editor reference declares no public fields on this type.
Gamepad Events
Gamepad listener payloads are three distinct types. Do not collapse them into a
generic GamepadInvocation.
export type GamepadMappingKind = "standard" | "unknown"
GamepadConnected
Access with isGamepadConnected() and asGamepadConnected().
| Field | Type | Description |
|---|---|---|
deviceId | number | Stable device ID for the logical gamepad session |
buttonMask | number | Pressed-button bitmask |
buttons | { number } | 1-based analog button values |
axes | { number } | 1-based analog axes |
isStandardMapping | boolean | Whether the embedder normalized the standard layout |
mapping | GamepadMappingKind | "standard" or "unknown" |
gamepadMapping | number | Raw mapping enum value (0 standard, 1 unknown) |
west, south, north, east | boolean | Standard face-button state |
leftShoulder, rightShoulder | boolean | Shoulder-button state |
back, forward, start | boolean | Standard navigation/start-button state |
leftStickButton, rightStickButton | boolean | Stick-click state |
dpadUp, dpadDown, dpadLeft, dpadRight | boolean | Direction-pad state |
leftStick, rightStick | Vector | Analog stick vectors |
leftTrigger, rightTrigger | number | Analog trigger values |
leftTriggerPressed, rightTriggerPressed | boolean | Digital trigger-button state |
Methods:
event:buttonPressed(index: number): booleanevent:buttonValue(index: number): numberevent:axis(index: number): number
The current reference documents these indices as 1-based.
GamepadEvent
Access with isGamepadEvent() and asGamepadEvent(). It contains the same full
device-state fields and query methods as GamepadConnected, plus:
| Field | Type | Description |
|---|---|---|
changeKind | string | "button" or "axis" |
changeIndex | number | 1-based button or axis index |
changeValue | number | New analog value |
hasStandardButtonIntent | boolean | Whether a standard button intent exists |
hasStandardAxisIntent | boolean | Whether a standard axis intent exists |
intentButton | string? | Optional semantic button intent |
intentAxis | string? | Optional semantic axis intent |
GamepadDisconnected
Access with isGamepadDisconnected() and asGamepadDisconnected(). It exposes
only deviceId: number.
Node Gamepad Callbacks
The current Editor Node<T> reference exposes these optional callbacks:
function gamepadConnected(self: MyNode, event: GamepadConnected)
print("connected", event.deviceId, event.mapping)
end
function gamepadEvent(self: MyNode, event: GamepadEvent)
print(event.changeKind, event.changeIndex, event.changeValue)
end
function gamepadDisconnected(self: MyNode, event: GamepadDisconnected)
print("disconnected", event.deviceId)
end
runtime-v0.1.344 also corrects gamepad focus-device selection. Re-test real
controller navigation and focus destruction/restoration in the selected
runtime because analyzer acceptance alone does not execute those paths.
NoneEvent
Fallback event shape for unknown or unsupported listener event kinds. The current Editor reference declares no public fields.
- Check with
listenerContext:isNone() - Access with
listenerContext:asNone()
Historical Runtime Wrapper Names
The pinned runtime-v0.1.262 source snapshot still uses Lua userdata wrapper
names such as KeyboardInvocation, TextInputInvocation, FocusInvocation,
ReportedEventInvocation, ViewModelChangeInvocation, and NoneInvocation.
It also exposes delaySeconds on that historical reported-event wrapper. These
names explain older source and LERP material; they are not the type names in the
current Editor reference and should not be used for new Editor-authored code.
The generic GamepadInvocation / isGamepad() / asGamepad() shape previously
shown by LERP is not the current reference contract. Current gamepad code must
use the connected/event/disconnected triad above.
Trigger
See Data & Input: Trigger for the Trigger type reference, and Trigger Inputs for the full usage guide.
Knowledge Check
Next Steps
- Continue to Assets
- Verify surface status in Runtime Compatibility Baseline
- Need a refresher? Review Quick Reference