chromiumembedded / java-cef

Java Chromium Embedded Framework (JCEF). A simple framework for embedding Chromium-based browsers in other applications using the Java programming language.
https://bitbucket.org/chromiumembedded/java-cef
Other
639 stars 139 forks source link

CefBrowser_N.doClose() unexpectedly closes the host window #364

Open magreenblatt opened 4 years ago

magreenblatt commented 4 years ago

Original report by Anton Tarasov (Bitbucket: Anton Tarasov).


CefClient.doClose() javadoc says that:

If CEF created an OS window for the browser returning false will send an OS close * notification to the browser window's top-level owner (e.g. WM_CLOSE on Windows, performClose:
* on OS-X and "delete_event" on Linux). If no OS window exists (window rendering disabled)
* returning false will cause the browser object to be destroyed immediately. Return true if the
* browser is parented to another window and that other window needs to receive close
* notification via some non-standard technique
.

CefClient.doClose() may delegate to CefBrowser.doClose(). Here’s the impl from CefBrowser_N.doClose():

    @Override
    public synchronized boolean doClose() {
        if (closeAllowed_) {
            // Allow the close to proceed.
            return false;
        }

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                // Trigger close of the parent window.
                Component parent = SwingUtilities.getRoot(getUIComponent());
                if (parent != null) {
                    parent.dispatchEvent(
                            new WindowEvent((Window) parent, WindowEvent.WINDOW_CLOSING));
                }
            }
        });

        // Cancel the close.
        return true;
    }

  1. On canceling the close the method dispatches WINDOW_CLOSING. This contradicts the spec. Moreover, closeAllowed_ is false by default. This notification may cause the app to actually start application exit steps (when the event is dispatched to the app’s main frame, I experience this on MS Windows).
  2. It’s not quite clear why JCEF needs to dispatch WINDOW_CLOSING even when closeAllowed_ is true. As the spec says, OS will deliver native closing message to the hosting window, that will make AWT generate all corresponding Java events.

magreenblatt commented 4 years ago

This was likely an attempt to match the logic flow of CefLifeSpanHandler::DoClose. Perhaps a different approach would be better. Suggestions (including demo PR) are welcome.