From 17be25c0364de8609b78e6b19da355f203f70760 Mon Sep 17 00:00:00 2001 From: Glavo Date: Sun, 1 Feb 2026 16:05:19 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=A8=20Linux=20=E5=B9=B3=E5=8F=B0=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=20dbus-send=20=E6=A3=80=E6=B5=8B=E6=B7=B1=E8=89=B2?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E8=AE=BE=E7=BD=AE=20(#5317)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/jackhuang/hmcl/theme/Themes.java | 36 +++++++++++++++++++ .../hmcl/util/platform/SystemUtils.java | 16 +++++++-- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/theme/Themes.java b/HMCL/src/main/java/org/jackhuang/hmcl/theme/Themes.java index 4a855977f..fbee0b817 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/theme/Themes.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/theme/Themes.java @@ -36,6 +36,7 @@ import org.glavo.monetfx.beans.property.ColorSchemeProperty; import org.glavo.monetfx.beans.property.ReadOnlyColorSchemeProperty; import org.glavo.monetfx.beans.property.SimpleColorSchemeProperty; import org.jackhuang.hmcl.ui.FXUtils; +import org.jackhuang.hmcl.util.io.FileUtils; import org.jackhuang.hmcl.ui.WindowsNativeUtils; import org.jackhuang.hmcl.util.platform.NativeUtils; import org.jackhuang.hmcl.util.platform.OSVersion; @@ -46,9 +47,12 @@ import org.jackhuang.hmcl.util.platform.windows.WinConstants; import org.jackhuang.hmcl.util.platform.windows.WinReg; import org.jackhuang.hmcl.util.platform.windows.WinTypes; +import java.nio.file.Path; +import java.time.Duration; import java.util.*; import static org.jackhuang.hmcl.setting.ConfigHolder.config; +import static org.jackhuang.hmcl.util.logging.Logger.LOG; /// @author Glavo public final class Themes { @@ -113,6 +117,7 @@ public final class Themes { if (defaultBrightness != null) return defaultBrightness; + LOG.info("Detecting system theme brightness"); Brightness brightness = Brightness.DEFAULT; if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) { WinReg reg = WinReg.INSTANCE; @@ -130,7 +135,38 @@ public final class Themes { // If the key does not exist, it means Light mode is used brightness = Brightness.LIGHT; } + } else if (OperatingSystem.CURRENT_OS == OperatingSystem.LINUX) { + Path dbusSend = SystemUtils.which("dbus-send"); + if (dbusSend != null) { + try { + String[] result = SystemUtils.run(List.of( + FileUtils.getAbsolutePath(dbusSend), + "--session", + "--print-reply=literal", + "--reply-timeout=1000", + "--dest=org.freedesktop.portal.Desktop", + "/org/freedesktop/portal/desktop", + "org.freedesktop.portal.Settings.Read", + "string:org.freedesktop.appearance", + "string:color-scheme" + ), Duration.ofSeconds(2)).trim().split(" "); + + if (result.length > 0) { + String value = result[result.length - 1]; + // 1: prefer dark + // 2: prefer light + if ("1".equals(value)) { + brightness = Brightness.DARK; + } else if ("2".equals(value)) { + brightness = Brightness.LIGHT; + } + } + } catch (Exception e) { + LOG.warning("Failed to get system theme from D-Bus", e); + } + } } + LOG.info("Detected system theme brightness: " + brightness); return defaultBrightness = brightness; } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/SystemUtils.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/SystemUtils.java index 2675d1046..b3f1e9740 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/SystemUtils.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/SystemUtils.java @@ -29,6 +29,7 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.time.Duration; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; @@ -75,12 +76,21 @@ public final class SystemUtils { return managedProcess.getProcess().waitFor(); } + private static final Duration DEFAULT_MAX_WAIT_TIME = Duration.ofSeconds(15); + public static String run(String... command) throws Exception { - return run(Arrays.asList(command), - inputStream -> IOUtils.readFullyAsString(inputStream, OperatingSystem.NATIVE_CHARSET)); + return run(List.of(command), DEFAULT_MAX_WAIT_TIME); + } + + public static String run(List command, Duration maxWaitTime) throws Exception { + return run(command, inputStream -> IOUtils.readFullyAsString(inputStream, OperatingSystem.NATIVE_CHARSET), maxWaitTime); } public static T run(List command, ExceptionalFunction convert) throws Exception { + return run(command, convert, DEFAULT_MAX_WAIT_TIME); + } + + public static T run(List command, ExceptionalFunction convert, Duration maxWaitTime) throws Exception { Process process = new ProcessBuilder(command) .redirectError(ProcessBuilder.Redirect.DISCARD) .start(); @@ -90,7 +100,7 @@ public final class SystemUtils { Lang.wrap(() -> convert.apply(inputStream)), Schedulers.io()); - if (!process.waitFor(15, TimeUnit.SECONDS)) + if (!process.waitFor(maxWaitTime.toMillis(), TimeUnit.MILLISECONDS)) throw new TimeoutException(); if (process.exitValue() != 0)