diff --git a/bundles/org.eclipse.swt/Eclipse SWT Browser/common/org/eclipse/swt/browser/Browser.java b/bundles/org.eclipse.swt/Eclipse SWT Browser/common/org/eclipse/swt/browser/Browser.java index 6d0403b9082..3f4eb80708e 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Browser/common/org/eclipse/swt/browser/Browser.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Browser/common/org/eclipse/swt/browser/Browser.java @@ -13,7 +13,10 @@ *******************************************************************************/ package org.eclipse.swt.browser; +import java.util.*; + import org.eclipse.swt.*; +import org.eclipse.swt.program.*; import org.eclipse.swt.widgets.*; /** @@ -93,10 +96,7 @@ public Browser (Composite parent, int style) { } style = getStyle (); - webBrowser = new BrowserFactory ().createWebBrowser (style); - if (webBrowser != null) { - webBrowser.setBrowser (this); - webBrowser.create (parent, style); + if (createWebBrowser(parent, style)) { return; } dispose (); @@ -119,6 +119,72 @@ public Browser (Composite parent, int style) { SWT.error (SWT.ERROR_NO_HANDLES, null, errMsg); } +private boolean createWebBrowser(Composite parent, int style) { + webBrowser = new BrowserFactory ().createWebBrowser (style); + if (webBrowser == null) { + return false; + } + webBrowser.setBrowser (this); + try { + webBrowser.create (parent, style); + return true; + } catch (SWTError error) { + boolean isEdge = "win32".equals(SWT.getPlatform()) && (style & SWT.IE) == 0; + if (isEdge && error.code == SWT.ERROR_NOT_IMPLEMENTED) { + WebViewUnavailableDialog.showAsync(getShell()); + } + throw error; + } +} + +private class WebViewUnavailableDialog { + private record DialogOption(int index, String message) {}; + private static final DialogOption USE_IE_OPTION = new DialogOption(SWT.YES, "Use IE"); + private static final DialogOption MORE_INFORMATION_OPTION = new DialogOption(SWT.NO, "Information"); + private static final DialogOption CANCEL_OPTION = new DialogOption(SWT.CANCEL, "Cancel"); + + private static final String DIALOG_TITLE = "Default browser engine not available"; + 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."; + 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"; + + private static final int DIALOG_OPTION_FLAGS = USE_IE_OPTION.index | MORE_INFORMATION_OPTION.index | CANCEL_OPTION.index; + private static final Map DIALOG_OPTION_LABELS = Map.of( // + USE_IE_OPTION.index, USE_IE_OPTION.message, // + MORE_INFORMATION_OPTION.index, MORE_INFORMATION_OPTION.message, // + CANCEL_OPTION.index, CANCEL_OPTION.message); + + private static boolean shownOnce; + + static void showAsync(Shell parentShell) { + if (shownOnce) { + return; + } + shownOnce = true; + parentShell.getDisplay().asyncExec(() -> { + processDialog(parentShell); + }); + } + + static private void processDialog(Shell parentShell) { + MessageBox fallbackInfoBox = new MessageBox(parentShell, SWT.ICON_ERROR | DIALOG_OPTION_FLAGS); + fallbackInfoBox.setText(DIALOG_TITLE); + fallbackInfoBox.setMessage(DIALOG_MESSAGE); + fallbackInfoBox.setButtonLabels(DIALOG_OPTION_LABELS); + boolean completed; + do { + int result = fallbackInfoBox.open(); + completed = true; + if (result == MORE_INFORMATION_OPTION.index) { + Program.launch(FAQ_URL); + completed = false; + } else if (result == USE_IE_OPTION.index) { + System.setProperty(PROPERTY_DEFAULTTYPE, "ie"); + DefaultType = SWT.IE; + } + } while (!completed); + } +} + static Composite checkParent (Composite parent) { String platform = SWT.getPlatform (); if (!"gtk".equals (platform)) return parent; //$NON-NLS-1$