diff options
author | Alexandr Miloslavskiy | 2021-10-13 21:36:58 +0000 |
---|---|---|
committer | Niraj Modi | 2021-10-18 10:16:13 +0000 |
commit | fb22c8ec55bee7b6eb77c862764a4e249176bc8a (patch) | |
tree | 1ea4d029c22c4cc09a89d1c9a8688e46b3f4dfde | |
parent | 465e26a3465d5d8660029fd7e87a32360f447d3c (diff) | |
download | eclipse.platform.swt-fb22c8ec55bee7b6eb77c862764a4e249176bc8a.tar.gz eclipse.platform.swt-fb22c8ec55bee7b6eb77c862764a4e249176bc8a.tar.xz eclipse.platform.swt-fb22c8ec55bee7b6eb77c862764a4e249176bc8a.zip |
Bug 563329 - [Dark theme] Ability to style the window title bar
While at it, also fix one instance that suffered from version lie when
compatibility manifest is not present.
Change-Id: I0cc01392655f30619f6a7c88ee28ae9589fe04e9
Signed-off-by: Alexandr Miloslavskiy <alexandr.miloslavskiy@syntevo.com>
Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/186458
Tested-by: Platform Bot <platform-bot@eclipse.org>
Reviewed-by: Niraj Modi <niraj.modi@in.ibm.com>
11 files changed, 248 insertions, 5 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/make_win32.mak b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/make_win32.mak index ba7d7aaca5..7e9cf972e6 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/make_win32.mak +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/make_win32.mak @@ -26,7 +26,7 @@ SWT_VERSION = $(maj_ver)$(min_ver)r$(rev) SWT_LIB = $(SWT_PREFIX)-$(WS_PREFIX)-$(SWT_VERSION).dll SWT_LIBS = comctl32.lib shell32.lib imm32.lib oleacc.lib usp10.lib \ wininet.lib Shlwapi.lib Uxtheme.lib Propsys.lib Urlmon.lib \ - Msimg32.lib + Msimg32.lib Dwmapi.lib SWT_OBJS = swt.obj callback.obj c.obj c_stats.obj \ os.obj os_structs.obj os_custom.obj os_stats.obj \ com_structs.obj com.obj com_stats.obj com_custom.obj @@ -53,7 +53,7 @@ WGL_OBJS = wgl.obj wgl_structs.obj wgl_stats.obj CFLAGS = -O1 -DNDEBUG -DUNICODE -D_UNICODE /c $(cflags) $(cvarsmt) $(CFLAGS) \ -DSWT_VERSION=$(maj_ver)$(min_ver) -DSWT_REVISION=$(rev) $(NATIVE_STATS) -DUSE_ASSEMBLER \ /I"$(SWT_JAVA_HOME)\include" /I"$(SWT_JAVA_HOME)\include\win32" /I. - + RCFLAGS = $(rcflags) $(rcvars) $(RCFLAGS) -DSWT_FILE_VERSION=\"$(maj_ver).$(min_ver).$(rev).0\" -DSWT_COMMA_VERSION=$(comma_ver) ldebug = /RELEASE /INCREMENTAL:NO /NOLOGO dlllflags = -dll diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os.c b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os.c index 8144b9c921..fd0a44c49c 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os.c @@ -1508,6 +1508,22 @@ fail: } #endif +#ifndef NO_DwmSetWindowAttribute +JNIEXPORT jboolean JNICALL OS_NATIVE(DwmSetWindowAttribute) + (JNIEnv *env, jclass that, jlong arg0, jint arg1, jintArray arg2, jint arg3) +{ + jint *lparg2=NULL; + jboolean rc = 0; + OS_NATIVE_ENTER(env, that, DwmSetWindowAttribute_FUNC); + if (arg2) if ((lparg2 = (*env)->GetIntArrayElements(env, arg2, NULL)) == NULL) goto fail; + rc = (jboolean)DwmSetWindowAttribute((HDC)arg0, arg1, lparg2, arg3); +fail: + if (arg2 && lparg2) (*env)->ReleaseIntArrayElements(env, arg2, lparg2, 0); + OS_NATIVE_EXIT(env, that, DwmSetWindowAttribute_FUNC); + return rc; +} +#endif + #ifndef NO_EMREXTCREATEFONTINDIRECTW_1sizeof JNIEXPORT jint JNICALL OS_NATIVE(EMREXTCREATEFONTINDIRECTW_1sizeof) (JNIEnv *env, jclass that) @@ -6399,6 +6415,18 @@ JNIEXPORT void JNICALL OS_NATIVE(NotifyWinEvent) } #endif +#ifndef NO_OSVERSIONINFOEX_1sizeof +JNIEXPORT jint JNICALL OS_NATIVE(OSVERSIONINFOEX_1sizeof) + (JNIEnv *env, jclass that) +{ + jint rc = 0; + OS_NATIVE_ENTER(env, that, OSVERSIONINFOEX_1sizeof_FUNC); + rc = (jint)OSVERSIONINFOEX_sizeof(); + OS_NATIVE_EXIT(env, that, OSVERSIONINFOEX_1sizeof_FUNC); + return rc; +} +#endif + #ifndef NO_OUTLINETEXTMETRIC_1sizeof JNIEXPORT jint JNICALL OS_NATIVE(OUTLINETEXTMETRIC_1sizeof) (JNIEnv *env, jclass that) @@ -7154,6 +7182,30 @@ JNIEXPORT jboolean JNICALL OS_NATIVE(RoundRect) } #endif +#ifndef NO_RtlGetVersion +JNIEXPORT jint JNICALL OS_NATIVE(RtlGetVersion) + (JNIEnv *env, jclass that, jobject arg0) +{ + OSVERSIONINFOEX _arg0, *lparg0=NULL; + jint rc = 0; + OS_NATIVE_ENTER(env, that, RtlGetVersion_FUNC); + if (arg0) if ((lparg0 = getOSVERSIONINFOEXFields(env, arg0, &_arg0)) == NULL) goto fail; +/* + rc = (jint)RtlGetVersion(lparg0); +*/ + { + OS_LOAD_FUNCTION(fp, RtlGetVersion) + if (fp) { + rc = (jint)((jint (CALLING_CONVENTION*)(OSVERSIONINFOEX *))fp)(lparg0); + } + } +fail: + if (arg0 && lparg0) setOSVERSIONINFOEXFields(env, arg0, lparg0); + OS_NATIVE_EXIT(env, that, RtlGetVersion_FUNC); + return rc; +} +#endif + #ifndef NO_SAFEARRAYBOUND_1sizeof JNIEXPORT jint JNICALL OS_NATIVE(SAFEARRAYBOUND_1sizeof) (JNIEnv *env, jclass that) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_custom.h b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_custom.h index 05186c6bc6..fe17bb57e9 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_custom.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_custom.h @@ -19,3 +19,4 @@ /* Libraries for dynamic loaded functions */ #define GetDpiForMonitor_LIB "shcore.dll" +#define RtlGetVersion_LIB "ntdll.dll" diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.c index 5d826b4e83..927226b396 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.c @@ -131,6 +131,7 @@ char * OS_nativeFunctionNames[] = { "DrawThemeBackground", "DrawThemeText", "DuplicateHandle", + "DwmSetWindowAttribute", "EMREXTCREATEFONTINDIRECTW_1sizeof", "EMR_1sizeof", "EXTLOGFONTW_1sizeof", @@ -490,6 +491,7 @@ char * OS_nativeFunctionNames[] = { "NONCLIENTMETRICS_1sizeof", "NOTIFYICONDATA_1V2_1SIZE", "NotifyWinEvent", + "OSVERSIONINFOEX_1sizeof", "OUTLINETEXTMETRIC_1sizeof", "OffsetRect", "OffsetRgn", @@ -542,6 +544,7 @@ char * OS_nativeFunctionNames[] = { "ReplyMessage", "RestoreDC", "RoundRect", + "RtlGetVersion", "SAFEARRAYBOUND_1sizeof", "SAFEARRAY_1sizeof", "SCRIPT_1ANALYSIS_1sizeof", diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.h index 0f7febd228..f1417d6928 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.h @@ -141,6 +141,7 @@ typedef enum { DrawThemeBackground_FUNC, DrawThemeText_FUNC, DuplicateHandle_FUNC, + DwmSetWindowAttribute_FUNC, EMREXTCREATEFONTINDIRECTW_1sizeof_FUNC, EMR_1sizeof_FUNC, EXTLOGFONTW_1sizeof_FUNC, @@ -500,6 +501,7 @@ typedef enum { NONCLIENTMETRICS_1sizeof_FUNC, NOTIFYICONDATA_1V2_1SIZE_FUNC, NotifyWinEvent_FUNC, + OSVERSIONINFOEX_1sizeof_FUNC, OUTLINETEXTMETRIC_1sizeof_FUNC, OffsetRect_FUNC, OffsetRgn_FUNC, @@ -552,6 +554,7 @@ typedef enum { ReplyMessage_FUNC, RestoreDC_FUNC, RoundRect_FUNC, + RtlGetVersion_FUNC, SAFEARRAYBOUND_1sizeof_FUNC, SAFEARRAY_1sizeof_FUNC, SCRIPT_1ANALYSIS_1sizeof_FUNC, diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_structs.c b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_structs.c index 3a2588c7f7..b7a6f7ec6b 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_structs.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_structs.c @@ -4213,6 +4213,73 @@ void setNOTIFYICONDATAFields(JNIEnv *env, jobject lpObject, NOTIFYICONDATA *lpSt } #endif +#ifndef NO_OSVERSIONINFOEX +typedef struct OSVERSIONINFOEX_FID_CACHE { + int cached; + jclass clazz; + jfieldID dwOSVersionInfoSize, dwMajorVersion, dwMinorVersion, dwBuildNumber, dwPlatformId, szCSDVersion, wServicePackMajor, wServicePackMinor, wSuiteMask, wProductType, wReserved; +} OSVERSIONINFOEX_FID_CACHE; + +OSVERSIONINFOEX_FID_CACHE OSVERSIONINFOEXFc; + +void cacheOSVERSIONINFOEXFields(JNIEnv *env, jobject lpObject) +{ + if (OSVERSIONINFOEXFc.cached) return; + OSVERSIONINFOEXFc.clazz = (*env)->GetObjectClass(env, lpObject); + OSVERSIONINFOEXFc.dwOSVersionInfoSize = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "dwOSVersionInfoSize", "I"); + OSVERSIONINFOEXFc.dwMajorVersion = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "dwMajorVersion", "I"); + OSVERSIONINFOEXFc.dwMinorVersion = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "dwMinorVersion", "I"); + OSVERSIONINFOEXFc.dwBuildNumber = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "dwBuildNumber", "I"); + OSVERSIONINFOEXFc.dwPlatformId = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "dwPlatformId", "I"); + OSVERSIONINFOEXFc.szCSDVersion = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "szCSDVersion", "[C"); + OSVERSIONINFOEXFc.wServicePackMajor = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "wServicePackMajor", "I"); + OSVERSIONINFOEXFc.wServicePackMinor = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "wServicePackMinor", "I"); + OSVERSIONINFOEXFc.wSuiteMask = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "wSuiteMask", "I"); + OSVERSIONINFOEXFc.wProductType = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "wProductType", "I"); + OSVERSIONINFOEXFc.wReserved = (*env)->GetFieldID(env, OSVERSIONINFOEXFc.clazz, "wReserved", "I"); + OSVERSIONINFOEXFc.cached = 1; +} + +OSVERSIONINFOEX *getOSVERSIONINFOEXFields(JNIEnv *env, jobject lpObject, OSVERSIONINFOEX *lpStruct) +{ + if (!OSVERSIONINFOEXFc.cached) cacheOSVERSIONINFOEXFields(env, lpObject); + lpStruct->dwOSVersionInfoSize = (*env)->GetIntField(env, lpObject, OSVERSIONINFOEXFc.dwOSVersionInfoSize); + lpStruct->dwMajorVersion = (*env)->GetIntField(env, lpObject, OSVERSIONINFOEXFc.dwMajorVersion); + lpStruct->dwMinorVersion = (*env)->GetIntField(env, lpObject, OSVERSIONINFOEXFc.dwMinorVersion); + lpStruct->dwBuildNumber = (*env)->GetIntField(env, lpObject, OSVERSIONINFOEXFc.dwBuildNumber); + lpStruct->dwPlatformId = (*env)->GetIntField(env, lpObject, OSVERSIONINFOEXFc.dwPlatformId); + { + jcharArray lpObject1 = (jcharArray)(*env)->GetObjectField(env, lpObject, OSVERSIONINFOEXFc.szCSDVersion); + (*env)->GetCharArrayRegion(env, lpObject1, 0, sizeof(lpStruct->szCSDVersion) / sizeof(jchar), (jchar *)lpStruct->szCSDVersion); + } + lpStruct->wServicePackMajor = (*env)->GetIntField(env, lpObject, OSVERSIONINFOEXFc.wServicePackMajor); + lpStruct->wServicePackMinor = (*env)->GetIntField(env, lpObject, OSVERSIONINFOEXFc.wServicePackMinor); + lpStruct->wSuiteMask = (*env)->GetIntField(env, lpObject, OSVERSIONINFOEXFc.wSuiteMask); + lpStruct->wProductType = (*env)->GetIntField(env, lpObject, OSVERSIONINFOEXFc.wProductType); + lpStruct->wReserved = (*env)->GetIntField(env, lpObject, OSVERSIONINFOEXFc.wReserved); + return lpStruct; +} + +void setOSVERSIONINFOEXFields(JNIEnv *env, jobject lpObject, OSVERSIONINFOEX *lpStruct) +{ + if (!OSVERSIONINFOEXFc.cached) cacheOSVERSIONINFOEXFields(env, lpObject); + (*env)->SetIntField(env, lpObject, OSVERSIONINFOEXFc.dwOSVersionInfoSize, (jint)lpStruct->dwOSVersionInfoSize); + (*env)->SetIntField(env, lpObject, OSVERSIONINFOEXFc.dwMajorVersion, (jint)lpStruct->dwMajorVersion); + (*env)->SetIntField(env, lpObject, OSVERSIONINFOEXFc.dwMinorVersion, (jint)lpStruct->dwMinorVersion); + (*env)->SetIntField(env, lpObject, OSVERSIONINFOEXFc.dwBuildNumber, (jint)lpStruct->dwBuildNumber); + (*env)->SetIntField(env, lpObject, OSVERSIONINFOEXFc.dwPlatformId, (jint)lpStruct->dwPlatformId); + { + jcharArray lpObject1 = (jcharArray)(*env)->GetObjectField(env, lpObject, OSVERSIONINFOEXFc.szCSDVersion); + (*env)->SetCharArrayRegion(env, lpObject1, 0, sizeof(lpStruct->szCSDVersion) / sizeof(jchar), (jchar *)lpStruct->szCSDVersion); + } + (*env)->SetIntField(env, lpObject, OSVERSIONINFOEXFc.wServicePackMajor, (jint)lpStruct->wServicePackMajor); + (*env)->SetIntField(env, lpObject, OSVERSIONINFOEXFc.wServicePackMinor, (jint)lpStruct->wServicePackMinor); + (*env)->SetIntField(env, lpObject, OSVERSIONINFOEXFc.wSuiteMask, (jint)lpStruct->wSuiteMask); + (*env)->SetIntField(env, lpObject, OSVERSIONINFOEXFc.wProductType, (jint)lpStruct->wProductType); + (*env)->SetIntField(env, lpObject, OSVERSIONINFOEXFc.wReserved, (jint)lpStruct->wReserved); +} +#endif + #ifndef NO_OUTLINETEXTMETRIC typedef struct OUTLINETEXTMETRIC_FID_CACHE { int cached; diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_structs.h b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_structs.h index af90404936..371671910f 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_structs.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_structs.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2020 IBM Corporation and others. + * Copyright (c) 2000, 2021 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -965,6 +965,18 @@ void setNOTIFYICONDATAFields(JNIEnv *env, jobject lpObject, NOTIFYICONDATA *lpSt #define NOTIFYICONDATA_sizeof() 0 #endif +#ifndef NO_OSVERSIONINFOEX +void cacheOSVERSIONINFOEXFields(JNIEnv *env, jobject lpObject); +OSVERSIONINFOEX *getOSVERSIONINFOEXFields(JNIEnv *env, jobject lpObject, OSVERSIONINFOEX *lpStruct); +void setOSVERSIONINFOEXFields(JNIEnv *env, jobject lpObject, OSVERSIONINFOEX *lpStruct); +#define OSVERSIONINFOEX_sizeof() sizeof(OSVERSIONINFOEX) +#else +#define cacheOSVERSIONINFOEXFields(a,b) +#define getOSVERSIONINFOEXFields(a,b,c) NULL +#define setOSVERSIONINFOEXFields(a,b,c) +#define OSVERSIONINFOEX_sizeof() 0 +#endif + #ifndef NO_OUTLINETEXTMETRIC void cacheOUTLINETEXTMETRICFields(JNIEnv *env, jobject lpObject); OUTLINETEXTMETRIC *getOUTLINETEXTMETRICFields(JNIEnv *env, jobject lpObject, OUTLINETEXTMETRIC *lpStruct); 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 bee9defea0..175ce13159 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 @@ -28,7 +28,27 @@ public class OS extends C { * SWT Windows flags */ public static final boolean IsDBLocale; + /** + * WARNING: This value can't be trusted since Win10. If the launcher's exe + * doesn't have compatibility GUID in its manifest:<br> + * <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/><br> + * then '6.2.9200' will be returned (version number for Win8). + * JDK11 has the compatibility GUID, but Eclipse's launcher doesn't! + * This may cause different behavior in debugger and in released SWT. + */ public static final int WIN32_VERSION; + /** + * Always reports the correct build number, regardless of manifest and + * compatibility GUIDs. Note that build number alone is sufficient to + * identify Windows version. + */ + public static final int WIN32_BUILD; + /** + * Values taken from https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions + */ + public static final int WIN32_BUILD_WIN10_1809 = 17763; // "Windows 10 October 2018 Update" + public static final int WIN32_BUILD_WIN10_2004 = 19041; // "Windows 10 May 2020 Update" + public static final int WIN32_BUILD_WIN11_21H2 = 22000; // Initial Windows 11 release public static final String NO_MANIFEST = "org.eclipse.swt.internal.win32.OS.NO_MANIFEST"; @@ -44,6 +64,20 @@ public class OS extends C { int dwVersion = OS.GetVersion (); WIN32_VERSION = VERSION (dwVersion & 0xff, (dwVersion >> 8) & 0xff); + /* + * Starting with Windows 10, GetVersionEx() lies about version unless + * application manifest has a proper entry. RtlGetVersion() always + * reports true version. + */ + OSVERSIONINFOEX osVersionInfoEx = new OSVERSIONINFOEX (); + osVersionInfoEx.dwOSVersionInfoSize = OSVERSIONINFOEX.sizeof; + if (0 == OS.RtlGetVersion (osVersionInfoEx)) { + WIN32_BUILD = osVersionInfoEx.dwBuildNumber; + } else { + System.err.println ("SWT: OS: Failed to detect Windows build number"); + WIN32_BUILD = 0; + } + /* Load the manifest to force the XP Theme */ if (System.getProperty (NO_MANIFEST) == null) { ACTCTX pActCtx = new ACTCTX (); @@ -1919,6 +1953,7 @@ public static final native int NONCLIENTMETRICS_sizeof (); /** @method flags=const */ public static final native int NOTIFYICONDATA_V2_SIZE (); public static final native int OUTLINETEXTMETRIC_sizeof (); +public static final native int OSVERSIONINFOEX_sizeof (); public static final native int PAINTSTRUCT_sizeof (); public static final native int POINT_sizeof (); public static final native int PRINTDLG_sizeof (); @@ -2211,6 +2246,7 @@ public static final void setTheme(boolean isDarkTheme) { throw new NullPointerException("Display must be already created before you call OS.setTheme()"); display.setData("org.eclipse.swt.internal.win32.useDarkModeExplorerTheme", isDarkTheme); + display.setData("org.eclipse.swt.internal.win32.useShellTitleColoring", isDarkTheme); display.setData("org.eclipse.swt.internal.win32.menuBarForegroundColor", isDarkTheme ? new Color(display, 0xD0, 0xD0, 0xD0) : null); display.setData("org.eclipse.swt.internal.win32.menuBarBackgroundColor", isDarkTheme ? new Color(display, 0x30, 0x30, 0x30) : null); display.setData("org.eclipse.swt.internal.win32.menuBarBorderColor", isDarkTheme ? new Color(display, 0x50, 0x50, 0x50) : null); @@ -2562,6 +2598,8 @@ public static final native int DrawThemeBackground (long hTheme, long hdc, int i * @param pRect flags=no_out */ public static final native int DrawThemeText (long hTheme, long hdc, int iPartId, int iStateId, char[] pszText, int iCharCount, int dwTextFlags, int dwTextFlags2, RECT pRect); +/** @param hwnd cast=(HDC) */ +public static final native boolean DwmSetWindowAttribute (long hwnd, int dwAttribute, int[] pvAttribute, int cbAttribute); /** @param hdc cast=(HDC) */ public static final native boolean Ellipse (long hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect); /** @param hMenu cast=(HMENU) */ @@ -3857,6 +3895,8 @@ public static final native boolean ReplyMessage (long lResult); public static final native boolean RestoreDC (long hdc, int nSavedDC); /** @param hdc cast=(HDC) */ public static final native boolean RoundRect (long hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nWidth, int nHeight); +/** @method flags=dynamic */ +public static final native int RtlGetVersion (OSVERSIONINFOEX lpVersionInformation); /** @param hdc cast=(HDC) */ public static final native int SaveDC (long hdc); /** @param hWnd cast=(HWND) */ diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OSVERSIONINFOEX.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OSVERSIONINFOEX.java new file mode 100644 index 0000000000..ecec0b653e --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OSVERSIONINFOEX.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2021 Syntevo 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: + * Syntevo - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.internal.win32; + +public class OSVERSIONINFOEX { + public int dwOSVersionInfoSize; + public int dwMajorVersion; + public int dwMinorVersion; + public int dwBuildNumber; + public int dwPlatformId; + public char[] szCSDVersion = new char[128]; + public int wServicePackMajor; + public int wServicePackMinor; + public int wSuiteMask; + public int wProductType; + public int wReserved; + + public static final int sizeof = OS.OSVERSIONINFOEX_sizeof (); +} 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 94b1cb7f2d..d0fe147cd0 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 @@ -184,6 +184,16 @@ public class Display extends Device { static final String USE_DARKMODE_EXPLORER_THEME_KEY = "org.eclipse.swt.internal.win32.useDarkModeExplorerTheme"; boolean useDarkModeExplorerTheme; /** + * Sets Shell titles to match theme selected in Windows. That is, dark is system is dark. + * Limitations:<br> + * <ul> + * <li>Only available since Win10.</li> + * <li>Does not affect already created Shells.</li> + * </ul> + */ + static final String USE_SHELL_TITLE_COLORING = "org.eclipse.swt.internal.win32.useShellTitleColoring"; + boolean useShellTitleColoring; + /** * Configures background/foreground colors of Menu(SWT.BAR).<br> * Side effects: * <ul> @@ -2093,9 +2103,9 @@ ImageList getImageListToolBarHot (int style, int width, int height) { public static boolean isSystemDarkTheme () { boolean isDarkTheme = false; /* - * Win10 onwards we can read the Dark Theme from the OS registry. + * The registry settings, and Dark Theme itself, is present since Win10 1809 */ - if (OS.WIN32_VERSION >= OS.VERSION (10, 0)) { + if (OS.WIN32_BUILD >= OS.WIN32_BUILD_WIN10_1809) { try { int result = OS.readRegistryDword(OS.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", "AppsUseLightTheme"); @@ -4412,6 +4422,9 @@ public void setData (String key, Object value) { OS.SetPreferredAppMode(PreferredAppMode_Default); } return; + case USE_SHELL_TITLE_COLORING: + useShellTitleColoring = !disableCustomThemeTweaks && _toBoolean(value); + return; case MENUBAR_FOREGROUND_COLOR_KEY: menuBarForegroundPixel = disableCustomThemeTweaks ? -1 : _toColorPixel(value); return; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Shell.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Shell.java index e048b8012b..8be1e4314e 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Shell.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Shell.java @@ -575,6 +575,24 @@ void createBalloonTipHandle () { OS.SetWindowLongPtr (balloonTipHandle, OS.GWLP_WNDPROC, display.windowProc); } +void setTitleColoring() { + int attributeID = 0; + if (OS.WIN32_BUILD >= OS.WIN32_BUILD_WIN10_2004) { + // Documented since build 20348, but was already present since build 19041 + final int DWMWA_USE_IMMERSIVE_DARK_MODE = 20; + attributeID = DWMWA_USE_IMMERSIVE_DARK_MODE; + } else if (OS.WIN32_BUILD >= OS.WIN32_BUILD_WIN10_1809) { + // Undocumented value + attributeID = 19; + } else { + // Not supported + return; + } + + int[] value = new int[] {1}; + OS.DwmSetWindowAttribute (handle, attributeID, value, 4); +} + @Override void createHandle () { boolean embedded = handle != 0 && (state & FOREIGN_HANDLE) == 0; @@ -607,6 +625,10 @@ void createHandle () { // if ((style & SWT.ON_TOP) != 0) display.lockActiveWindow = false; if (!embedded) { + if (display.useShellTitleColoring) { + setTitleColoring(); + } + int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); bits &= ~(OS.WS_OVERLAPPED | OS.WS_CAPTION); bits |= OS.WS_POPUP; |