Events
wybthon.events¶
events
¶
Delegated event handling for the batched renderer.
Event delegation lives in the rendering kernel: one native listener per
event type is installed on each render root (the container passed to
render, plus any Portal target),
walks the ancestor chain of the event target natively, and calls into
Python once for the bubbling route. Non-bubbling events and explicit native
listener options use direct listeners.
The call carries a small JSON payload (event type, target value/checked
state, key, mouse buttons, modifiers), so the common handler patterns
(evt.target.value, evt.key, evt.prevent_default()) never touch a
JsProxy at all.
Registering a handler costs no bridge crossing: a template declares its
delegated listeners when it's registered, so cloning a row marks them
natively, and other handlers ride the same command buffer as the DOM
mutations (LISTEN).
A handler may take the DomEvent or no arguments
at all: on_click=lambda: set_open(False).
Public surface:
DomEvent: the event object passed to handlers, exposingtype,target,current_target, key and mouse fields, and helpers likeprevent_defaultandstop_propagation.
The remaining helpers are internal:
set_handler and
remove_handlers_for are called
by the renderer, and dispatch_event
is the entry point the kernel invokes when a native event fires.
See Also
Classes:
| Name | Description |
|---|---|
EventHandler |
A handler with native listener options, constructed with |
DomEvent |
The event object Wybthon passes to delegated handlers. |
Functions:
| Name | Description |
|---|---|
event |
Configure a native listener. Ordinary handlers use batched delegation. |
EventHandler
dataclass
¶
EventHandler(callback: Callable[..., Any], capture: bool = False, passive: bool = False, once: bool = False)
A handler with native listener options, constructed with event.
DomEvent
¶
The event object Wybthon passes to delegated handlers.
Built from the kernel's dispatch payload rather than a JsProxy,
so reading it is free of bridge crossings. Use
raw to reach the native event object for
anything not covered by the payload.
Attributes:
| Name | Type | Description |
|---|---|---|
type |
Event type string (e.g., |
|
target |
Payload-backed view of the original event target,
exposing |
|
current_target |
The element whose handler is currently running
(an id-backed |
|
key |
|
|
code |
|
|
alt_key |
Whether Alt was held. |
|
ctrl_key |
Whether Ctrl was held. |
|
meta_key |
Whether Meta/Cmd was held. |
|
shift_key |
Whether Shift was held. |
|
button |
|
|
client_x |
Pointer x position, when applicable. |
|
client_y |
Pointer y position, when applicable. |
Build an event from a dispatch payload dict.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
payload
|
dict[str, Any]
|
Parsed dispatch payload from the kernel. |
required |
current_target
|
Any | None
|
The |
None
|
Methods:
| Name | Description |
|---|---|
prevent_default |
Prevent the default browser action for this event. |
stop_propagation |
Stop the delegated dispatch from walking further up the tree. |
event
¶
event(handler: Callable[..., Any], *, capture: bool = False, passive: bool = False, once: bool = False) -> EventHandler
Configure a native listener. Ordinary handlers use batched delegation.
bind_delegated
¶
Record a delegated handler whose listener the node's template already declared.
set_handler
¶
Attach, update, or remove a handler for an event property on a node.
Registration is batched: the kernel-side LISTEN/UNLISTEN ops
ride the same command buffer as the DOM mutations, so wiring
handlers costs no extra bridge crossings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
node_id
|
int
|
Kernel node id to attach to. |
required |
event_prop_name
|
str
|
Prop name as seen on the |
required |
handler
|
Callable[..., Any] | None
|
Callback to invoke, with the event or no arguments.
Pass |
required |
remove_handlers_for
¶
remove_handlers_for(node_id: int) -> None
Drop every handler registered for node_id (Python side only).
Called by the renderer during unmount. The kernel-side listener
bookkeeping is cleared by the RELEASE op that accompanies the
subtree removal, so no per-handler ops are needed.
dispatch_event
¶
Invoke the handler for (node_id, event_type) with a payload.
This is the entry point the kernel's native root listener calls, once for the matching bubbling route, or once for a direct native listener.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
node_id
|
int
|
Id of the node whose handler should run. |
required |
event_type
|
str
|
DOM event type (e.g., |
required |
payload_json
|
str
|
JSON-encoded payload built natively by the kernel. |
required |
Returns:
| Type | Description |
|---|---|
int
|
Flag bits for the kernel: bit 1 stops the delegated walk and |
int
|
native propagation, bit 2 calls |
What's in this module¶
Event handling is delegated at the render root. The JS kernel
installs one native listener per event type on each container passed to
render (falling back to document when no root is
registered), walks the ancestor chain natively when an event fires, and
calls into Python once for the matching bubbling route with a small JSON payload.
Handlers receive a DomEvent built from that
payload, so the common reads (evt.target.value, evt.key) never touch
a JsProxy. Registering a handler costs no bridge crossing: handlers
on template-mounted nodes are declared by the template itself, so a
cloned row marks its listeners natively, and other handlers ride the
command buffer as a batched LISTEN op.
| Name | Description |
|---|---|
DomEvent |
The event object: type, target (.value, .checked, .files, .element), current_target, key, code, alt_key, ctrl_key, meta_key, shift_key, button, client_x, client_y, prevent_default(), stop_propagation(), raw. |
event |
event(handler, *, capture=False, passive=False, once=False): attach a direct native listener with options instead of delegating. |
EventHandler |
What event returns: the callback plus its listener options. |
set_handler, remove_handlers_for, and dispatch_event are internal
entry points used by the renderer and the kernel.
Handler props¶
- Any prop named
on_<type>(oron<Type>) is a handler:on_click,on_input,on_keydown,onChange. The prefix is stripped and the remainder lower-cased to get the DOM event type. - A handler takes the
DomEventor no arguments at all (on_click=lambda: set_open(False)); the arity is checked once, at registration. Signal writes made inside a handler are flushed automatically when it returns, so the DOM updates before the browser paints. evt.rawis the native event and is valid only synchronously during dispatch.
from wybthon import DomEvent, button, create_signal, event, form, input_, li, ul
items, set_items = create_signal([])
draft, set_draft = create_signal("")
def submit(evt: DomEvent) -> None:
evt.prevent_default()
set_items(lambda xs: [*xs, draft.peek()])
set_draft("")
def keydown(evt: DomEvent) -> None:
if evt.key == "Escape":
set_draft("")
view = form(
input_(value=draft, on_input=lambda e: set_draft(e.target.value), on_keydown=keydown),
button("Clear", type="button", on_click=lambda: set_items([])), # no event needed
ul(lambda: [li(x) for x in items()]),
on_submit=submit,
on_touchstart=event(lambda: None, passive=True), # direct native listener
)
Delegation notes¶
- Delegation relies on bubbling, so non-bubbling types (
focus,blur,mouseenter,mouseleave,pointerenter,pointerleave,scroll,load,error,invalid, andtoggle) get a direct native listener on the element instead. For listener options such aspassiveorcapture, wrap the handler inevent, which also attaches a direct listener. stop_propagation()stops both the delegated walk and native propagation;prevent_default()is applied by the kernel after the handler returns.- Unmounting a subtree drops its handlers on the Python side, and the
kernel's
DISPOSE_RANGEorDISPOSEcommand clears its listener bookkeeping natively.Root.dispose()unregisters the container as a delegation root. - In CPython tests,
wybthon.testingfires events through the real dispatcher:fire.click(node),fire.input(node, value),fire.key_down(node, key).
See also¶
- HTML helpers: how handler props are recognized
- Kernel:
REGISTER_TPL,LISTEN,UNLISTEN,ROOT, and the dispatch payload - Concepts: Events
- Concepts: Forms