diff --git a/windows/src/main/cpp/ThemeInfo.cpp b/windows/src/main/cpp/ThemeInfo.cpp index c4eda2e8..90fa62f4 100644 --- a/windows/src/main/cpp/ThemeInfo.cpp +++ b/windows/src/main/cpp/ThemeInfo.cpp @@ -39,9 +39,13 @@ #define HIGH_CONTRAST_THEME_KEY ("High Contrast Scheme") #define HIGH_CONTRAST_LIGHT_THEME ("High Contrast White") +#define ACCENT_COLOR_PATH "SOFTWARE\\Microsoft\\Windows\\DWM" +#define ACCENT_COLOR_KEY "ColorizationColor" + #define DARK_MODE_DEFAULT_VALUE false #define HIGH_CONTRAST_DEFAULT_VALUE false #define FONT_SCALE_DEFAULT_VALUE 100 +#define ACCENT_COLOR_DEFAULT_VALUE 0 void ModifyFlags(DWORD &flags) @@ -136,26 +140,44 @@ bool RegisterRegistryEvent(const LPCSTR subKey, HANDLE event) } else { - return false; + return FALSE; + } +} + +int GetAccentColor() +{ + try + { + return RegGetDword(HKEY_CURRENT_USER, ACCENT_COLOR_PATH, ACCENT_COLOR_KEY); + } + catch (LONG e) + { + return ACCENT_COLOR_DEFAULT_VALUE; } } JNIEXPORT jboolean JNICALL Java_com_github_weisj_darklaf_platform_windows_JNIThemeInfoWindows_isDarkThemeEnabled(JNIEnv *env, jclass obj) { - return (jboolean)IsDarkMode(); + return (jboolean) IsDarkMode(); } JNIEXPORT jboolean JNICALL Java_com_github_weisj_darklaf_platform_windows_JNIThemeInfoWindows_isHighContrastEnabled(JNIEnv *env, jclass obj) { - return (jboolean)IsHighContrastMode(); + return (jboolean) IsHighContrastMode(); } JNIEXPORT jlong JNICALL Java_com_github_weisj_darklaf_platform_windows_JNIThemeInfoWindows_getFontScaleFactor(JNIEnv *env, jclass obj) { - return (jlong)GetTextScaleFactor(); + return (jlong) GetTextScaleFactor(); +} + +JNIEXPORT jint JNICALL +Java_com_github_weisj_darklaf_platform_windows_JNIThemeInfoWindows_getAccentColor(JNIEnv *env, jclass obj) +{ + return (jint) GetAccentColor(); } JNIEXPORT jlong JNICALL @@ -177,5 +199,6 @@ Java_com_github_weisj_darklaf_platform_windows_JNIThemeInfoWindows_waitPreferenc if (!RegisterRegistryEvent(FONT_SCALE_PATH, event)) return (jboolean) false; if (!RegisterRegistryEvent(DARK_MODE_PATH, event)) return (jboolean) false; if (!RegisterRegistryEvent(HIGH_CONTRAST_PATH, event)) return (jboolean) false; + if (!RegisterRegistryEvent(ACCENT_COLOR_PATH, event)) return (jboolean) false; return (jboolean) (WaitForSingleObject(event, INFINITE) != WAIT_FAILED); } diff --git a/windows/src/main/java/com/github/weisj/darklaf/platform/windows/JNIThemeInfoWindows.java b/windows/src/main/java/com/github/weisj/darklaf/platform/windows/JNIThemeInfoWindows.java index b00c6801..f34d48e7 100644 --- a/windows/src/main/java/com/github/weisj/darklaf/platform/windows/JNIThemeInfoWindows.java +++ b/windows/src/main/java/com/github/weisj/darklaf/platform/windows/JNIThemeInfoWindows.java @@ -46,6 +46,13 @@ public class JNIThemeInfoWindows { */ public static native long getFontScaleFactor(); + /** + * Returns the currently used accent color. + * + * @return the accent color in the format 0xAARRGGBB. + */ + public static native int getAccentColor(); + /** * Create a monitor event handle. * diff --git a/windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsPreferenceMonitor.java b/windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsPreferenceMonitor.java index 0c1e7e46..d471382f 100644 --- a/windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsPreferenceMonitor.java +++ b/windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsPreferenceMonitor.java @@ -23,6 +23,7 @@ */ package com.github.weisj.darklaf.platform.windows; +import java.awt.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Logger; @@ -31,12 +32,12 @@ public class WindowsPreferenceMonitor { private static final Logger LOGGER = Logger.getLogger(WindowsThemePreferenceProvider.class.getName()); private final WindowsThemePreferenceProvider preferenceProvider; - private Thread worker; private boolean darkMode; private boolean highContrast; private long fontScaleFactor; private long eventHandle; + private int color; private AtomicBoolean running = new AtomicBoolean(false); public WindowsPreferenceMonitor(final WindowsThemePreferenceProvider preferenceProvider) { @@ -49,11 +50,19 @@ public class WindowsPreferenceMonitor { boolean newDark = JNIThemeInfoWindows.isDarkThemeEnabled(); boolean newHighContrast = JNIThemeInfoWindows.isHighContrastEnabled(); long newFotScale = JNIThemeInfoWindows.getFontScaleFactor(); - if (darkMode != newDark || fontScaleFactor != newFotScale || highContrast != newHighContrast) { + int newColor = JNIThemeInfoWindows.getAccentColor(); + if (darkMode != newDark + || color != newColor + || fontScaleFactor != newFotScale + || highContrast != newHighContrast) { + if (newColor != color) { + System.out.println("Color changed to " + new Color(newColor)); + } darkMode = newDark; fontScaleFactor = newFotScale; highContrast = newHighContrast; - preferenceProvider.reportPreferenceChange(highContrast, darkMode, fontScaleFactor); + color = newColor; + preferenceProvider.reportPreferenceChange(highContrast, darkMode, fontScaleFactor, color); } } if (running.get()) { @@ -69,14 +78,14 @@ public class WindowsPreferenceMonitor { highContrast = JNIThemeInfoWindows.isHighContrastEnabled(); fontScaleFactor = JNIThemeInfoWindows.getFontScaleFactor(); eventHandle = JNIThemeInfoWindows.createEventHandle(); + color = JNIThemeInfoWindows.getAccentColor(); /* * In theory this shouldn't be necessary, but * it ensures that the registry listeners are actually unregistered. */ Runtime.getRuntime().addShutdownHook(new Thread(this::stop)); this.running.set(true); - worker = new Thread(this::run); - worker.start(); + new Thread(this::run).start(); } private void stop() { diff --git a/windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsThemePreferenceProvider.java b/windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsThemePreferenceProvider.java index 7c71c518..df6bbf03 100644 --- a/windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsThemePreferenceProvider.java +++ b/windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsThemePreferenceProvider.java @@ -25,6 +25,7 @@ package com.github.weisj.darklaf.platform.windows; import com.github.weisj.darklaf.theme.info.*; +import java.awt.*; import java.util.function.Consumer; public class WindowsThemePreferenceProvider implements ThemePreferenceProvider { @@ -40,16 +41,23 @@ public class WindowsThemePreferenceProvider implements ThemePreferenceProvider { boolean darkMode = JNIThemeInfoWindows.isDarkThemeEnabled(); boolean highContrast = JNIThemeInfoWindows.isHighContrastEnabled(); long fontScaling = JNIThemeInfoWindows.getFontScaleFactor(); - return create(highContrast, darkMode, fontScaling); + int accentColorRGB = JNIThemeInfoWindows.getAccentColor(); + return create(highContrast, darkMode, fontScaling, accentColorRGB); } - private PreferredThemeStyle create(final boolean highContrast, final boolean darkMode, final long fontScaling) { + private PreferredThemeStyle create(final boolean highContrast, final boolean darkMode, + final long fontScaling, final int accentColorRGB) { ContrastRule contrastRule = highContrast ? ContrastRule.HIGH_CONTRAST : ContrastRule.STANDARD; ColorToneRule toneRule = darkMode ? ColorToneRule.DARK : ColorToneRule.LIGHT; FontSizeRule fontSizeRule = FontSizeRule.relativeAdjustment(fontScaling / 100f); return new PreferredThemeStyle(contrastRule, toneRule, fontSizeRule); } + private Color createColorFromRGB(final int rgb) { + if (rgb == 0) return null; + return new Color(rgb); + } + @Override public void setReporting(final boolean reporting) { if (reporting && !WindowsLibrary.isLoaded()) WindowsLibrary.updateLibrary(); @@ -63,9 +71,10 @@ public class WindowsThemePreferenceProvider implements ThemePreferenceProvider { return monitor.isRunning(); } - void reportPreferenceChange(final boolean highContrast, final boolean darkMode, final long fontScaleFactor) { + void reportPreferenceChange(final boolean highContrast, final boolean darkMode, + final long fontScaleFactor, final int accentColorRGB) { if (callback != null) { - PreferredThemeStyle style = create(highContrast, darkMode, fontScaleFactor); + PreferredThemeStyle style = create(highContrast, darkMode, fontScaleFactor, accentColorRGB); callback.accept(style); } }