Azul GUI Framework

repository·master·Indexed 27 days ago

https://github.com/fschutt/azul

A functional, reactive desktop GUI framework for Rust, C, and C++ that utilizes WebRender and a CSS/HTML-like DOM for rendering. The project includes azul-core (v0.0.12) and a comprehensive toolset called azul-doc for managing the public API via api.json, generating FFI language bindings (Rust, C, C++, Python), and performing visual reference testing against Google Chrome.

Tokens
156.4K
Snippets
231
Records
877
Agent score
91%

What's inside Azul

  1. Overview of the AZUL GUI framework

    master
    Azul is a free, functional, and reactive GUI framework designed for Rust, C, and C++. It utilizes the WebRender rendering engine and a CSS/HTML-like Document Object Model (DOM) to enable rapid development of native desktop applications.
  2. Overview of ScrollManager capabilities

    master

    The ScrollManager (located in layout/src/managers/) serves as the single source of truth for scroll offsets within the AZUL framework. It manages:

    • Queuing wheel and trackpad input for physics-based movement (momentum/rubber-band).
    • Scrollbar geometry, hit-testing, and thumb dragging.
    • Easing animations and scroll-into-view logic.
    • Feeding scroll offsets to renderers.

    Note: Platform support varies. For example, macOS has full support for trackpad continuous scrolling and momentum, while Windows support is currently limited to discrete wheel events and lacks trackpad/gesture support.

  3. Overview of Azul Crate Organization

    master

    Azul is modularized into several key crates, each handling a specific domain of the GUI framework:

    • core: Contains fundamental data structures like Dom, RefAny, StyledDom, events, and resources.
    • css: Handles CSS parsing, properties (Css, CssProperty), and styling logic.
    • layout: Contains the layout engine (solver3), text shaping (text3), managers, and the LayoutWindow.
    • dll: Provides platform-specific shells (Windows, macOS, X11, Wayland) and WebRender integration.
    • webrender: A fork of Mozilla's WebRender GPU rendering engine.
  4. Understand the Scroll Physics Timer Architecture

    master

    The scroll physics system follows a specific lifecycle to handle momentum and rubber-banding:

    1. Input Capture: A platform event handler (macOS/Windows/X11/Wayland) calls ScrollManager.record_scroll_from_hit_test and pushes a ScrollInput to the ScrollInputQueue. This starts the SCROLL_MOMENTUM_TIMER_ID timer.
    2. Timer Execution: Every ~16ms, the scroll_physics_timer_callback (in layout/src/scroll_timer.rs) executes:
      • Consumes pending inputs from the queue.
      • Performs physics integration (velocity, friction, etc.).
      • Pushes CallbackChange::ScrollTo for updated nodes.
      • Returns an Update status (e.g., Update::RefreshDom or Update::DoNothing).
    3. Result Flow: The timer result is collected via run_single_timer() into a CallCallbacksResult. This result is then processed by the platform's timer handler (e.g., tick_timers()), which calls process_callback_result_v2() to trigger scroll_manager.scroll_to() and eventually scroll_all_nodes(txn) to update WebRender offsets.
  5. Current status of Smalltalk bindings

    master

    The Smalltalk bindings for Azul are currently not functional and cannot be loaded into any Smalltalk system (Pharo or GNU Smalltalk).

    Critical issues include:

    • Unloadable Artifacts: The generated Azul.st file uses a single-file Tonel format that is incompatible with Pharo's fileIn (which expects chunk-format) and requires a per-package directory layout that is not currently provided. GNU Smalltalk (gst) also fails to parse the file.
    • Missing Features: There is no bridge for converting Smalltalk Strings to AzString, and no support for callbacks (typedefs are erased to void*).
    • Documentation Errors: Existing installation guides in api.json and examples/smalltalk/README.md contain incorrect steps and false claims regarding compatibility with GNU Smalltalk.
  6. Understand the TextInputManager workflow

    master

    The TextInputManager (located in layout/src/managers/text_input.rs) manages text-edit changesets using a two-phase process:

    1. Record Phase: Captures keyboard, IME, accessibility, or programmatic insertions as PendingTextEdit objects.
    2. Emit Phase: Emits EventType::Input via the EventProvider.
    3. Apply Phase: Applies the changes (or clears them if preventDefault is called) using LayoutWindow::apply_text_changeset.

    This manager is designed with a minimal surface area; the primary logic resides in LayoutWindow and TextEditManager.

  7. Understand CSS Transforms in the rendering pipeline

    master

    CSS transforms follow a specific pipeline to move from style definitions to hardware-accelerated rendering:

    1. StyleTransform (CSS definition)
    2. ComputedTransform3D (Resolved value)
    3. WebRender matrix pipeline (Final rendering)

    The system utilizes SIMD acceleration and supports various coordinate systems and rotation modes.

  8. Understand the azul-mini.wasm loading architecture

    master

    The azul-mini.wasm deployment follows a layered loading strategy to minimize initial Time to Interactive (TTI):

    1. Boot Module: Contains hydrate, dispatchEvent, hit-test, patch-builder, and allocator/libc shims. Target size: < 500 KB.
    2. Layout Module: Contains solver3 and text3 measurement. This is loaded lazily upon the first event that requires layout mutation.
    3. Callback Shards: Individual WASM modules for application-specific callbacks.
    4. On-demand Shards: Any code required by the call graph that was not in the initial closure is fetched via a missing_block trap (lazy lift-and-fetch).
  9. Understand the Rendering Pipeline

    master

    Azul uses the Mozilla WebRender engine for high-performance, GPU-accelerated rendering. The pipeline follows these steps:

    1. Display List Generation: After layout, LayoutWindow calls layout_and_generate_display_list() to create a DisplayList containing primitives like Rect, Border, Text, Image, and PushStackingContext.
    2. WebRender Translation: The compositor2 module translates Azul primitives into WebRender formats (e.g., converting font hashes into FontKey and FontInstanceKey).
    3. Resource Synchronization: The translation generates ResourceUpdate messages (such as AddFont or AddImage) to inform the GPU thread of new assets.
    4. Transaction Submission: All commands, resource updates, and scroll offsets are packaged into a WebRender Transaction and sent to the Render Backend thread.
    5. Scene Building: The Render Backend builds the stacking context tree and scene primitives, then signals the main thread when the frame is ready.
    6. Presentation: The main thread triggers a buffer swap (via OS events like WM_PAINT) to present the frame. Note that GPU-accelerated properties like opacity and transform can update the frame without a full layout pass.
  10. Understand the GestureAndDragManager capabilities

    master

    The GestureAndDragManager (located in layout/src/managers/gesture.rs) is responsible for recording mouse/pen input sessions and detecting multi-frame gestures such as drags, double/triple-clicks, long-presses, swipes, pinches, and rotations. It also manages the unified DragContext for node and window drags, pen state, and Wacom-pad state.

    Key Capabilities

    • Input Session Recording: Uses PlatformWindow::record_input_sample (defined in common/event.rs) to feed input data to the manager.
    • Pointer Capture: Supports keeping motion delivery active even when the pointer moves outside the window boundaries (implementation varies by platform).
    • Gesture Detection:
      • Drag: Detects DragStart, Drag, DragEnd, and Drop events using a 5px threshold (detect_drag in gesture.rs:117).
      • Clicks: Detects double/triple-clicks via detect_double_click and detect_click_count.
      • Long-press: Detects LongPress events via detect_long_press.
      • Swipe: Detects SwipeLeft, SwipeRight, SwipeUp, and SwipeDown using velocity heuristics via detect_swipe_direction.
      • Pinch/Rotate: Detects pinch and rotation gestures via detect_pinch and detect_rotation (requires two concurrent sessions).
    • Drag-and-Drop (DnD):
      • Node DnD: Automatically activates via activate_node_drag on a DragStart over a draggable node.
      • Window Move: Provides context for window dragging via activate_window_drag, though actual movement is often handled by titlebar callbacks using get_drag_delta_screen_incremental.
    • Pen/Stylus Support: Tracks pen state (pressure, tilt, twist, eraser) via update_pen_state_full, emitting PenEnter, PenLeave, PenDown, PenUp, and PenMove events.
    • Wacom Tablet-Pad Support: Provides interfaces for update_pad_state, get_pad_state, express keys, and touch rings (Note: availability depends on backend implementation).
  11. Understand the XmlComponent System

    master

    The current component system in Azul is based on the XmlComponentTrait defined in core/src/xml.rs. This system allows for defining components that can render a DOM and compile to Rust code.

    Key concepts include:

    • XmlComponentTrait: A Rust trait requiring implementations for get_type_id, get_xml_node, get_available_arguments, render_dom, and compile_to_rust_code.
    • XmlComponent: A struct containing an ID, a boxed renderer implementing the trait, and inherited variables.
    • XmlComponentMap: A flat BTreeMap that stores components by name. Note that this system currently lacks namespacing and uses a single global namespace.
    • DynamicXmlComponent: Components defined via XML (e.g., <component name="..." args="a: String">). These use a system-defined implementation where the system walks the XML template tree to generate code.
    • ComponentArguments: Defines the arguments a component accepts, including their names, types, and whether it accepts text content.