Maui icon indicating copy to clipboard operation
Maui copied to clipboard

[BUG] Somtime, Popup2 ShowPopupAsync() calls do not return when other WindowOverlay exists.

Open usausa opened this issue 6 months ago • 2 comments

Is there an existing issue for this?

  • [x] I have searched the existing issues

Did you read the "Reporting a bug" section on Contributing file?

  • [x] I have read the "Reporting a bug" section on Contributing file: https://github.com/CommunityToolkit/Maui/blob/main/CONTRIBUTING.md#reporting-a-bug

Current Behavior

There exists another library that uses WindowOverlay. If ShowPopupAsync() is called while another WindowOverlay is displayed, it may rarely return from the ShowPopupAsync() call when the popup is closed. If another WindowOverlay does not exist, this phenomenon will not occur.

Expected Behavior

Return from ShowPopupAsync() call when Popup is closed, even if another Overlay exists.

Steps To Reproduce

  1. Create another WindowOverlay.
  2. Show WindowOverlay.
  3. Call to ShowPopupAsync().
  4. Close Popup.
  5. Repeat about 10 times and you can almost reproduce it.

The sample code is below. When a popup is repeatedly displayed and closed by OnWithOverlayClick(), the “** end” may not be displayed after the popup disappears, and the BusyOverlay may remain.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="Popup2App.MainPage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">

    <VerticalStackLayout Padding="30" Spacing="25">

        <Button
            Clicked="OnWithOverlayClick"
            HorizontalOptions="Fill"
            Text="With overlay" />

        <Button
            Clicked="OnWithoutOverlayClick"
            HorizontalOptions="Fill"
            Text="Without overlay" />

    </VerticalStackLayout>

</ContentPage>
using System.Diagnostics;

using CommunityToolkit.Maui;

namespace Popup2App
{
    using CommunityToolkit.Maui.Extensions;

    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        // Overlay issue

        private async void OnWithOverlayClick(object? sender, EventArgs e)
        {
            var overlay = new BusyOverlay(Application.Current!.Windows[0]);
            overlay.Window.AddOverlay(overlay);

            Debug.WriteLine("** start");
            await this.ShowPopupAsync(new SamplePopup(), new PopupOptions { Shape = null, Shadow = null });
            Debug.WriteLine("** end");

            overlay.Window.RemoveOverlay(overlay);
        }

        private async void OnWithoutOverlayClick(object? sender, EventArgs e)
        {
            Debug.WriteLine("** start");
            await this.ShowPopupAsync(new SamplePopup(), new PopupOptions { Shape = null, Shadow = null });
            Debug.WriteLine("** end");
        }
    }
}

public sealed class BusyOverlay : WindowOverlay
{
    public BusyOverlay(IWindow window)
        : base(window)
    {
        AddWindowElement(new OverlayElement());
        EnableDrawableTouchHandling = true;
    }

    private sealed class OverlayElement : IWindowOverlayElement
    {
        public void Draw(ICanvas canvas, RectF dirtyRect)
        {
            canvas.FillColor = new(255, 0, 0, 128);
            canvas.FillRectangle(dirtyRect);
        }

        public bool Contains(Point point) => true;
    }
}

Link to public reproduction project repository

https://github.com/usausa/Issue-CommunityToolkitMaui-Popup2

Environment

- .NET MAUI CommunityToolkit: 12.0.0
- OS: Android
- .NET MAUI: 9.0.80

Anything else?

No response

usausa avatar Jun 19 '25 00:06 usausa

This is potentially a duplicate of #2703. @usausa are you able to test with a preview build to confirm whether this issue is resolved? We have a guide on how to do this https://github.com/CommunityToolkit/Maui/wiki/Preview-Packages

bijington avatar Jun 23 '25 20:06 bijington

The problem seems to be resolved, just like #2703. Thank you.

However, while testing, I noticed that a PopupBlockedException would occur if I repeatedly opened and closed the app. I will create a separate issue about this.

**CommunityToolkit.Maui.Views.PopupBlockedException:** 'Unable to close Popup because it is blocked by the Modal Page CommunityToolkit.Maui.Views.PopupPage. Please call `Navigation.PopModalAsync()` to first remove CommunityToolkit.Maui.Views.PopupPage from the ModalStack'
[mono-rt] [ERROR] FATAL UNHANDLED EXCEPTION: CommunityToolkit.Maui.Views.PopupBlockedException: Unable to close Popup because it is blocked by the Modal Page CommunityToolkit.Maui.Views.PopupPage. Please call `Navigation.PopModalAsync()` to first remove CommunityToolkit.Maui.Views.PopupPage from the ModalStack
[mono-rt]    at CommunityToolkit.Maui.Views.PopupPage.CloseAsync(PopupResult result, CancellationToken token)
[mono-rt]    at CommunityToolkit.Maui.Views.PopupPage.<>c__DisplayClass4_0.<<-ctor>b__0>d.MoveNext()
[mono-rt] --- End of stack trace from previous location ---
[mono-rt]    at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_0(Object state)
[mono-rt]    at Android.App.SyncContext.<>c__DisplayClass2_0.<Post>b__0() in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.App/SyncContext.cs:line 36
[mono-rt]    at Java.Lang.Thread.RunnableImplementor.Run() in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Java.Lang/Thread.cs:line 37
[mono-rt]    at Java.Lang.IRunnableInvoker.n_Run(IntPtr jnienv, IntPtr native__this) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net9.0/android-35/mcw/Java.Lang.IRunnable.cs:line 59
[mono-rt]    at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(_JniMarshal_PP_V callback, IntPtr jnienv, IntPtr klazz) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:line 22

usausa avatar Jun 23 '25 23:06 usausa