bundled-skills/makepad-event-action/SKILL.md
CRITICAL: Use for Makepad event and action handling. Triggers on: makepad event, makepad action, Event enum, ActionTrait, handle_event, MouseDown, KeyDown, TouchUpdate, Hit, FingerDown, post_action, makepad 事件, makepad action, 事件处理
npx skillsauth add FrancoStino/opencode-skills-antigravity makepad-event-actionInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Version: makepad-widgets (dev branch) | Last Updated: 2026-01-19
Check for updates: https://crates.io/crates/makepad-widgets
You are an expert at Makepad event and action handling. Help users by:
handle_event, Event variants, Hit processing, or widget action propagation.Refer to the local files for detailed documentation:
./references/event-system.md - Event enum and handling./references/action-system.md - Action trait and patternsBefore answering questions, Claude MUST:
/sync-crate-skills makepad --force 更新文档"pub enum Event {
// Lifecycle
Startup,
Shutdown,
Foreground,
Background,
Resume,
Pause,
// Drawing
Draw(DrawEvent),
LiveEdit,
// Window
WindowGotFocus(WindowId),
WindowLostFocus(WindowId),
WindowGeomChange(WindowGeomChangeEvent),
WindowClosed(WindowClosedEvent),
// Mouse
MouseDown(MouseDownEvent),
MouseMove(MouseMoveEvent),
MouseUp(MouseUpEvent),
Scroll(ScrollEvent),
// Touch
TouchUpdate(TouchUpdateEvent),
// Keyboard
KeyDown(KeyEvent),
KeyUp(KeyEvent),
TextInput(TextInputEvent),
TextCopy(TextClipboardEvent),
// Timer
Timer(TimerEvent),
NextFrame(NextFrameEvent),
// Network
HttpResponse(HttpResponse),
// Widget Actions
Actions(ActionsBuf),
}
impl Widget for MyWidget {
fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
// Check if event hits this widget's area
match event.hits(cx, self.area()) {
Hit::FingerDown(fe) => {
// Mouse/touch down on this widget
cx.action(MyWidgetAction::Pressed);
}
Hit::FingerUp(fe) => {
if fe.is_over {
// Released while still over widget = click
cx.action(MyWidgetAction::Clicked);
}
}
Hit::FingerHoverIn(_) => {
self.animator_play(cx, id!(hover.on));
}
Hit::FingerHoverOut(_) => {
self.animator_play(cx, id!(hover.off));
}
Hit::KeyDown(ke) => {
if ke.key_code == KeyCode::Return {
cx.action(MyWidgetAction::Submitted);
}
}
_ => {}
}
}
}
pub enum Hit {
// Finger/Mouse
FingerDown(FingerDownEvent),
FingerUp(FingerUpEvent),
FingerMove(FingerMoveEvent),
FingerHoverIn(FingerHoverEvent),
FingerHoverOver(FingerHoverEvent),
FingerHoverOut(FingerHoverEvent),
FingerLongPress(FingerLongPressEvent),
// Keyboard
KeyDown(KeyEvent),
KeyUp(KeyEvent),
KeyFocus,
KeyFocusLost,
TextInput(TextInputEvent),
TextCopy,
// Nothing
Nothing,
}
#[derive(Clone, Debug, DefaultNone)]
pub enum ButtonAction {
None,
Clicked,
Pressed,
Released,
}
// DefaultNone derives Default returning None variant
// From main thread (in handle_event)
cx.action(ButtonAction::Clicked);
// From any thread (thread-safe)
Cx::post_action(MyAction::DataLoaded(data));
fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
// Handle child widget actions
let actions = cx.capture_actions(|cx| {
self.button.handle_event(cx, event, scope);
});
// Check for specific action
if self.button(id!(my_button)).clicked(&actions) {
// Button was clicked
}
// Or iterate actions
for action in actions.iter() {
if let Some(ButtonAction::Clicked) = action.downcast_ref() {
// Handle click
}
}
}
// Common widget action checks
impl ButtonRef {
fn clicked(&self, actions: &ActionsBuf) -> bool;
fn pressed(&self, actions: &ActionsBuf) -> bool;
fn released(&self, actions: &ActionsBuf) -> bool;
}
impl TextInputRef {
fn changed(&self, actions: &ActionsBuf) -> Option<String>;
fn returned(&self, actions: &ActionsBuf) -> Option<String>;
}
handle_eventcx.action()cx.capture_actions()// Start a timer
let timer = cx.start_timer(1.0); // 1 second
// In handle_event
if let Event::Timer(te) = event {
if te.timer_id == self.timer {
// Timer fired
}
}
// Request next frame callback
let next_frame = cx.new_next_frame();
// In handle_event
if let Event::NextFrame(ne) = event {
if ne.frame_id == self.next_frame {
// Next frame arrived
}
}
event.hits(cx, area) to check if event targets a widgetcx.capture_actions() to intercept child actionsCx::post_action() is thread-safe for async operationsDefaultNone derive macro auto-implements Default for enumsresearch
Skill for academic research workflows: search Semantic Scholar (200M+ papers), inspect citations, download arXiv PDFs, and extract PDF text. Bundles a self-contained Python CLI.
development
Turns vague prompts into 8 structured planning files for brand new projects. DO NOT use on existing codebases.
development
Maps code, architecture, and infrastructure changes to specific control IDs in PCI-DSS v4.0 and MAS TRM (Singapore financial regulator), producing an audit-traceable findings report with per-control remediation.
testing
Companion to atlas-contract. Auto-invoked by its Final Audit on caught drift; also use after Post Reviews or user requests to record a mistake. Distills drift into WHEN/DON'T/INSTEAD clauses, writes to Atlas.md after confirmation.