Skip to content

Fix Avalonia Event Bubbling#521

Merged
wieslawsoltes merged 3 commits into
wieslawsoltes:masterfrom
JaggerJo:svg-in-button-clickable-fix
May 1, 2026
Merged

Fix Avalonia Event Bubbling#521
wieslawsoltes merged 3 commits into
wieslawsoltes:masterfrom
JaggerJo:svg-in-button-clickable-fix

Conversation

@JaggerJo
Copy link
Copy Markdown

@JaggerJo JaggerJo commented Apr 28, 2026

Seems like the Focus refactoring in Avalonia v12 might have caused some issues with Pointer Capturing and Event Bubbling.

We've been using version 1.0.0.18 and recently updated to 4.2.0. We just discovered that buttons with SVG icons in them are no longer clickable.

I first thought this is related to focus refactoring in v12 - but it seems like this only has to do with changes / the addition of the interaction system.

↓ With Avalonia v12 + current master

CleanShot 2026-04-28 at 22 29 14

↓ With the fix

CleanShot 2026-04-28 at 22 35 19

Demo App

Project File

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Avalonia" Version="12.0.1" />
    <PackageReference Include="Avalonia.Desktop" Version="12.0.1" />
    <PackageReference Include="Avalonia.Themes.Fluent" Version="12.0.1" />
    <!-- Reproduces against the published broken version. -->
    <PackageReference Include="Svg.Controls.Skia.Avalonia" Version="12.0.0.5" />
  </ItemGroup>

</Project>
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Layout;
using Avalonia.Themes.Fluent;
using AvSvg = Avalonia.Svg.Skia.Svg;

AppBuilder.Configure<App>().UsePlatformDetect().StartWithClassicDesktopLifetime(args);

public sealed class App : Application
{
    public override void Initialize() => Styles.Add(new FluentTheme());

    public override void OnFrameworkInitializationCompleted()
    {
        const string svg = "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'>" +
                           "<circle cx='50' cy='50' r='44' fill='#3B82F6'/></svg>";

        int btn = 0, brd = 0;
        var status = new TextBlock { HorizontalAlignment = HorizontalAlignment.Center };
        void Refresh() => status.Text = $"button={btn}  border={brd}";
        Refresh();

        var button = new Button { Content = NewSvg(svg) };
        button.Click += (_, _) => { btn++; Refresh(); };

        var border = new Border { Padding = new Thickness(8), Child = NewSvg(svg) };
        border.Tapped += (_, _) => { brd++; Refresh(); };

        ((IClassicDesktopStyleApplicationLifetime)ApplicationLifetime!).MainWindow = new Window
        {
            Width = 320, Height = 280, Title = "Svg pointer-bubble repro",
            Content = new StackPanel
            {
                Margin = new Thickness(20), Spacing = 12,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                Children = { button, border, status },
            },
        };
        base.OnFrameworkInitializationCompleted();
    }

    private static AvSvg NewSvg(string source) => new(new System.Uri("avares://SvgBubbleRepro/"))
    {
        Source = source, Width = 80, Height = 80,
    };
}

@wieslawsoltes
Copy link
Copy Markdown
Owner

@codex review

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: 5f30ecd440

ℹ️ 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 891 to 893
var currentPoint = e.GetCurrentPoint(this);
var button = MapPointerUpdateKind(currentPoint.Properties.PointerUpdateKind);
var result = Interaction.DispatchPointerPressed(skSvg, CreatePointerInput(e, button, e.ClickCount, 0));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restore pointer capture on press to avoid stuck SVG capture

Without capturing the Avalonia pointer on press, a PointerReleased that occurs outside this control will not be delivered here, so Interaction.DispatchPointerReleased(...) never runs to clear the dispatcher’s internal _capturedElement/_pressedElement state. In that path, later DispatchPointerMoved calls continue routing to the stale captured SVG element (_capturedElement ?? hitTarget), which breaks hover/cursor updates and event targeting after an outside release until another full press/release cycle happens.

Useful? React with 👍 / 👎.

@JaggerJo
Copy link
Copy Markdown
Author

@wieslawsoltes anything I can do to get a fix in? :)

@pull-request-size pull-request-size Bot added size/L and removed size/XS labels May 1, 2026
@wieslawsoltes wieslawsoltes merged commit 713236d into wieslawsoltes:master May 1, 2026
5 checks passed
@wieslawsoltes
Copy link
Copy Markdown
Owner

@JaggerJo Thanks for PR, sorry for long time to merge but have huge backlog of PRs for Svg.Skia

@JaggerJo
Copy link
Copy Markdown
Author

JaggerJo commented May 2, 2026

@JaggerJo Thanks for PR, sorry for long time to merge but have huge backlog of PRs for Svg.Skia

No worries - thanks for all the OSS work 👏

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.

2 participants