diff --git a/bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/Edge.java b/bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/Edge.java index 0f5dec79f93..1d83f74be68 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/Edge.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/Edge.java @@ -222,9 +222,8 @@ static int callAndWait(long[] ppv, ToIntFunction callable) { ppv[0] = 0; phr[0] = callable.applyAsInt(completion); completion.Release(); - Display display = Display.getCurrent(); while (phr[0] == COM.S_OK && ppv[0] == 0) { - if (!display.readAndDispatch()) display.sleep(); + processNextOSMessage(); } return phr[0]; } @@ -241,13 +240,33 @@ static int callAndWait(String[] pstr, ToIntFunction callable) { pstr[0] = null; phr[0] = callable.applyAsInt(completion); completion.Release(); - Display display = Display.getCurrent(); while (phr[0] == COM.S_OK && pstr[0] == null) { - if (!display.readAndDispatch()) display.sleep(); + processNextOSMessage(); } return phr[0]; } +/** + * Processes a single OS message using {@link Display#readAndDispatch()}. This + * is required for processing the OS events during browser initialization, since + * Edge browser initialization happens asynchronously. + *

+ * {@link Display#readAndDisplay()} also processes events scheduled for + * asynchronous execution via {@link Display#asyncExec(Runnable)}. This may + * include events such as the disposal of the browser's parent composite, which + * leads to a failure in browser initialization if processed in between the OS + * events for initialization. Thus, this method does not implement an ordinary + * readAndDispatch loop, but waits for an OS event to be processed. + */ +private static void processNextOSMessage() { + Display display = Display.getCurrent(); + MSG msg = new MSG(); + while (!OS.PeekMessage (msg, 0, 0, 0, OS.PM_NOREMOVE)) { + display.sleep(); + } + display.readAndDispatch(); +} + static ICoreWebView2CookieManager getCookieManager() { if (Instances.isEmpty()) { SWT.error(SWT.ERROR_NOT_IMPLEMENTED, null, " [WebView2: cookie access requires a Browser instance]"); diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_browser_Browser.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_browser_Browser.java index 6c88a2af863..6eb42e4b435 100644 --- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_browser_Browser.java +++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_browser_Browser.java @@ -268,6 +268,17 @@ public void test_ConstructorLorg_eclipse_swt_widgets_CompositeI() { browser = createBrowser(null, SWT.NONE); // Should throw. } +/** + * Regression test for issue #339: [Edge] No more handle exceptions from Edge browser + */ +@Test +public void test_Constructor_asyncParentDisposal() { + Display.getCurrent().asyncExec(() -> { + shell.dispose(); + }); + Browser browser = createBrowser(shell, SWT.EDGE); + assertFalse(browser.isDisposed()); +} @Test public void test_evalute_Cookies () {