From 030a03a0fc776e2fb05dc5e820e8347fb20a0615 Mon Sep 17 00:00:00 2001 From: Alex Bates Date: Sun, 8 Feb 2026 10:10:26 +0000 Subject: [PATCH] detect system-wide dark mode and use that --- build.gradle.kts | 49 +++++++++++++------------ gradle/verification-metadata.xml | 61 ++++++++++++++++++++++++++++++++ src/main/java/app/Themes.java | 44 ++++++++++++++++++++--- 3 files changed, 126 insertions(+), 28 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 28796ca..5edda59 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,6 +11,7 @@ val appVersion = appProperties.getProperty("version") repositories { mavenCentral() + maven { url = uri("https://jitpack.io") } } plugins { @@ -28,28 +29,28 @@ java { dependencies { implementation(platform("org.lwjgl:lwjgl-bom:3.3.3")) - + implementation("org.lwjgl", "lwjgl") implementation("org.lwjgl", "lwjgl-opengl") implementation("org.lwjgl", "lwjgl-jawt") implementation("org.lwjgl", "lwjgl-glfw") implementation("org.lwjgl", "lwjgl-tinyfd") implementation("org.lwjgl", "lwjgl-assimp") - + runtimeOnly("org.lwjgl:lwjgl::natives-windows") runtimeOnly("org.lwjgl:lwjgl::natives-windows-arm64") runtimeOnly("org.lwjgl:lwjgl::natives-macos") runtimeOnly("org.lwjgl:lwjgl::natives-macos-arm64") runtimeOnly("org.lwjgl:lwjgl::natives-linux") runtimeOnly("org.lwjgl:lwjgl::natives-linux-arm64") - + runtimeOnly("org.lwjgl:lwjgl-opengl::natives-windows") runtimeOnly("org.lwjgl:lwjgl-opengl::natives-windows-arm64") runtimeOnly("org.lwjgl:lwjgl-opengl::natives-macos") runtimeOnly("org.lwjgl:lwjgl-opengl::natives-macos-arm64") runtimeOnly("org.lwjgl:lwjgl-opengl::natives-linux") runtimeOnly("org.lwjgl:lwjgl-opengl::natives-linux-arm64") - + runtimeOnly("org.lwjgl:lwjgl-glfw::natives-windows") runtimeOnly("org.lwjgl:lwjgl-glfw::natives-windows-arm64") runtimeOnly("org.lwjgl:lwjgl-glfw::natives-macos") @@ -63,38 +64,40 @@ dependencies { runtimeOnly("org.lwjgl:lwjgl-tinyfd::natives-macos-arm64") runtimeOnly("org.lwjgl:lwjgl-tinyfd::natives-linux") runtimeOnly("org.lwjgl:lwjgl-tinyfd::natives-linux-arm64") - + runtimeOnly("org.lwjgl:lwjgl-assimp::natives-windows") runtimeOnly("org.lwjgl:lwjgl-assimp::natives-windows-arm64") runtimeOnly("org.lwjgl:lwjgl-assimp::natives-macos") runtimeOnly("org.lwjgl:lwjgl-assimp::natives-macos-arm64") runtimeOnly("org.lwjgl:lwjgl-assimp::natives-linux") runtimeOnly("org.lwjgl:lwjgl-assimp::natives-linux-arm64") - + implementation("org.lwjglx:lwjgl3-awt:0.2.2") { exclude(group = "org.lwjgl") // https://github.com/LWJGLX/lwjgl3-awt/issues/74 } - + implementation("commons-io:commons-io:2.16.1") implementation("org.apache.commons:commons-text:1.12.0") implementation("org.apache.commons:commons-lang3:3.14.0") - + implementation("com.miglayout:miglayout-core:11.3") implementation("com.miglayout:miglayout-swing:11.3") - + implementation("com.alexandriasoftware.swing:jsplitbutton:1.3.1") implementation("com.alexdupre:pngj:2.1.2.1") - + implementation("com.google.code.gson:gson:2.10.1") implementation("org.yaml:snakeyaml:2.2") - + implementation("com.formdev:flatlaf:3.4.1") implementation("com.formdev:flatlaf-intellij-themes:3.4.1") implementation("com.formdev:flatlaf-extras:3.4.1") - + + implementation("com.github.Dansoftowner:jSystemThemeDetector:3.6") + implementation(files("lib/org.eclipse.cdt.core-5.11.0.jar")) implementation(files("lib/org.eclipse.equinox.common-3.6.0.jar")) - + implementation("org.ahocorasick:ahocorasick:0.6.3") } @@ -111,7 +114,7 @@ tasks { classpath = files() // use empty classpath since there are no dependencies options.release.set(8) } - + val jarBoot = register("jarBoot") { dependsOn(compileBoot) archiveBaseName.set("boot") @@ -120,7 +123,7 @@ tasks { } from(bootBuildDir) } - + val compileApp = register("compileApp") { source = fileTree("src/main/java") destinationDirectory.set(appBuildDir.get().asFile) @@ -128,7 +131,7 @@ tasks { options.release.set(17) options.compilerArgs.add("-Xlint:deprecation") } - + val jarApp = register("jarApp") { dependsOn(compileApp) archiveBaseName.set("main-app") @@ -140,16 +143,16 @@ tasks { shadowJar { dependsOn(jarBoot, jarApp) - + from(bootBuildDir, appBuildDir) - + mergeServiceFiles("META-INF/spring.*") exclude("META-INF/*.SF") exclude("META-INF/*.DSA") exclude("META-INF/*.RSA") exclude("META-INF/LICENSE") archiveFileName.set("StarRod.jar") - + manifest { attributes["Main-Class"] = bootMain attributes["App-Version"] = appVersion @@ -162,20 +165,20 @@ tasks { register("createReleaseZip") { dependsOn(clean, licenseReport, shadowJar) - + group = "release" description = "Create zip file for Star Rod release" from(shadowJar.get().outputs.files) - + from(file(licenseBuildDir)) { into("licenses") } - + from(file("exec")) { into("") } - + val versionTag = versioning.info.tag val commitHash = versioning.info.build diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 1b1051a..05e5d74 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -86,6 +86,14 @@ + + + + + + + + @@ -99,6 +107,19 @@ + + + + + + + + + + + + + @@ -271,6 +292,14 @@ + + + + + + + + @@ -292,6 +321,14 @@ + + + + + + + + @@ -323,6 +360,14 @@ + + + + + + + + @@ -331,6 +376,14 @@ + + + + + + + + @@ -624,6 +677,14 @@ + + + + + + + + diff --git a/src/main/java/app/Themes.java b/src/main/java/app/Themes.java index 6476359..a7d7f7f 100644 --- a/src/main/java/app/Themes.java +++ b/src/main/java/app/Themes.java @@ -11,11 +11,14 @@ import java.util.jar.JarEntry; import java.util.jar.JarFile; import javax.swing.UIManager; +import javax.swing.SwingUtilities; import org.apache.commons.text.WordUtils; import com.formdev.flatlaf.IntelliJTheme; +import com.jthemedetecor.OsThemeDetector; + import app.input.IOUtils; import util.CaseInsensitiveMap; import util.Logger; @@ -154,8 +157,10 @@ public abstract class Themes public static void setThemeByKey(String themeKey) { - if (themeKey == null || themeKey.isEmpty()) - themeKey = DEFAULT_THEME.key; + if (themeKey == null || themeKey.isEmpty()) { + setSystemTheme(); + return; + } if (currentTheme != null && themeKey.equalsIgnoreCase(currentTheme.key)) return; @@ -164,6 +169,34 @@ public abstract class Themes setTheme(newTheme); } + private static boolean isSystem = false; + + public static void setSystemTheme() + { + isSystem = true; + if (OsThemeDetector.getDetector().isDark()) + setThemeByKey("macOS Dark"); + else + setThemeByKey("macOS Light"); + } + + public static boolean isSystemTheme() + { + return isSystem; + } + + private static void registerSystemThemeListener() + { + final OsThemeDetector detector = OsThemeDetector.getDetector(); + detector.registerListener(isDark -> { + if (isSystem) { + SwingUtilities.invokeLater(() -> { + setSystemTheme(); + }); + } + }); + } + private static void addCustomJarTheme(File file) { try (JarFile jar = new JarFile(file)) { @@ -200,10 +233,11 @@ public abstract class Themes static { if (!Environment.isCommandLine()) { // @formatter:off - DEFAULT_THEME = Theme.createBuiltIn("Flat Dark", "com.formdev.flatlaf.FlatDarkLaf"); + DEFAULT_THEME = Theme.createBuiltIn("Flat Light", "com.formdev.flatlaf.FlatLightLaf"); addTheme(DEFAULT_THEME); - - addTheme(Theme.createBuiltIn("Flat Light", "com.formdev.flatlaf.FlatLightLaf")); + addTheme(Theme.createBuiltIn("Flat Dark", "com.formdev.flatlaf.FlatDarkLaf")); + addTheme(Theme.createBuiltIn("macOS Light", "com.formdev.flatlaf.themes.FlatMacLightLaf")); + addTheme(Theme.createBuiltIn("macOS Dark", "com.formdev.flatlaf.themes.FlatMacDarkLaf")); addTheme(Theme.createBuiltIn("Arc Light", "com.formdev.flatlaf.intellijthemes.FlatArcIJTheme")); addTheme(Theme.createBuiltIn("Arc Light Orange", "com.formdev.flatlaf.intellijthemes.FlatArcOrangeIJTheme")); addTheme(Theme.createBuiltIn("Arc Dark", "com.formdev.flatlaf.intellijthemes.FlatArcDarkIJTheme")); -- 2.51.2