Skip to content

Commit 25ad773

Browse files
committed
[Edge] Add fallback when WebView2 runtime is not present #2000
When using WebView2 as browser engine in SWT without a WebView2 runtime being available on the system, browser initialization fails. In order to more gracefully handle the case that a system has no such runtime installed (like on some Windows 10 systems), this change introduces an automatic fallback option to Internet Explorer in case no WebView2 runtime is found. It shows a dialog informing about the missing runtime, the option to fallback to IE and also allows to open further information provided via the FAQ. Fixes #2000
1 parent f498ca3 commit 25ad773

File tree

1 file changed

+70
-4
lines changed
  • bundles/org.eclipse.swt/Eclipse SWT Browser/common/org/eclipse/swt/browser

1 file changed

+70
-4
lines changed

bundles/org.eclipse.swt/Eclipse SWT Browser/common/org/eclipse/swt/browser/Browser.java

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
*******************************************************************************/
1414
package org.eclipse.swt.browser;
1515

16+
import java.util.*;
17+
1618
import org.eclipse.swt.*;
19+
import org.eclipse.swt.program.*;
1720
import org.eclipse.swt.widgets.*;
1821

1922
/**
@@ -93,10 +96,7 @@ public Browser (Composite parent, int style) {
9396
}
9497

9598
style = getStyle ();
96-
webBrowser = new BrowserFactory ().createWebBrowser (style);
97-
if (webBrowser != null) {
98-
webBrowser.setBrowser (this);
99-
webBrowser.create (parent, style);
99+
if (createWebBrowser(parent, style)) {
100100
return;
101101
}
102102
dispose ();
@@ -119,6 +119,72 @@ public Browser (Composite parent, int style) {
119119
SWT.error (SWT.ERROR_NO_HANDLES, null, errMsg);
120120
}
121121

122+
private boolean createWebBrowser(Composite parent, int style) {
123+
webBrowser = new BrowserFactory ().createWebBrowser (style);
124+
if (webBrowser == null) {
125+
return false;
126+
}
127+
webBrowser.setBrowser (this);
128+
try {
129+
webBrowser.create (parent, style);
130+
return true;
131+
} catch (SWTError error) {
132+
boolean isEdge = "win32".equals(SWT.getPlatform()) && (style & SWT.IE) == 0;
133+
if (isEdge && error.code == SWT.ERROR_NOT_IMPLEMENTED) {
134+
WebViewUnavailableDialog.showAsync(getShell());
135+
}
136+
throw error;
137+
}
138+
}
139+
140+
private class WebViewUnavailableDialog {
141+
private record DialogOption(int index, String message) {};
142+
private static final DialogOption USE_IE_OPTION = new DialogOption(SWT.YES, "Use IE");
143+
private static final DialogOption MORE_INFORMATION_OPTION = new DialogOption(SWT.NO, "Information");
144+
private static final DialogOption CANCEL_OPTION = new DialogOption(SWT.CANCEL, "Cancel");
145+
146+
private static final String DIALOG_TITLE = "Default browser engine not available";
147+
private static final String DIALOG_MESSAGE = "Microsoft Edge (WebView2) is not available. Do you want to use the legacy Internet Explorer?\n\nNote: It is necessary to reopen browsers for the change to take effect.";
148+
private static final String FAQ_URL = "https://github.com/eclipse-platform/eclipse.platform/tree/master/docs/FAQ/FAQ_How_do_I_use_Edge-IE_as_the_Browser's_underlying_renderer.md";
149+
150+
private static final int DIALOG_OPTION_FLAGS = USE_IE_OPTION.index | MORE_INFORMATION_OPTION.index | CANCEL_OPTION.index;
151+
private static final Map<Integer, String> DIALOG_OPTION_LABELS = Map.of( //
152+
USE_IE_OPTION.index, USE_IE_OPTION.message, //
153+
MORE_INFORMATION_OPTION.index, MORE_INFORMATION_OPTION.message, //
154+
CANCEL_OPTION.index, CANCEL_OPTION.message);
155+
156+
private static boolean shownOnce;
157+
158+
static void showAsync(Shell parentShell) {
159+
if (shownOnce) {
160+
return;
161+
}
162+
shownOnce = true;
163+
parentShell.getDisplay().asyncExec(() -> {
164+
processDialog(parentShell);
165+
});
166+
}
167+
168+
static private void processDialog(Shell parentShell) {
169+
MessageBox fallbackInfoBox = new MessageBox(parentShell, SWT.ICON_ERROR | DIALOG_OPTION_FLAGS);
170+
fallbackInfoBox.setText(DIALOG_TITLE);
171+
fallbackInfoBox.setMessage(DIALOG_MESSAGE);
172+
fallbackInfoBox.setButtonLabels(DIALOG_OPTION_LABELS);
173+
boolean completed;
174+
do {
175+
int result = fallbackInfoBox.open();
176+
completed = true;
177+
if (result == MORE_INFORMATION_OPTION.index) {
178+
Program.launch(FAQ_URL);
179+
completed = false;
180+
} else if (result == USE_IE_OPTION.index) {
181+
System.setProperty(PROPERTY_DEFAULTTYPE, "ie");
182+
DefaultType = SWT.IE;
183+
}
184+
} while (!completed);
185+
}
186+
}
187+
122188
static Composite checkParent (Composite parent) {
123189
String platform = SWT.getPlatform ();
124190
if (!"gtk".equals (platform)) return parent; //$NON-NLS-1$

0 commit comments

Comments
 (0)