Add gradient brush ABI support (LinearGradientBrush/RadialGradientBrush) - #7
Merged
Marc-André Moreau (mamoreau-devolutions) merged 2 commits intoSep 12, 2026
Conversation
Introduces IAvnGradientBrush/IAvnLinearGradientBrush/IAvnRadialGradientBrush as new sibling COM interfaces alongside the existing solid-only IAvnBrush (v1 unchanged). IAvnControlFactory gains create_linear_gradient_brush and create_radial_gradient_brush, requiring its IID to move from ABI version 13 to 14. - C# IR/generator layer emits the new interfaces, native header, and factory methods (IR schema bumped to v17). - Rust avalonia-sys exposes the raw vtables/structs; avalonia adds safe LinearGradientBrush/RadialGradientBrush/Paint/GradientStop/SpreadMethod/ RelativePoint/RelativeScalar types. - Existing chrome properties (Background/BorderBrush/Foreground) remain solid-brush-only by design; reading a gradient there still returns AVN_E_NONSOLIDBRUSH. - Updates hardcoded factory ABI version expectations (13->14) across the C# and Rust ABI test suites, and adds new tests covering the gradient interfaces' shapes/IIDs and safe-API value semantics. - Documents the new capability in MARSHALLING.md/README.md/COMPATIBILITY.md and bumps release-manifest.json's projectionIr schema to 17.
…lid-only A rubber-duck review of PR #7 caught a real regression: the generator's FromBrush/ToBrush helpers (used by every existing Background/BorderBrush/ Foreground getter and setter) special-cased gradient brushes, silently routing them through the solid-only IAvnBrush property path instead of throwing AVN_E_NONSOLIDBRUSH as documented and originally tested. This contradicted the PR's own stated scope decision (existing chrome properties stay solid-brush-only in this wave) and broke BrushMemberComTests.A_non_solid_brush_fails_explicitly_instead_of_picking_a_nearest_colour. Fix: remove the gradient special-casing from ComSourceEmitter's emitted FromBrush/ToBrush methods, restoring the solid-only behavior for existing properties. Gradient objects still separately implement IAvnBrush at the class level (AvnLinearGradientBrush/AvnRadialGradientBrush), where GetColor correctly returns AVN_E_NONSOLIDBRUSH by design - that path was already correct and is unchanged. No ABI/IID/header changes result from this fix (regenerated header/IR/ Rust bindings are byte-identical); only IAvnBrush.g.cs's static helper methods changed. Verified: Avalonia.Host.Tests 375/375 pass (was 374/375), Avalonia.Projection.Ir.Tests 129/129 pass, and the full non-host-dependent Rust test suite passes.
Marc-André Moreau (mamoreau-devolutions)
deleted the
copilot/expand-avalonia-api-coverage
branch
September 12, 2026 14:35
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Expands Avalonia API coverage in Rustolonia with gradient brush support (
LinearGradientBrush/RadialGradientBrush), following the existing "sibling interface + QueryInterface" versioning pattern.What changed
IAvnGradientBrush/IAvnLinearGradientBrush/IAvnRadialGradientBrush.IAvnBrushv1 (solid-color only) is untouched.IAvnControlFactorygainscreate_linear_gradient_brush/create_radial_gradient_brush, which required bumping its deterministic IID from ABI version 13 → 14.ProjectionIrv16→17) + generator emits the new interfaces, native header, and factory methods.avalonia-sysexposes the raw vtables/structs.avaloniaadds safeLinearGradientBrush,RadialGradientBrush,Paint,GradientStop,SpreadMethod,RelativePoint,RelativeScalartypes.Background/BorderBrush/Foreground) remain solid-brush-only — reading a gradient-backed brush off them still returnsAVN_E_NONSOLIDBRUSH. Wiring gradients into control properties is left for a future wave.ClrTypeExtractorTests.cs) and Rust (brush_abi.rs,control_abi.rs,definitions_abi.rs,wave_a_abi.rs…wave_k_abi.rs) ABI test suites.rust/avalonia-sys/tests/gradient_brush_abi.rs(interface shapes/IIDs/vtable slots) andrust/avalonia/tests/gradient_brush_round_trip.rs(safe-API value semantics).rust/MARSHALLING.md(new "Gradient brushes" section),rust/README.md,rust/COMPATIBILITY.md(IR v17 + gradient-wave ABI notes).rust/release-manifest.jsonbumped to IR v17.Testing
cargo test -p avalonia-sys --locked: 77/77 passing (excludes pre-existing host-binary-dependentnativeaot_fixturetests, unrelated/environment-gated).cargo test -p avalonia --locked: all passing.cargo test -p avalonia-bindgen --locked: 50/50 passing.dotnet test tests\Avalonia.Projection.Ir.Tests\Avalonia.Projection.Ir.Tests.csproj -c Release: 129/129 passing.dotnet build host\Avalonia.Host.csproj -c Release: succeeded, 0 errors.