Skip to main content

makepad-2-0-troubleshooting

CRITICAL: Use for Makepad 2.0 troubleshooting and common mistakes. Triggers on: makepad error, makepad bug, makepad problem, makepad issue, makepad not working, text invisible, widget not showing, click not working, height zero, makepad pitfall, makepad gotcha, makepad FAQ, makepad help, script_mod error, compile error, widget not found, render not updating, hot reload not working, wasm build error, port conflict, server lock, IME popup, selection handle, popup window crash, canvas splash, POST splash loop, 100% CPU, set_visible not working, on_render empty, event bridge unreliable, float time display, fn tick not called, on_audio not called, button click through, 常见错误, 问题排查, 故障排除, 不显示, 不工作, 看不见, 热重载, 编译错误

الانتقال إلى التثبيت

معلومات المصدر

المستودع
ZhangHanDong/makepad-skills
آخر نشاط في المصدر
٧ أبريل ٢٠٢٦ في ١٥:٥٠
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٧٤٨
التفرعات
٨٧

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
2 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
makepad-2.0-troubleshooting
description
CRITICAL: Use for Makepad 2.0 troubleshooting and common mistakes. Triggers on: makepad error, makepad bug, makepad problem, makepad issue, makepad not working, text invisible, widget not showing, click not working, height zero, makepad pitfall, makepad gotcha, makepad FAQ, makepad help, script_mod error, compile error, widget not found, render not updating, hot reload not working, wasm build error, port conflict, server lock, IME popup, selection handle, popup window crash, canvas splash, POST splash loop, 100% CPU, set_visible not working, on_render empty, event bridge unreliable, float time display, fn tick not called, on_audio not called, button click through, 常见错误, 问题排查, 故障排除, 不显示, 不工作, 看不见, 热重载, 编译错误
# Makepad 2.0 Common Pitfalls & Troubleshooting Guide This skill covers common mistakes when building with Makepad 2.0 and the Splash scripting language. Each pitfall includes: - What the user sees (symptom) - Why it happens (root cause) - How to fix it (correct code) Reference documents: `AGENTS.md`, `splash.md` --- ## Pitfall #1: Container height is 0px -- UI is invisible **Symptom:** Your entire UI or a section of it does not appear. The container renders with zero height, making all children invisible. **Root Cause:** All View-based containers (`View`, `SolidView`, `RoundedView`, etc.) default to `height: Fill`. When a `Fill` container is placed inside a `Fit` parent (or any context where the available height is determined by children), the height resolves to 0px due to circular dependency: the parent asks the child how tall it is, the child says "as tall as my parent", and the result is zero. **Fix:** Always set `height: Fit` on containers that should shrink-wrap their content. ``` // WRONG -- height defaults to Fill, resolves to 0px in a Fit context View{ flow: Down Label{text: "Hello"} } // CORRECT -- height: Fit makes the container wrap its children View{ height: Fit flow: Down Label{text: "Hello"} } ``` **Rule of thumb:** Write `height: Fit` immediately after the opening brace of every container unless you have a fixed-height parent or you explicitly want `height: Fill` inside a known fixed-size ancestor. **Exception:** Inside a fixed-height parent, `height: Fill` is valid: ``` View{ height: 300 View{ height: Fill Label{text: "I fill the 300px"} } } ``` --- ## Pitfall #2: Text invisible on colored background -- missing new_batch **Symptom:** You add a `Label` inside a `RoundedView` or `SolidView` with a background color, but the text is invisible. The container appears correctly colored but the text cannot be seen, even though `draw_text.color` is set to a contrasting color. **Root Cause:** Makepad batches draw calls by shader type for GPU performance. All `Label` widgets using the same text shader get batched into one draw call, and all backgrounds into another. Without `new_batch: true`, the text draw call may execute *before* the background draw call, placing the text geometrically behind the opaque background. **Fix:** Add `new_batch: true` to any View-based container that has a visible background (`show_bg: true` or pre-styled views like `SolidView`, `RoundedView`) and contains text children. ``` // WRONG -- text is drawn behind the background due to batching RoundedView{ height: Fit draw_bg.color: #333 Label{text: "Can't see me"} } // CORRECT -- new_batch forces background to draw before children's text RoundedView{ height: Fit new_batch: true draw_bg.color: #333 Label{text: "Now visible" draw_text.color: #fff} } ``` **When you MUST use `new_batch: true`:** - Any container with `show_bg: true` (or pre-styled like `SolidView`, `RoundedView`) that contains text - Hoverable items with background animator -- text disappears on hover without it - Parent containers of repeated items that each have their own background --- ## Pitfall #3: Named child override does not work -- used `:` instead of `:=` **Symptom:** You define a template with `let` and try to override a child property per-instance, but the override is silently ignored. The default text always shows. **Root Cause:** In Splash, `:` creates a **static** property, while `:=` creates a **named/dynamic** child that is addressable and overridable. If you declare `label: Label{...}` (with `:`), the child has no addressable name and the override path `label.text:` cannot find it. **Fix:** Use `:=` for any child you want to reference or override later. ``` // WRONG -- static child, override fails silently let Card = View{ height: Fit title: Label{text: "default"} } Card{title.text: "new text"} // Fails! title is not addressable // CORRECT -- named child with :=, override works let Card = View{ height: Fit title := Label{text: "default"} } Card{title.text: "new text"} // Works! title is a named child ``` **Additional rule:** Named children inside anonymous containers are UNREACHABLE. Every container in the path from root to child must also be named: ``` // WRONG -- label is inside an anonymous View, unreachable let Item = View{ height: Fit View{ flow: Down label := Label{text: "default"} } } Item{label.text: "new"} // Fails! No path to label through anonymous View // CORRECT -- full named path let Item = View{ height: Fit texts := View{ flow: Down label := Label{text: "default"} } } Item{texts.label.text: "new"} // Works! Full dot-path through named containers ``` --- ## Pitfall #4: Hex color with letter 'e' renders wrong or causes parse error **Symptom:** A hex color like `#2ecc71` causes a cryptic parse error such as `expected at least one digit in exponent`, or the color renders incorrectly. **Root Cause:** The Rust tokenizer inside `script_mod!{}` interprets a digit followed by `e` as the start of a scientific notation number (e.g., `2e` looks like `2 * 10^...`). This breaks parsing of hex colors that contain the letter `e` adjacent to digits. **Fix:** Use the `#x` prefix for any hex color containing the letter `e` or `E`. ``` // WRONG -- parser reads '2e' as scientific notation exponent draw_bg.color: #2ecc71 draw_bg.color: #1e1e2e draw_bg.color: #4466ee // CORRECT -- #x prefix escapes the hex literal draw_bg.color: #x2ecc71 draw_bg.color: #x1e1e2e draw_bg.color: #x4466ee ``` **When is `#x` NOT needed?** Colors without the letter `e` work fine with plain `#`: ``` draw_bg.color: #ff4444 // OK -- no 'e' draw_bg.color: #44cc44 // OK -- no 'e' draw_bg.color: #333 // OK -- no 'e' ``` --- ## Pitfall #5: border_radius takes wrong type -- must be float, not Inset **Symptom:** Attempting to set per-corner border radii with `Inset` causes a parse error or silently breaks the layout. The rounded corners do not appear. **Root Cause:** Border radius is a single `f32` uniform value applied uniformly to all corners. It is NOT an Inset-like struct with per-corner values. Passing an `Inset` or object silently breaks the entire layout. **CRITICAL:** The property name differs by context: - **In Canvas Splash (POST /splash):** Use `draw_bg.radius` with trailing-dot float - **In script_mod! macro:** Use `draw_bg.border_radius` **Fix:** Use a plain float value with the correct property name. ``` // WRONG -- border_radius is not an Inset draw_bg.border_radius: Inset{top_left: 10 top_right: 10} // WRONG -- not an object draw_bg.border_radius: {top: 10 bottom: 0} // CORRECT (Canvas Splash context) -- use draw_bg.radius with trailing dot draw_bg.radius: 10. // CORRECT (script_mod! context) -- use draw_bg.border_radius draw_bg.border_radius: 10.0 // For per-corner radii, use RoundedAllView with a vec4 // (top-left, top-right, right-bottom, left-bottom) RoundedAllView{ height: Fit draw_bg.border_radius: vec4(10.0 10.0 0.0 0.0) } ``` --- ## Pitfall #6: Widget not found from Rust -- registration order wrong **Symptom:** At runtime, a widget type is not found or a script error occurs saying a widget is not registered. The app may panic or display nothing. **Root Cause:** In Makepad 2.0, widget modules must be registered via `script_mod(vm)` calls in the correct order. Base widgets must be registered before custom widgets, and custom widgets before the UI that uses them. If the order is wrong, a module tries to use a widget type that has not been registered yet. **Fix:** Follow the correct registration order in `App::run()`. ```rust impl App { fn run(vm: &mut ScriptVm) -> Self { // 1. Register base widget library (theme + all standard widgets) crate::makepad_widgets::script_mod(vm); // 2. Register your custom widget modules (if any) crate::my_custom_widgets::script_mod(vm); // 3. Register your app UI module (uses widgets from steps 1 and 2) crate::app_ui::script_mod(vm); // 4. Create the app from its own script_mod App::from_script_mod(vm, self::script_mod) } } ``` **Key rule:** Widget modules must be registered BEFORE UI modules that use them. Always call `lib.rs::script_mod` before `app_ui::script_mod`. --- ## Pitfall #7: Filler clips text -- used alongside width: Fill sibling **Symptom:** Text in a horizontal layout is cut off halfway. The text label appears to have only half the available width. **Root Cause:** `Filler{}` is defined as `View{width: Fill height: Fill}`. When placed next to a sibling that also has `width: Fill`, both compete for the remaining horizontal space and split it 50/50. The text label only gets half the width and text is clipped. **Fix:** Remove `Filler{}` when a sibling already uses `width: Fill`. The `Fill` sibling naturally takes all remaining space, pushing `Fit`-sized siblings to the edge. ``` // WRONG -- Filler splits space with Fill sibling, text is clipped View{ flow: Right height: Fit Label{width: Fill text: "Long text that gets clipped"} Filler{} Button{text: "OK"} } // CORRECT -- width: Fill on label pushes button to the right edge View{ flow: Right height: Fit Label{width: Fill text: "Long text now has full space"} Button{text: "OK"} } // CORRECT use of Filler -- between Fit-sized siblings View{ flow: Right height: Fit Label{text: "left"} Filler{} Label{text: "right"} } ``` --- ## Pitfall #8: Text disappears on hover -- animated View without new_batch **Symptom:** A list item or button has hover effects. When you hover over it, the background color changes but the text vanishes completely. Moving the cursor away brings the text back. **Root Cause:** The hover animator changes the View's background from transparent (`#0000`) to an opaque or semi-opaque color. Without `new_batch: true`, the background and text are in the same draw batch. When the background becomes opaque, it covers the text that was drawn in the same batch order. **Fix:** Add `new_batch: true` to any View with `show_bg: true` that has a hover animator and contains text. ``` // WRONG -- text disappears when hover activates the background View{ width: Fill height: Fit show_bg: true draw_bg +: { color: uniform(#0000) color_hover: uniform(#fff2) hover: instance(0.0) pixel: fn(){ return Pal.premul(self.color.mix(self.color_hover, self.hover)) } } animator: Animator{ hover: { default: @off off: AnimatorState{ from: {all: Forward {duration: 0.15}} apply: {draw_bg: {hover: 0.0}} } on: AnimatorState{ from: {all: Forward {duration: 0.15}} apply: {draw_bg: {hover: 1.0}} } } } Label{text: "Vanishes on hover!" draw_text.color: #fff} } // CORRECT -- add new_batch: true View{ width: Fill height: Fit new_batch: true show_bg: true draw_bg +: { color: uniform(#0000) color_hover: uniform(#fff2) hover: instance(0.0) pixel: fn(){ return Pal.premul(self.color.mix(self.color_hover, self.hover)) } } animator: Animator{ hover: { default: @off off: AnimatorState{ from: {all: Forward {duration: 0.15}} apply: {draw_bg: {hover: 0.0}} } on: AnimatorState{ from: {all: Forward {duration: 0.15}} apply: {draw_bg: {hover: 1.0}} } } } Label{text: "Stays visible on hover!" draw_text.color: #fff} } ``` --- ## Pitfall #9: Commas in Splash -- tolerated but not required **Symptom:** Confusion about whether commas are allowed between properties in `script_mod!` blocks. **Root Cause:** Splash is primarily whitespace-delimited. However, the Splash tokenizer **treats commas as whitespace** — they are silently consumed and do not cause parse errors. Many Makepad projects (including Robrix) use commas extensively in `script_mod!` blocks, inherited from Makepad 1.x `live_design!` syntax which required commas. **Guidance:** Both styles are valid. Match the surrounding code style: ``` // Style A: with commas (common in codebases migrated from 1.x) View{ flow: Down, height: Fit, spacing: 10, padding: Inset{top: 5, bottom: 5, left: 10, right: 10} } // Style B: without commas (pure Splash style) View{ flow: Down height: Fit spacing: 10 padding: Inset{top: 5 bottom: 5 left: 10 right: 10} } ``` **Note:** Both compile and run identically. The tokenizer discards commas. Do NOT waste time removing commas from existing code — it creates noisy diffs with no functional change. --- ## Pitfall #10: Using semicolons -- not valid in Splash **Symptom:** Parse errors or unexpected behavior. The semicolons are treated as part of property values or cause tokenizer failures. **Root Cause:** Splash does not use semicolons to terminate statements. This is a common mistake for developers coming from CSS, JavaScript, or Rust backgrounds. **Fix:** Remove all semicolons. ``` // WRONG -- semicolons are not valid View{ flow: Down; height: Fit; Label{text: "Hello";}; } // CORRECT -- no semicolons needed View{ flow: Down height: Fit Label{text: "Hello"} } ``` --- ## Pitfall #11: Root container without width: Fill -- narrow or broken layout **Symptom:** The UI appears as a narrow sliver on one side of the window, or the layout is entirely broken. Content does not fill the available window width. **Root Cause:** Using a fixed pixel width (e.g., `width: 400`) on the outermost container means it does not adapt to the available window space. If the window is wider, the content is a small strip. If narrower, content is clipped. **Fix:** Always use `width: Fill` on the root container. Fixed pixel widths are fine for inner elements. ``` // WRONG -- fixed width on root, does not adapt to window RoundedView{ width: 400 height: Fit flow: Down
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub