dispatch_studio_msg pushed to screenshot_requests but never
triggered a redraw. The GL readback that captures the screenshot
only runs during the render path, so the request was never
serviced in windowed backends (Wayland, X11, macOS).
Co-authored-by: ant <ant@offline.click>
The Contents.json only had a single universal+platform entry, which is
only recognized by iOS 16+. Add classic per-idiom entries (iphone, ipad,
ios-marketing) so actool compiles both sets into Assets.car. iOS 15
falls back to the idiom-based entries.
Co-authored-by: ant <ant@offline.click>
Move font family registration out of on_custom_apply (script apply time)
and into ensure_fonts_loaded (draw time). This avoids redundant work when
the same FontFamily is applied to hundreds of widgets during a frame.
ensure_fonts_loaded now has a fast path that checks is_font_family_complete()
and returns immediately when all expected members are already registered.
The slow path calls load_all_script_resources() to progress pending loads
before falling back to update_font_definitions().
Other changes:
- FontFamilyDefinition gains expected_member_count to distinguish partial
from complete registrations.
- set_font_family_definition skips cache eviction when the definition or
cached family is already equivalent.
- load_font_family now clones the definition instead of removing it,
allowing re-loads after cache eviction without losing the definition.
- Loader::font_family_definitions and Layouter::loader are now pub(crate)
to support the completeness query from Fonts.
---
Review observations (not yet addressed):
1. STALE FAMILY ON RE-APPLY (medium risk): If a FontFamily is re-applied
with different members but the same object index (same family_id), the
fast path in ensure_fonts_loaded will see the old definition as
"complete" and never call update_font_definitions with the new members.
Fix: compare current member handles against stored definition, or set a
dirty flag in on_custom_apply that forces one refresh.
2. UNNECESSARY LAYOUT CACHE FLUSH (medium risk): Layouter::set_font_family_definition
unconditionally clears cached_params and cached_results even when
Loader::set_font_family_definition short-circuits as unchanged. During
partial-load states ensure_fonts_loaded may call update repeatedly with
identical partial definitions, flushing the text layout cache each time.
Fix: propagate a changed bool from Loader and only clear when true.
3. COMPLETENESS IGNORES CACHE-ONLY STATE (low risk): is_font_family_complete
only checks font_family_definitions, not font_family_cache. If a family
was already loaded into cache and its definition consumed, completeness
returns false. The new early-return in set_font_family_definition for
cache-match mitigates this in practice but the invariant is fragile.
Fix: also check font_family_cache in is_font_family_complete, or ensure
definitions are always retained (which this diff partly does by switching
from remove to get+clone in load_font_family).
Co-authored-by: ant <ant@offline.click>
* Add support for Video widget on WASM
* Add support for Video widget on Linux
* Linux video: GStreamer appsink pipeline, GL texture upload, accurate seeking
* Add support for Video widget on Windows
* Harden cross-platform video playback and error handling
* Cleanup video playback logs
* Restore wasm builds
* Restore linux builds
* Restore linux builds
* Remove unused import
file_resource and crate_resource now check if a resource with the same
abs_path already exists before creating a new entry. Returns the existing
handle instead of reading the same file multiple times.
Before: 54 resource entries, same font files loaded up to 15 times each
(427MB of duplicate heap data). After: ~10 unique entries, each file
loaded once (~50MB).
Co-authored-by: ant <ant@offline.click>
Android defaults to target/android/, apple to target/apple/.
Prevents cross-platform builds from invalidating each other's caches.
Co-authored-by: ant <ant@offline.click>
Fix EGL context initialization on Android to properly wire up the GL
render bridge display/context/surface.
Add GL state reset in restore_gl_context on Linux/Android to prevent
state leakage from external GL consumers (e.g. Servo) back into the
Makepad render pipeline.
Co-authored-by: ant <ant@offline.click>
Refactor app icon handling into a unified app_icon module that replaces
the old window_icon.rs. Build-time icon generation produces platform-
native formats (ICO with multiple sizes for Windows, ICNS for macOS,
multi-resolution PNGs for Linux/Wayland/X11).
Add `cargo makepad desktop` subcommand for desktop packaging with
automatic icon detection from MAKEPAD_APP_ICON_PATH env var, or from
Cargo package metadata.
Resolve binary names from [[bin]] targets in Cargo.toml so .app bundles,
.exe outputs, and APK labels use the correct name instead of defaulting
to the package name.
Use llvm-rc for Windows .res generation (cross-compilation compatible)
with absolute link paths for reliable resource embedding.
Co-authored-by: ant <ant@offline.click>
When script_mod! is used with 'let app = startup() do ...' but the
block omits the final 'app' expression, the module returns nil. This
silently creates an App with an empty WidgetRef -- no window, no UI,
no error. The app runs indefinitely doing nothing.
Panic with an actionable message instead of silently succeeding.
Co-authored-by: ant <ant@offline.click>
* Fix draw_svg to support a rotated Icon. Add `IconRotated` widget.
Fix icon resource paths in `splash` example
* Expose geometry in draw_svg to make icon/svg rotation more efficient
simplifies the code too
The rebase squash into 6df7c870 used the early draft of window_icon.rs,
dropping the OnceLock-based global setter added in the fixup commit.
Restore from pre-rebase commit 83bf5d62:
- add static GLOBAL_ICON: OnceLock<WindowIcon>
- add pub fn set_window_icon(icon: WindowIcon)
- refactor default_window_icon() to check global override first
- re-export set_window_icon from platform lib.rs
Co-authored-by: ant <ant@offline.click>
* Remove left margin from window caption label
Delete the hardcoded Inset{left: 100} margin on the caption Label in widgets/src/window.rs so the label can be centered by the parent layout. This cleans up alignment and removes an unnecessary offset in the window header.
* Use window title in caption; format button click
Apply the configured window title to the window caption and make a small UI code cleanup.
- examples/splash: set window.title to "Splash Example" and reformat the tooltip button click check to a multiline expression for readability.
- widgets/src/window.rs: import label::* and update ensure_initialized to copy cx.windows[window_id].create_title into the caption_label when non-empty so the window chrome shows the configured title.
The CalloutTooltip is a fancier wrapper atop Tooltip that allows
the user to display a tooltip with a callout triangle that points
at a particular widget, making it clearer what the tooltip
corresponds to. It also supports a custom text color, background color,
positioning suggestion (top, right, left, bottom), full text wrapping,
and dynamically resize and re-orient itself to fit within the app screen.
New GlRenderBridge API lets external code (e.g. servo in havi) render
via GL into a makepad-displayable texture with zero-copy.
Platform backends:
- Linux/Android: wraps existing EGL context (EglRenderBridge)
- Windows: ANGLE EGL on D3D11 device via mozangle (AngleRenderBridge)
- macOS: standalone CGL 3.2 Core bridged to Metal via IOSurface (CglRenderBridge)
Cx methods: create_gl_render_bridge, create_gl_render_bridge_texture,
restore_gl_context -- all platform-dispatched via cfg.
Co-authored-by: ant <ant@offline.click>
Wayland wl_pointer::Axis values are defined as motion-event vectors:
positive vertical = downward on screen. This means positive values
represent content sliding down under the pointer, i.e. the viewport
moving UP.
Makepad's internal scroll convention is positive = viewport moves DOWN.
This matches X11 (button 4/up maps to negative, button 5/down maps to
positive) and macOS (which negates scrollingDeltaY for the same reason).
The web backend also follows this via browser deltaY semantics.
The Wayland backend was passing axis values through without negation,
producing reversed scroll on all Wayland sessions. Negate at the
accumulator stage, consistent with how winit handles the same mismatch
(explicit comment: "Wayland sign convention is the inverse of winit").
The ignored AxisRelativeDirection event is unrelated -- it is a hint
telling clients whether the compositor applied natural-scrolling
inversion to the axis values, intended for widgets like volume sliders
that should track physical finger direction. The axis values themselves
already have natural scrolling applied by the compositor.
Co-authored-by: ant <ant@offline.click>
Add WindowIcon and WindowIconBuffer types to platform/src/window.rs with
RGBA8 pixel buffer data. Embed a default 64x64 Makepad icon generated at
runtime (dark rounded rect with white M glyph).
Platform backends:
- Windows: CreateIcon from RGBA->BGRA data, set on WNDCLASSEXW.hIcon
- X11: XChangeProperty with _NET_WM_ICON atom (RGBA->ARGB u32 array)
- macOS: NSBitmapImageRep + NSImage, setApplicationIconImage on NSApp
- Wayland: vendor xdg-toplevel-icon-v1 protocol, regenerate bindings,
bind wl_shm + xdg_toplevel_icon_manager_v1 globals, create shm buffer
icon when compositor supports it, silent fallback to app_id otherwise.
Use configurable create_app_id field (default "Makepad").
Codegen: extend tools/wayland_codegen to generate xdg toplevel_icon
bindings into libs/linux/wayland-protocols/src/xdg.rs.
Co-authored-by: ant <ant@offline.click>