Antigravity-awesome-skills makepad-event-action
install
source · Clone the upstream repo
git clone https://github.com/sickn33/antigravity-awesome-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/sickn33/antigravity-awesome-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/antigravity-awesome-skills/skills/makepad-event-action" ~/.claude/skills/sickn33-antigravity-awesome-skills-makepad-event-action-d4625f && rm -rf "$T"
manifest:
plugins/antigravity-awesome-skills/skills/makepad-event-action/SKILL.mdsource content
Makepad Event/Action Skill
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:
- Handling events: Mouse, keyboard, touch, lifecycle events
- Creating actions: Widget-to-parent communication
- Event flow: Understanding event propagation
When to Use
- You need to handle input, lifecycle, or UI interaction events in Makepad.
- The task involves
,handle_event
variants,Event
processing, or widget action propagation.Hit - You need to design or debug Makepad event/action flow between widgets and parents.
Documentation
Refer to the local files for detailed documentation:
- Event enum and handling./references/event-system.md
- Action trait and patterns./references/action-system.md
IMPORTANT: Documentation Completeness Check
Before answering questions, Claude MUST:
- Read the relevant reference file(s) listed above
- If file read fails or file is empty:
- Inform user: "本地文档不完整,建议运行
更新文档"/sync-crate-skills makepad --force - Still answer based on SKILL.md patterns + built-in knowledge
- Inform user: "本地文档不完整,建议运行
- If reference file exists, incorporate its content into the answer
Event Enum (Key Variants)
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), }
Handling Events in Widgets
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); } } _ => {} } } }
Hit Enum
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, }
Action System
Defining Actions
#[derive(Clone, Debug, DefaultNone)] pub enum ButtonAction { None, Clicked, Pressed, Released, } // DefaultNone derives Default returning None variant
Emitting Actions
// From main thread (in handle_event) cx.action(ButtonAction::Clicked); // From any thread (thread-safe) Cx::post_action(MyAction::DataLoaded(data));
Handling Actions
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 } } }
Widget Action Helpers
// 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>; }
Event Flow
- Event arrives from platform layer
- Root widget receives event first
- Propagates down to children via
handle_event - Widgets emit actions via
cx.action() - Parent captures actions via
cx.capture_actions() - App handles remaining actions
Timer and NextFrame
// 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 } }
When Answering Questions
- Use
to check if event targets a widgetevent.hits(cx, area) - Actions flow UP from child to parent (unlike events which flow DOWN)
- Use
to intercept child actionscx.capture_actions()
is thread-safe for async operationsCx::post_action()
derive macro auto-implements Default for enumsDefaultNone
Limitations
- Use this skill only when the task clearly matches the scope described above.
- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.