Skip to content

[Linux/X11] WebView remains blank until OS window resize due to asynchronous GTK adapter creation after first layout pass #192

@pardont

Description

@pardont

On Linux X11, NativeWebView.OnAttached() creates the GTK adapter asynchronously, after the first layout pass. The adapter never receives the current Bounds, so the X11 child window stays at the default 200×200 size and WebKit renders into a hidden corner.

Workaround: subscribe to AdapterCreated, toggle IsVisible once → triggers TryGetAdapter()?.SizeChanged(Bounds.Size).

Expected: adapter should receive current bounds immediately after creation.

Handler to fix the bug:

public sealed class AvaloniaWebViewSizeFixHandler
    : Avalonia.Controls.Maui.Handlers.WebViewHandler
{
    protected override void ConnectHandler(Control platformView)
    {
        base.ConnectHandler(platformView);
        if (platformView is NativeWebView nwv)
            nwv.AdapterCreated += OnNativeAdapterCreated;
    }

    protected override void DisconnectHandler(Control platformView)
    {
        if (platformView is NativeWebView nwv)
            nwv.AdapterCreated -= OnNativeAdapterCreated;
        base.DisconnectHandler(platformView);
    }

    private static void OnNativeAdapterCreated(object? sender, WebViewAdapterEventArgs e)
    {
        if (sender is not NativeWebView nwv) return;

        // DispatcherPriority.Background: let the in-flight layout / arrange settle first
        // so when we toggle IsVisible the IsVisibleProperty handler reads a fully-laid-out
        // Bounds. Doing it synchronously here would race with the same layout pass that
        // produced the empty Bounds in the first place.
        UIThread.UIThread.Post(() =>
        {
            // If the page already navigated away before this tick fires, toggling
            // IsVisible is a harmless no-op (NativeWebView's property handler still posts
            // a SizeChanged but TryGetAdapter will return null), so no extra guard needed.
            var was = nwv.IsVisible;
            nwv.IsVisible = !was;
            nwv.IsVisible = was;
        }, DispatcherPriority.Background);
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions