From b5a92d60ba4855a69cf9b535451e70766445bc04 Mon Sep 17 00:00:00 2001 From: "Mennig, Robin" Date: Wed, 12 Aug 2026 13:24:44 +0200 Subject: [PATCH] Handle CreateCoreWebView2EnvironmentWithOptions ERROR_NOT_SUPPORTED When passing a Edge binary directory to 'org.eclipse.swt.browser.EdgeDir', CreateCoreWebView2EnvironmentWithOptions returns HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED) instead of HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) which is thrown for other invalid directories. In this case, the passed completion callback exits immediately before the processOSMessagesUntil(..) loop starts spinning. This previously caused the return value being overwritten in callAndWait(long[], ToIntFunction), leading to a permanent UI freeze. Fixes https://github.com/eclipse-platform/eclipse.platform.swt/issues/3499 --- .../win32/org/eclipse/swt/browser/Edge.java | 35 ++++++++++++------- .../org/eclipse/swt/internal/win32/OS.java | 1 + bundles/org.eclipse.swt/Readme.WebView2.md | 4 ++- 3 files changed, 27 insertions(+), 13 deletions(-) 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 226607eb2a6..047b7c5d2bf 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 @@ -305,12 +305,16 @@ static int callAndWait(long[] ppv, ToIntFunction callable) { return COM.S_OK; }); ppv[0] = 0; - phr[0] = callable.applyAsInt(completion); - // "completion" callback may be called asynchronously, - // so keep processing next OS message that may call it - processOSMessagesUntil(() -> phr[0] != COM.S_OK || ppv[0] != 0, exception -> { - throw exception; - }, Display.getCurrent()); + int cr = callable.applyAsInt(completion); + if (cr != COM.S_OK) { + phr[0] = cr; + } else { + // "completion" callback may be called asynchronously, + // so keep processing next OS message that may call it + processOSMessagesUntil(() -> phr[0] != COM.S_OK || ppv[0] != 0, exception -> { + throw exception; + }, Display.getCurrent()); + } completion.Release(); return phr[0]; } @@ -325,12 +329,16 @@ int callAndWait(String[] pstr, ToIntFunction callable) { return COM.S_OK; }); pstr[0] = null; - phr[0] = callable.applyAsInt(completion); - // "completion" callback may be called asynchronously, - // so keep processing next OS message that may call it - processOSMessagesUntil(() -> phr[0] != COM.S_OK || pstr[0] != null, exception -> { - throw exception; - }, browser.getDisplay()); + int cr = callable.applyAsInt(completion); + if (cr != COM.S_OK) { + phr[0] = cr; + } else { + // "completion" callback may be called asynchronously, + // so keep processing next OS message that may call it + processOSMessagesUntil(() -> phr[0] != COM.S_OK || pstr[0] != null, exception -> { + throw exception; + }, browser.getDisplay()); + } completion.Release(); return phr[0]; } @@ -645,6 +653,9 @@ WebViewEnvironment createEnvironment() { if (hr == OS.HRESULT_FROM_WIN32(OS.ERROR_FILE_NOT_FOUND)) { SWT.error(SWT.ERROR_NOT_IMPLEMENTED, null, " [WebView2 runtime not found]"); } + if (hr == OS.HRESULT_FROM_WIN32(OS.ERROR_NOT_SUPPORTED)) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, String.format(" [Invalid WebView2 directory: %s. Please ensure that '%s' points to a WebView2 application directory (which usually ends with \\EdgeWebView\\Application\\)]", browserDir, BROWSER_DIR_PROP)); + } if (hr != COM.S_OK) error(SWT.ERROR_NO_HANDLES, hr); ICoreWebView2Environment environment = new ICoreWebView2Environment(ppv[0]); WebViewEnvironment environmentWrapper = new WebViewEnvironment(environment); diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java index 931b6e39da0..2c02e0c6a9c 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java @@ -426,6 +426,7 @@ public class OS extends C { public static final int EN_CHANGE = 0x300; public static final int EP_EDITTEXT = 1; public static final int ERROR_FILE_NOT_FOUND = 0x2; + public static final int ERROR_NOT_SUPPORTED = 0x32; public static final int ERROR_INVALID_STATE = 0x139F; public static final int ERROR_NO_MORE_ITEMS = 0x103; public static final int ERROR_CANCELED = 0x4C7; diff --git a/bundles/org.eclipse.swt/Readme.WebView2.md b/bundles/org.eclipse.swt/Readme.WebView2.md index f9e53149bbc..6a9b0a13e7f 100644 --- a/bundles/org.eclipse.swt/Readme.WebView2.md +++ b/bundles/org.eclipse.swt/Readme.WebView2.md @@ -38,10 +38,12 @@ the `Browser` will automatically fall back to the Internet Explorer backend. ### Browser Directory WebView2 backend will automatically locate runtimes and Edge installations. -The path to the Edge binary directory can also be set manually using the +The path to the WebView2 binary directory can also be set manually using the `org.eclipse.swt.browser.EdgeDir` system property. This is also required when bundling fixed-version WebView2 binaries. +_Note_: The directory pointed to by `org.eclipse.swt.browser.EdgeDir` must contain the WebView2 binary (`msedgewebview2.exe`, usually in `\EdgeWebView\Application\`), **not** the Edge application binary (`msedge.exe`, usually in `\Edge\Application\`). + ### User Directory WebView creates a user data directory to stores caches and