Skip to content

Add Svg.Controls.Skia.Maui control support#508

Merged
wieslawsoltes merged 15 commits into
masterfrom
docs/maui-compatibility-discussion-83
May 1, 2026
Merged

Add Svg.Controls.Skia.Maui control support#508
wieslawsoltes merged 15 commits into
masterfrom
docs/maui-compatibility-discussion-83

Conversation

@wieslawsoltes
Copy link
Copy Markdown
Owner

@wieslawsoltes wieslawsoltes commented Apr 22, 2026

Add Svg.Controls.Skia.Maui Control Support

Summary

This PR adds a dedicated Svg.Controls.Skia.Maui package for .NET MAUI applications that need a reusable Skia-backed SVG view. It addresses the control-support gap discussed in GitHub Discussion #83 by bringing the external-asset/source-string control model used by Svg.Controls.Skia.Uno to MAUI, while keeping SvgML.Maui positioned for inline XAML-authored SVG trees and foreignObject scenarios.

Background

Discussion #83 asked whether Svg.Skia can be used from a .NET MAUI application. The answer is now split into two supported MAUI paths:

  • Svg.Controls.Skia.Maui for external .svg files, source strings, reusable SvgSource resources, hit testing, zoom/pan, render flags, and animation playback on top of SKCanvasView.
  • SvgML.Maui for authoring the SVG element tree directly in MAUI XAML and hosting native MAUI controls inside SVG foreignObject.

Implementation

  • Added src/Svg.Controls.Skia.Maui.
  • Added Maui.Svg.Skia.Svg, a SkiaSharp.Views.Maui.Controls.SKCanvasView-based SVG control.
  • Added bindable control properties for Path, Source, SvgSource, Stretch, StretchDirection, EnableCache, Wireframe, DisableFilters, Zoom, PanX, PanY, Css, and CurrentCss.
  • Added host-driven animation properties and diagnostics matching the shared Svg.Skia animation host model.
  • Added MAUI package asset loading through FileSystem.OpenAppPackageFileAsync(...), plus absolute file and http/https source support.
  • Added reusable SvgSource loading, cloning, reloading, stream/document helpers, and cache-key handling.
  • Added layout helpers for stretch, stretch direction, zoom, pan, coordinate mapping, and hit testing.
  • Added MAUI XML namespace registration for https://github.com/svgskia/maui.
  • Hardened review findings around render/resource lifetime, stale async loads, cache toggles, invalid zoom/pan values, UI dispatch fallback, and HTTP stream ownership.
  • Updated the build and release workflows so the dedicated MAUI jobs restore, build, and pack both SvgML.Maui and Svg.Controls.Skia.Maui.
  • Kept Svg.Controls.Skia.Maui out of generated Lunet API extraction because the Docs workflow runs on Ubuntu without MAUI workloads; the package remains covered by authored docs and dedicated MAUI build/pack jobs.

Documentation

  • Added a new package article: site/articles/packages/svg-controls-skia-maui.md.
  • Updated the packages index, installation guide, getting-started overview, XAML overview, XAML index, package/namespace reference, API coverage index, and site config.
  • Updated the README package table and .NET MAUI section to explain when to use Svg.Controls.Skia.Maui versus SvgML.Maui.
  • Linked the new MAUI control package from the existing SvgML.Maui docs.
  • Updated packaging, animation, and API coverage documentation to include the new MAUI control package and its workflow path.

Validation

  • Ran dotnet format Svg.Skia.slnx --no-restore.
    • The command exited successfully, but reported expected missing-reference warnings because it was intentionally run without restore.
  • Ran dotnet format src/Svg.Controls.Skia.Maui/Svg.Controls.Skia.Maui.csproj --no-restore.
    • The command exited successfully, with expected missing-reference warnings because generated restore assets had been cleaned.
  • Ran dotnet build src/Svg.Controls.Skia.Maui/Svg.Controls.Skia.Maui.csproj -c Release.
    • Passed for net10.0-android, net10.0-ios, and net10.0-maccatalyst.
    • Existing shared-library warnings were reported outside the new MAUI control package.
  • Ran dotnet build src/Svg.Controls.Skia.Maui/Svg.Controls.Skia.Maui.csproj -c Release --no-restore.
    • Passed for net10.0-android, net10.0-ios, and net10.0-maccatalyst with zero warnings after the review fixes.
  • Ran dotnet build Svg.Skia.slnx -c Release.
    • Passed with existing repository warning noise, including NuGet advisory warnings in sample/build projects and nullable/obsolete warnings in existing code.
  • Ran dotnet test Svg.Skia.slnx -c Release --no-restore --no-build.
    • Passed: all test assemblies completed successfully, including Svg.Skia.UnitTests with 1635 passed and 593 skipped.
  • Parsed .github/workflows/build.yml and .github/workflows/release.yml.
    • Passed YAML syntax validation.
  • Ran ./build-docs.sh.
    • Passed after removing Svg.Controls.Skia.Maui from generated API extraction, avoiding the previous Ubuntu NETSDK1147 MAUI workload failure.
  • Ran git diff --check.
    • Passed with no whitespace errors.

