CefSharp icon indicating copy to clipboard operation
CefSharp copied to clipboard

WPF - Tab freeze after opening multiple popups

Open MandyHolm opened this issue 1 year ago • 2 comments

Is there an existing issue for this?

  • [X] I have searched both open/closed issues, no issue already exists.

CefSharp Version

126.2.30

Operating System

Windows 10

Architecture

x64

.Net Version

.Net 4.8

Implementation

WPF

Reproduction Steps

Hi, I have tested this in the latest cefsharp.wpf.sample app and I am getting a tab freeze after using the popup Test open my window.

  • I used the cefsharp.wpf.sample
  • Open a tab www.google.com
  • Open the Tests and Popup Test and add change window.open("https://www.google.com", "", "width=200,height=100") and Run
  • Select the Open "mywindow" 3 or 4 times
  • Select the Tab www.google.com ( sometimes this tab is frozen)
  • Got back to the Popup tab and cannot select Open "mywindow" , sometimes this tab is frozen

Expected behavior

Tab does not freeze

Actual behavior

No error message, a tab freezes and does not allow an ui input

Regression?

No response

Known Workarounds

No response

Does this problem also occur in the CEF Sample Application

Yes using WPF/OffScreen command line args

Other information

No response

MandyHolm avatar Jul 19 '24 03:07 MandyHolm

I was thinking as a workaround, I could just show the window popup as a dialog popup and therefore lock the UI until the dialog is closed. Changing the OnAfterCreated from Show() to ShowDialog() does not display anything in the popup, with following code public class CustomLifeSpanHandler : ILifeSpanHandler { public event Action<ChromiumWebBrowser> OnPopupCreated;

public bool DoClose(IWebBrowser chromiumWebBrowser, IBrowser browser)
{
    // Return false to let the browser close
    return false;
}

public void OnAfterCreated(IWebBrowser chromiumWebBrowser, IBrowser browser)
{
    if (browser.IsPopup)
    {
        var myBrowser = (ChromiumWebBrowser)chromiumWebBrowser;

        myBrowser.Dispatcher.Invoke(() =>
        {
            var owner = Window.GetWindow(myBrowser);
            if (owner != null && owner.Content == chromiumWebBrowser)
            {
             owner.ShowDialog();
            }
        });
    }
}

public void OnBeforeClose(IWebBrowser chromiumWebBrowser, IBrowser browser)
{
    //NOTE: This is experimental
    if (!browser.IsDisposed && browser.IsPopup)
    {
        var mybrowser = (ChromiumWebBrowser)chromiumWebBrowser;

        mybrowser.Dispatcher.Invoke(() =>
        {
            var owner = Window.GetWindow(mybrowser);
            if (owner != null && owner.Content == chromiumWebBrowser)
            {
                owner.Close();
            }
        });
    }
}

public bool OnBeforePopup(
    IWebBrowser chromiumWebBrowser,
    IBrowser browser,
    IFrame frame,
    string targetUrl,
    string targetFrameName,
    WindowOpenDisposition targetDisposition,
    bool userGesture,
    IPopupFeatures popupFeatures,
    IWindowInfo windowInfo,
    IBrowserSettings browserSettings,
    ref bool noJavascriptAccess,
    out IWebBrowser newBrowser)
{
    newBrowser = null;
    try
    {
        ChromiumWebBrowser chromiumBrowser = null;
       
        var myBrowser = (ChromiumWebBrowser)chromiumWebBrowser;

        var windowX = (windowInfo.X == int.MinValue) ? double.NaN : windowInfo.X;
        var windowY = (windowInfo.Y == int.MinValue) ? double.NaN : windowInfo.Y;
        var windowWidth = (windowInfo.Width == int.MinValue) ? double.NaN : windowInfo.Width;
        var windowHeight = (windowInfo.Height == int.MinValue) ? double.NaN : windowInfo.Height;
        myBrowser.Dispatcher.Invoke(() =>
        {
            var owner = Window.GetWindow(myBrowser);
            chromiumBrowser = new ChromiumWebBrowser
            {
                Address = targetUrl,
            };

            chromiumBrowser.SetAsPopup();
            chromiumBrowser.LifeSpanHandler = this;

            var popup = new Window
            {
                Left = windowX,
                Top = windowY,
                Width = windowWidth,
                Height = windowHeight,
                Content = chromiumBrowser,
                Owner = owner,
                Title = targetFrameName
            };

            var windowInteropHelper = new WindowInteropHelper(popup);
            //Create the handle Window handle (In WPF there's only one handle per window, not per control)
            var handle = windowInteropHelper.EnsureHandle();

            //The parentHandle value will be used to identify monitor info and to act as the parent window for dialogs,
            //context menus, etc. If parentHandle is not provided then the main screen monitor will be used and some
            //functionality that requires a parent window may not function correctly.
            windowInfo.SetAsWindowless(handle);

            popup.Closed += (o, e) =>
            {
                var w = o as Window;
                if (w != null && w.Content is IWebBrowser)
                {
                    (w.Content as IWebBrowser).Dispose();
                    w.Content = null;
                }
            };

        });
        
        newBrowser = chromiumBrowser;

        return false;

    }
    catch (Exception exception)
    {
        newBrowser = null;
        var test = exception;
        return false;
       
    }
}

}

MandyHolm avatar Jul 21 '24 07:07 MandyHolm

Does the browser start redrawing if you resize the window?

Did you check the log for errors?

Popups are shown in a new window by default, the example demos hosting them as tabs, you don't need to do this in your code.

amaitland avatar Jul 25 '24 07:07 amaitland

Closing due to lack of feedback.

amaitland avatar Oct 15 '24 08:10 amaitland