{"id":"9a085dc1-cf72-40c9-8d1d-fa96a81154a9","shortId":"FnMxR2","kind":"skill","title":"makepad-event-action","tagline":"CRITICAL: Use for Makepad event and action handling. Triggers on:\nmakepad event, makepad action, Event enum, ActionTrait, handle_event,\nMouseDown, KeyDown, TouchUpdate, Hit, FingerDown, post_action,\nmakepad 事件, makepad action, 事件处理","description":"# Makepad Event/Action Skill\n\n> **Version:** makepad-widgets (dev branch) | **Last Updated:** 2026-01-19\n>\n> Check for updates: https://crates.io/crates/makepad-widgets\n\nYou are an expert at Makepad event and action handling. Help users by:\n- **Handling events**: Mouse, keyboard, touch, lifecycle events\n- **Creating actions**: Widget-to-parent communication\n- **Event flow**: Understanding event propagation\n\n## When to Use\n- You need to handle input, lifecycle, or UI interaction events in Makepad.\n- The task involves `handle_event`, `Event` variants, `Hit` processing, or widget action propagation.\n- You need to design or debug Makepad event/action flow between widgets and parents.\n\n## Documentation\n\nRefer to the local files for detailed documentation:\n- `./references/event-system.md` - Event enum and handling\n- `./references/action-system.md` - Action trait and patterns\n\n## IMPORTANT: Documentation Completeness Check\n\n**Before answering questions, Claude MUST:**\n\n1. Read the relevant reference file(s) listed above\n2. If file read fails or file is empty:\n   - Inform user: \"本地文档不完整，建议运行 `/sync-crate-skills makepad --force` 更新文档\"\n   - Still answer based on SKILL.md patterns + built-in knowledge\n3. If reference file exists, incorporate its content into the answer\n\n## Event Enum (Key Variants)\n\n```rust\npub enum Event {\n    // Lifecycle\n    Startup,\n    Shutdown,\n    Foreground,\n    Background,\n    Resume,\n    Pause,\n\n    // Drawing\n    Draw(DrawEvent),\n    LiveEdit,\n\n    // Window\n    WindowGotFocus(WindowId),\n    WindowLostFocus(WindowId),\n    WindowGeomChange(WindowGeomChangeEvent),\n    WindowClosed(WindowClosedEvent),\n\n    // Mouse\n    MouseDown(MouseDownEvent),\n    MouseMove(MouseMoveEvent),\n    MouseUp(MouseUpEvent),\n    Scroll(ScrollEvent),\n\n    // Touch\n    TouchUpdate(TouchUpdateEvent),\n\n    // Keyboard\n    KeyDown(KeyEvent),\n    KeyUp(KeyEvent),\n    TextInput(TextInputEvent),\n    TextCopy(TextClipboardEvent),\n\n    // Timer\n    Timer(TimerEvent),\n    NextFrame(NextFrameEvent),\n\n    // Network\n    HttpResponse(HttpResponse),\n\n    // Widget Actions\n    Actions(ActionsBuf),\n}\n```\n\n## Handling Events in Widgets\n\n```rust\nimpl Widget for MyWidget {\n    fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {\n        // Check if event hits this widget's area\n        match event.hits(cx, self.area()) {\n            Hit::FingerDown(fe) => {\n                // Mouse/touch down on this widget\n                cx.action(MyWidgetAction::Pressed);\n            }\n            Hit::FingerUp(fe) => {\n                if fe.is_over {\n                    // Released while still over widget = click\n                    cx.action(MyWidgetAction::Clicked);\n                }\n            }\n            Hit::FingerHoverIn(_) => {\n                self.animator_play(cx, id!(hover.on));\n            }\n            Hit::FingerHoverOut(_) => {\n                self.animator_play(cx, id!(hover.off));\n            }\n            Hit::KeyDown(ke) => {\n                if ke.key_code == KeyCode::Return {\n                    cx.action(MyWidgetAction::Submitted);\n                }\n            }\n            _ => {}\n        }\n    }\n}\n```\n\n## Hit Enum\n\n```rust\npub enum Hit {\n    // Finger/Mouse\n    FingerDown(FingerDownEvent),\n    FingerUp(FingerUpEvent),\n    FingerMove(FingerMoveEvent),\n    FingerHoverIn(FingerHoverEvent),\n    FingerHoverOver(FingerHoverEvent),\n    FingerHoverOut(FingerHoverEvent),\n    FingerLongPress(FingerLongPressEvent),\n\n    // Keyboard\n    KeyDown(KeyEvent),\n    KeyUp(KeyEvent),\n    KeyFocus,\n    KeyFocusLost,\n    TextInput(TextInputEvent),\n    TextCopy,\n\n    // Nothing\n    Nothing,\n}\n```\n\n## Action System\n\n### Defining Actions\n\n```rust\n#[derive(Clone, Debug, DefaultNone)]\npub enum ButtonAction {\n    None,\n    Clicked,\n    Pressed,\n    Released,\n}\n\n// DefaultNone derives Default returning None variant\n```\n\n### Emitting Actions\n\n```rust\n// From main thread (in handle_event)\ncx.action(ButtonAction::Clicked);\n\n// From any thread (thread-safe)\nCx::post_action(MyAction::DataLoaded(data));\n```\n\n### Handling Actions\n\n```rust\nfn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {\n    // Handle child widget actions\n    let actions = cx.capture_actions(|cx| {\n        self.button.handle_event(cx, event, scope);\n    });\n\n    // Check for specific action\n    if self.button(id!(my_button)).clicked(&actions) {\n        // Button was clicked\n    }\n\n    // Or iterate actions\n    for action in actions.iter() {\n        if let Some(ButtonAction::Clicked) = action.downcast_ref() {\n            // Handle click\n        }\n    }\n}\n```\n\n## Widget Action Helpers\n\n```rust\n// Common widget action checks\nimpl ButtonRef {\n    fn clicked(&self, actions: &ActionsBuf) -> bool;\n    fn pressed(&self, actions: &ActionsBuf) -> bool;\n    fn released(&self, actions: &ActionsBuf) -> bool;\n}\n\nimpl TextInputRef {\n    fn changed(&self, actions: &ActionsBuf) -> Option<String>;\n    fn returned(&self, actions: &ActionsBuf) -> Option<String>;\n}\n```\n\n## Event Flow\n\n1. **Event arrives** from platform layer\n2. **Root widget** receives event first\n3. **Propagates down** to children via `handle_event`\n4. **Widgets emit actions** via `cx.action()`\n5. **Parent captures actions** via `cx.capture_actions()`\n6. **App handles** remaining actions\n\n## Timer and NextFrame\n\n```rust\n// Start a timer\nlet timer = cx.start_timer(1.0); // 1 second\n\n// In handle_event\nif let Event::Timer(te) = event {\n    if te.timer_id == self.timer {\n        // Timer fired\n    }\n}\n\n// Request next frame callback\nlet next_frame = cx.new_next_frame();\n\n// In handle_event\nif let Event::NextFrame(ne) = event {\n    if ne.frame_id == self.next_frame {\n        // Next frame arrived\n    }\n}\n```\n\n## When Answering Questions\n\n1. Use `event.hits(cx, area)` to check if event targets a widget\n2. Actions flow UP from child to parent (unlike events which flow DOWN)\n3. Use `cx.capture_actions()` to intercept child actions\n4. `Cx::post_action()` is thread-safe for async operations\n5. `DefaultNone` derive macro auto-implements Default for enums\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.","tags":["makepad","event","action","antigravity","awesome","skills","sickn33","agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding"],"capabilities":["skill","source-sickn33","skill-makepad-event-action","topic-agent-skills","topic-agentic-skills","topic-ai-agent-skills","topic-ai-agents","topic-ai-coding","topic-ai-workflows","topic-antigravity","topic-antigravity-skills","topic-claude-code","topic-claude-code-skills","topic-codex-cli","topic-codex-skills"],"categories":["antigravity-awesome-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/sickn33/antigravity-awesome-skills/makepad-event-action","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add sickn33/antigravity-awesome-skills","source_repo":"https://github.com/sickn33/antigravity-awesome-skills","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 34726 github stars · SKILL.md body (6,388 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-23T12:51:12.519Z","embedding":null,"createdAt":"2026-04-18T21:40:24.254Z","updatedAt":"2026-04-23T12:51:12.519Z","lastSeenAt":"2026-04-23T12:51:12.519Z","tsv":"'-01':48 '-19':49 '/crates/makepad-widgets':55 '/references/action-system.md':143 '/references/event-system.md':138 '/sync-crate-skills':179 '1':157,533,583,630 '1.0':582 '2':166,539,642 '2026':47 '3':193,545,655 '4':553,663 '5':559,674 '6':566 'action':4,11,18,30,34,64,77,114,144,262,263,383,386,406,425,430,448,450,452,462,469,475,477,490,495,502,508,514,522,528,556,562,565,570,643,658,662,666 'action.downcast':485 'actions.iter':479 'actionsbuf':264,503,509,515,523,529 'actiontrait':21 'answer':153,184,203,628 'app':567 'area':294,634 'arriv':535,626 'ask':717 'async':672 'auto':679 'auto-impl':678 'background':216 'base':185 'bool':504,510,516 'boundari':725 'branch':44 'built':190 'built-in':189 'button':467,470 'buttonact':394,415,483 'buttonref':498 'callback':603 'captur':561 'chang':520 'check':50,151,287,459,496,636 'child':446,647,661 'children':549 'clarif':719 'claud':155 'clear':692 'click':321,324,396,416,468,472,484,488,500 'clone':389 'code':344 'common':493 'communic':82 'complet':150 'content':200 'crates.io':54 'crates.io/crates/makepad-widgets':53 'creat':76 'criteria':728 'critic':5 'cx':279,281,297,329,336,423,437,439,453,456,633,664 'cx.action':307,322,347,414,558 'cx.capture':451,564,657 'cx.new':607 'cx.start':580 'data':428 'dataload':427 'debug':121,390 'default':401,681 'defaultnon':391,399,675 'defin':385 'deriv':388,400,676 'describ':696 'design':119 'detail':136 'dev':43 'document':129,137,149 'draw':219,220 'drawev':221 'emit':405,555 'empti':174 'enum':20,140,205,210,351,354,393,683 'environ':708 'environment-specif':707 'event':3,9,16,19,23,62,70,75,83,86,100,107,108,139,204,211,266,276,282,283,289,413,434,440,441,455,457,531,534,543,552,587,590,593,612,615,618,638,651 'event.hits':296,632 'event/action':37,123 'exist':197 'expert':59,713 'fail':170 'fe':301,312 'fe.is':314 'file':134,162,168,172,196 'finger/mouse':356 'fingerdown':28,300,357 'fingerdownev':358 'fingerhoverev':364,366,368 'fingerhoverin':326,363 'fingerhoverout':333,367 'fingerhoverov':365 'fingerlongpress':369 'fingerlongpressev':370 'fingermov':361 'fingermoveev':362 'fingerup':311,359 'fingerupev':360 'fire':599 'first':544 'flow':84,124,532,644,653 'fn':274,432,499,505,511,519,525 'forc':181 'foreground':215 'frame':602,606,609,623,625 'handl':12,22,65,69,94,106,142,265,275,412,429,433,445,487,551,568,586,611 'help':66 'helper':491 'hit':27,110,290,299,310,325,332,339,350,355 'hover.off':338 'hover.on':331 'httprespons':259,260 'id':330,337,465,596,621 'impl':270,497,517 'implement':680 'import':148 'incorpor':198 'inform':175 'input':95,722 'interact':99 'intercept':660 'involv':105 'iter':474 'ke':341 'ke.key':343 'key':206 'keyboard':72,244,371 'keycod':345 'keydown':25,245,340,372 'keyev':246,248,373,375 'keyfocus':376 'keyfocuslost':377 'keyup':247,374 'knowledg':192 'last':45 'layer':538 'let':449,481,578,589,604,614 'lifecycl':74,96,212 'limit':684 'list':164 'liveedit':222 'local':133 'macro':677 'main':409 'makepad':2,8,15,17,31,33,36,41,61,102,122,180 'makepad-event-act':1 'makepad-widget':40 'match':295,693 'miss':730 'mous':71,232 'mouse/touch':302 'mousedown':24,233 'mousedownev':234 'mousemov':235 'mousemoveev':236 'mouseup':237 'mouseupev':238 'must':156 'mut':277,280,285,435,438,443 'myaction':426 'mywidget':273 'mywidgetact':308,323,348 'ne':617 'ne.frame':620 'need':92,117 'network':258 'next':601,605,608,624 'nextfram':256,573,616 'nextframeev':257 'none':395,403 'noth':381,382 'oper':673 'option':524,530 'output':702 'parent':81,128,560,649 'pattern':147,188 'paus':218 'permiss':723 'platform':537 'play':328,335 'post':29,424,665 'press':309,397,506 'process':111 'propag':87,115,546 'pub':209,353,392 'question':154,629 'read':158,169 'receiv':542 'ref':486 'refer':130,161,195 'releas':316,398,512 'relev':160 'remain':569 'request':600 'requir':721 'resum':217 'return':346,402,526 'review':714 'root':540 'rust':208,269,352,387,407,431,492,574 'safe':422,670 'safeti':724 'scope':284,286,442,444,458,695 'scroll':239 'scrollev':240 'second':584 'self':278,436,501,507,513,521,527 'self.animator':327,334 'self.area':298 'self.button':464 'self.button.handle':454 'self.next':622 'self.timer':597 'shutdown':214 'skill':38,687 'skill-makepad-event-action' 'skill.md':187 'source-sickn33' 'specif':461,709 'start':575 'startup':213 'still':183,318 'stop':715 'submit':349 'substitut':705 'success':727 'system':384 'target':639 'task':104,691 'te':592 'te.timer':595 'test':711 'textclipboardev':252 'textcopi':251,380 'textinput':249,378 'textinputev':250,379 'textinputref':518 'thread':410,419,421,669 'thread-saf':420,668 'timer':253,254,571,577,579,581,591,598 'timerev':255 'topic-agent-skills' 'topic-agentic-skills' 'topic-ai-agent-skills' 'topic-ai-agents' 'topic-ai-coding' 'topic-ai-workflows' 'topic-antigravity' 'topic-antigravity-skills' 'topic-claude-code' 'topic-claude-code-skills' 'topic-codex-cli' 'topic-codex-skills' 'touch':73,241 'touchupd':26,242 'touchupdateev':243 'trait':145 'treat':700 'trigger':13 'ui':98 'understand':85 'unlik':650 'updat':46,52 'use':6,90,631,656,685 'user':67,176 'valid':710 'variant':109,207,404 'version':39 'via':550,557,563 'widget':42,79,113,126,261,268,271,292,306,320,447,489,494,541,554,641 'widget-to-par':78 'window':223 'windowclos':230 'windowclosedev':231 'windowgeomchang':228 'windowgeomchangeev':229 'windowgotfocus':224 'windowid':225,227 'windowlostfocus':226 '事件':32 '事件处理':35 '建议运行':178 '更新文档':182 '本地文档不完整':177","prices":[{"id":"e9ddcdf8-4821-4b6d-a710-fbc0ea669b7e","listingId":"9a085dc1-cf72-40c9-8d1d-fa96a81154a9","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"sickn33","category":"antigravity-awesome-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T21:40:24.254Z"}],"sources":[{"listingId":"9a085dc1-cf72-40c9-8d1d-fa96a81154a9","source":"github","sourceId":"sickn33/antigravity-awesome-skills/makepad-event-action","sourceUrl":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/makepad-event-action","isPrimary":false,"firstSeenAt":"2026-04-18T21:40:24.254Z","lastSeenAt":"2026-04-23T12:51:12.519Z"}],"details":{"listingId":"9a085dc1-cf72-40c9-8d1d-fa96a81154a9","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"sickn33","slug":"makepad-event-action","github":{"repo":"sickn33/antigravity-awesome-skills","stars":34726,"topics":["agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows","antigravity","antigravity-skills","claude-code","claude-code-skills","codex-cli","codex-skills","cursor","cursor-skills","developer-tools","gemini-cli","gemini-skills","kiro","mcp","skill-library"],"license":"mit","html_url":"https://github.com/sickn33/antigravity-awesome-skills","pushed_at":"2026-04-23T06:41:03Z","description":"Installable GitHub library of 1,400+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and more. Includes installer CLI, bundles, workflows, and official/community skill collections.","skill_md_sha":"a1c8b56b1f6c5b0fbf411653a0ff9b33a60229ba","skill_md_path":"skills/makepad-event-action/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/makepad-event-action"},"layout":"multi","source":"github","category":"antigravity-awesome-skills","frontmatter":{"name":"makepad-event-action","description":"CRITICAL: Use for Makepad event and action handling. Triggers on:\nmakepad event, makepad action, Event enum, ActionTrait, handle_event,\nMouseDown, KeyDown, TouchUpdate, Hit, FingerDown, post_action,\nmakepad 事件, makepad action, 事件处理"},"skills_sh_url":"https://skills.sh/sickn33/antigravity-awesome-skills/makepad-event-action"},"updatedAt":"2026-04-23T12:51:12.519Z"}}