From d90d1563d6db019fde5cc6eba62750b0cc3514c0 Mon Sep 17 00:00:00 2001 From: Sebastian Ratz Date: Thu, 10 Oct 2024 22:46:18 +0200 Subject: [PATCH] Edge: Inherit dark theme from Eclipse Set ICoreWebView2Profile#put_PreferredColorScheme() based on the Eclipse theme, if this is dark. The same way it is done in Display.setData(USE_DARKMODE_EXPLORER_THEME_KEY, ...) via OS.SetPreferredAppMode(PreferredAppMode_...); --- .../win32/org/eclipse/swt/browser/Edge.java | 38 ++++++++++++++ .../eclipse/swt/internal/ole/win32/COM.java | 1 + .../ole/win32/ICoreWebView2Profile.java | 50 +++++++++++++++++++ .../internal/ole/win32/ICoreWebView2_13.java | 26 ++++++++++ .../org/eclipse/swt/internal/win32/OS.java | 1 + .../org/eclipse/swt/widgets/Display.java | 14 ++++++ 6 files changed, 130 insertions(+) create mode 100644 bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2Profile.java create mode 100644 bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2_13.java 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 157cc12fe9..ae122f25db 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 @@ -40,6 +40,7 @@ class Edge extends WebBrowser { // Display.getData() keys static final String APPLOCAL_DIR_KEY = "org.eclipse.swt.internal.win32.appLocalDir"; + static final String EDGE_USE_DARK_PREFERED_COLOR_SCHEME = "org.eclipse.swt.internal.win32.Edge.useDarkPreferedColorScheme"; //$NON-NLS-1$ // System.getProperty() keys static final String BROWSER_DIR_PROP = "org.eclipse.swt.browser.EdgeDir"; @@ -64,6 +65,7 @@ public WebViewEnvironment(ICoreWebView2Environment environment) { private static Map webViewEnvironments = new HashMap<>(); ICoreWebView2Controller controller; ICoreWebView2Settings settings; + ICoreWebView2Profile profile; ICoreWebView2Environment2 environment2; private final WebViewProvider webViewProvider = new WebViewProvider(); @@ -285,6 +287,7 @@ class WebViewProvider { private CompletableFuture webView_2Future = new CompletableFuture<>(); private CompletableFuture webView_11Future = new CompletableFuture<>(); private CompletableFuture webView_12Future = new CompletableFuture<>(); + private CompletableFuture webView_13Future = new CompletableFuture<>(); private CompletableFuture lastWebViewTask = webViewFuture.thenRun(() -> {}); @@ -295,6 +298,7 @@ ICoreWebView2 initializeWebView(ICoreWebView2Controller controller) { initializeWebView_2(webView); initializeWebView_11(webView); initializeWebView_12(webView); + initializeWebView_13(webView); webViewFuture.complete(webView); return webView; } @@ -329,6 +333,16 @@ private void initializeWebView_12(ICoreWebView2 webView) { } } + private void initializeWebView_13(ICoreWebView2 webView) { + long[] ppv = new long[1]; + int hr = webView.QueryInterface(COM.IID_ICoreWebView2_13, ppv); + if (hr == COM.S_OK) { + webView_13Future.complete(new ICoreWebView2_13(ppv[0])); + } else { + webView_13Future.cancel(true); + } + } + ICoreWebView2 getWebView(boolean waitForPendingWebviewTasksToFinish) { if(waitForPendingWebviewTasksToFinish) { waitForFutureToFinish(lastWebViewTask); @@ -372,6 +386,18 @@ boolean isWebView_12Available() { return !webView_12Future.isCancelled(); } + ICoreWebView2_13 getWebView_13(boolean waitForPendingWebviewTasksToFinish) { + if(waitForPendingWebviewTasksToFinish) { + waitForFutureToFinish(lastWebViewTask); + } + return webView_13Future.join(); + } + + boolean isWebView_13Available() { + waitForFutureToFinish(webView_13Future); + return !webView_13Future.isCancelled(); + } + /* * Schedule a given runnable in a queue to execute when the webView is free and * has finished all the pending tasks queued before it. @@ -547,6 +573,18 @@ void setupBrowser(int hr, long pv) { settings.put_IsStatusBarEnabled(false); } + if (webViewProvider.isWebView_13Available()) { + webViewProvider.getWebView_13(false).get_Profile(ppv); + profile = new ICoreWebView2Profile(ppv[0]); + + // Dark theme inherited from application theme + if (Boolean.TRUE.equals(browser.getDisplay().getData(EDGE_USE_DARK_PREFERED_COLOR_SCHEME))) { + profile.put_PreferredColorScheme(/* COREWEBVIEW2_PREFERRED_COLOR_SCHEME_DARK */ 2); + } else { + profile.put_PreferredColorScheme(/* COREWEBVIEW2_PREFERRED_COLOR_SCHEME_AUTO */ 0); + } + } + long[] token = new long[1]; IUnknown handler; handler = newCallback(this::handleCloseRequested); diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/COM.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/COM.java index f0d45d548e..08a7ad0e08 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/COM.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/COM.java @@ -88,6 +88,7 @@ public class COM extends OS { public static final GUID IID_ICoreWebView2_2 = IIDFromString("{9E8F0CF8-E670-4B5E-B2BC-73E061E3184C}"); //$NON-NLS-1$ public static final GUID IID_ICoreWebView2_11 = IIDFromString("{0BE78E56-C193-4051-B943-23B460C08BDB}"); //$NON-NLS-1$ public static final GUID IID_ICoreWebView2_12 = IIDFromString("{35D69927-BCFA-4566-9349-6B3E0D154CAC}"); //$NON-NLS-1$ + public static final GUID IID_ICoreWebView2_13 = IIDFromString("{F75F09A8-667E-4983-88D6-C8773F315E84}"); //$NON-NLS-1$ // IA2 related GUIDS public static final GUID IIDIAccessible2 = IIDFromString("{E89F726E-C4F4-4c19-BB19-B647D7FA8478}"); //$NON-NLS-1$ diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2Profile.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2Profile.java new file mode 100644 index 0000000000..ee53375813 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2Profile.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2024 SAP SE and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * SAP SE - initial implementation + *******************************************************************************/ +package org.eclipse.swt.internal.ole.win32; + +public class ICoreWebView2Profile extends IUnknown { + +public ICoreWebView2Profile(long address) { + super(address); +} + +public int get_ProfileName(long[] value) { + return COM.VtblCall(3, address, value); +} + +public int get_IsInPrivateModeEnabled(long[] value) { + return COM.VtblCall(4, address, value); +} + +public int get_ProfilePath(long[] value) { + return COM.VtblCall(5, address, value); +} + +public int get_DefaultDownloadFolderPath(long[] value) { + return COM.VtblCall(6, address, value); +} + +public int put_DefaultDownloadFolderPath(long[] value) { + return COM.VtblCall(7, address, value); +} + +public int get_PreferredColorScheme(long[] value) { + return COM.VtblCall(8, address, value); +} + +public int put_PreferredColorScheme(long value) { + return COM.VtblCall(9, address, value); +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2_13.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2_13.java new file mode 100644 index 0000000000..52041243cf --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/ICoreWebView2_13.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2024 SAP SE and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * SAP SE - initial implementation + *******************************************************************************/ +package org.eclipse.swt.internal.ole.win32; + +public class ICoreWebView2_13 extends ICoreWebView2_12 { + +public ICoreWebView2_13(long address) { + super(address); +} + +public int get_Profile(long[] value) { + return COM.VtblCall(105, address, value); +} + +} 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 68a3faf435..df69b3483c 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 @@ -2285,6 +2285,7 @@ public static final void setTheme(boolean isDarkTheme) { display.setData("org.eclipse.swt.internal.win32.Combo.useDarkTheme", isDarkTheme); display.setData("org.eclipse.swt.internal.win32.ProgressBar.useColors", isDarkTheme); display.setData("org.eclipse.swt.internal.win32.Text.useDarkThemeIcons", isDarkTheme); + display.setData("org.eclipse.swt.internal.win32.Edge.useDarkPreferedColorScheme", isDarkTheme); } public static final boolean SetWindowText (long hWnd, TCHAR lpString) { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java index 8ef94c8ea5..cea9da177d 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java @@ -270,6 +270,17 @@ public class Display extends Device implements Executor { */ static final String USE_DARKTHEME_TEXT_ICONS = "org.eclipse.swt.internal.win32.Text.useDarkThemeIcons"; //$NON-NLS-1$ boolean textUseDarkthemeIcons = false; + /** + * Use dark prefered color scheme in Edge browser. + * Note:
+ *
    + *
  • When setting this property on the display, it is first AND'ed with !disableCustomThemeTweaks. + *
  • The data is then read from withing Edge. + *
  • This is to avoid adding public methods/members. + *
+ * Expects a boolean value. + */ + static final String EDGE_USE_DARK_PREFERED_COLOR_SCHEME = "org.eclipse.swt.internal.win32.Edge.useDarkPreferedColorScheme"; //$NON-NLS-1$ /* Custom icons */ private HashMap sizeToSearchIconHandle = new HashMap<>(); @@ -4575,6 +4586,9 @@ public void setData (String key, Object value) { case USE_DARKTHEME_TEXT_ICONS: textUseDarkthemeIcons = !disableCustomThemeTweaks && _toBoolean(value); break; + case EDGE_USE_DARK_PREFERED_COLOR_SCHEME: + value = !disableCustomThemeTweaks && _toBoolean(value); + break; } /* Remove the key/value pair */