Notes

  • Generated bin and obj output under the new MAUI package was removed before staging.
  • The PR summary file at plan/pr-summary-maui-compatibility-discussion-83.md is intentionally left uncommitted and used as the pull request description.

@wieslawsoltes wieslawsoltes changed the title Document MAUI compatibility path Add MAUI Skia SVG control support Apr 22, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e78237e04a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Svg.Controls.Skia.Maui/Svg.cs Outdated
Comment thread src/Svg.Controls.Skia.Maui/Svg.cs Outdated
@wieslawsoltes wieslawsoltes changed the title Add MAUI Skia SVG control support Add Svg.Controls.Skia.Maui control support Apr 22, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8525dc4cc5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Svg.Controls.Skia.Maui/Svg.cs Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b5a0a5090b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Svg.Controls.Skia.Maui/Svg.cs Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8954a6e09c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Svg.Controls.Skia.Maui/Svg.cs Outdated
Comment thread src/Svg.Controls.Skia.Maui/Svg.cs
Copy link
Copy Markdown
Owner Author

@wieslawsoltes wieslawsoltes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Submitted review-thread reply for commit 8954a6e.

Comment thread src/Svg.Controls.Skia.Maui/Svg.cs Outdated
Copy link
Copy Markdown
Owner Author

@wieslawsoltes wieslawsoltes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Submitted review-thread reply for commit 8954a6e.

Comment thread src/Svg.Controls.Skia.Maui/Svg.cs Outdated
Copy link
Copy Markdown
Owner Author

@wieslawsoltes wieslawsoltes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Submitted review-thread reply for commit 8954a6e.

Comment thread src/Svg.Controls.Skia.Maui/Svg.cs Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 934ba9ca93

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Svg.Controls.Skia.Maui/Svg.cs Outdated
Comment thread src/Svg.Controls.Skia.Maui/SvgSource.cs Outdated
Copy link
Copy Markdown
Owner Author

@wieslawsoltes wieslawsoltes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Submitted review-thread reply for commit 861f2f8.

Comment thread src/Svg.Controls.Skia.Maui/Svg.cs Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 861f2f8786

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Svg.Controls.Skia.Maui/Svg.cs
Comment thread src/Svg.Controls.Skia.Maui/Svg.cs Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b5ca004a31

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Svg.Controls.Skia.Maui/Svg.cs
Comment thread src/Svg.Controls.Skia.Maui/Svg.cs
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 70b1c416e1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +586 to +589
catch (OperationCanceledException)
{
DisposeResultIfOwned(result);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Treat timeout cancellations as source-load failures

ReloadSourceAsync unconditionally swallows OperationCanceledException, but remote loads can throw TaskCanceledException on HttpClient timeout even when cancellationToken was never canceled. In that case this path skips the normal failure handling and never clears the completed load token, leaving _pendingLoadCts stale and causing later lifecycle/cache logic to behave as if a load is still in flight. Please branch this catch on cancellationToken.IsCancellationRequested and route non-token cancellations through the error path.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 11ee3384c0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +613 to +616
if (clone.HasPathSource)
{
await clone.ReLoadAsync(parameters, cancellationToken).ConfigureAwait(false);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid reloading already-loaded external path sources

LoadExternalSourceAsync unconditionally calls ReLoadAsync for any clone with HasPathSource, even when no per-control parameters are being applied. For callers that pass an already-loaded SvgSource (with a valid in-memory picture), this forces unnecessary reparsing and can regress correctness: if the underlying file/path is temporarily unavailable, the reload path returns an empty result and the control clears instead of using the already-loaded clone. Gate this reload so path-backed clones are reused when no parameterized restyle is needed.

Useful? React with 👍 / 👎.

Comment on lines +112 to +116
if (System.IO.Path.IsPathRooted(path))
{
var fullPath = System.IO.Path.GetFullPath(path);
return new Uri(fullPath);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve leading-slash MAUI asset paths as package URIs

This rooted-path branch converts inputs like /Assets/icon.svg into file URIs (Path.GetFullPath + new Uri(fullPath)), so later loading goes through file-system checks instead of maui-app package asset resolution. In MAUI apps, leading-slash logical asset paths are commonly expected to resolve from app package assets, so this behavior makes those paths fail unless a real absolute file exists at that OS root path. Handle app-asset rooted paths before generic rooted-file normalization.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant