Skip to content

Commit 17be25c

Browse files
authored
在 Linux 平台使用 dbus-send 检测深色模式设置 (#5317)
1 parent 5a518ce commit 17be25c

File tree

2 files changed

+49
-3
lines changed

2 files changed

+49
-3
lines changed

HMCL/src/main/java/org/jackhuang/hmcl/theme/Themes.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.glavo.monetfx.beans.property.ReadOnlyColorSchemeProperty;
3737
import org.glavo.monetfx.beans.property.SimpleColorSchemeProperty;
3838
import org.jackhuang.hmcl.ui.FXUtils;
39+
import org.jackhuang.hmcl.util.io.FileUtils;
3940
import org.jackhuang.hmcl.ui.WindowsNativeUtils;
4041
import org.jackhuang.hmcl.util.platform.NativeUtils;
4142
import org.jackhuang.hmcl.util.platform.OSVersion;
@@ -46,9 +47,12 @@
4647
import org.jackhuang.hmcl.util.platform.windows.WinReg;
4748
import org.jackhuang.hmcl.util.platform.windows.WinTypes;
4849

50+
import java.nio.file.Path;
51+
import java.time.Duration;
4952
import java.util.*;
5053

5154
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
55+
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
5256

5357
/// @author Glavo
5458
public final class Themes {
@@ -113,6 +117,7 @@ private static Brightness getDefaultBrightness() {
113117
if (defaultBrightness != null)
114118
return defaultBrightness;
115119

120+
LOG.info("Detecting system theme brightness");
116121
Brightness brightness = Brightness.DEFAULT;
117122
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
118123
WinReg reg = WinReg.INSTANCE;
@@ -130,7 +135,38 @@ private static Brightness getDefaultBrightness() {
130135
// If the key does not exist, it means Light mode is used
131136
brightness = Brightness.LIGHT;
132137
}
138+
} else if (OperatingSystem.CURRENT_OS == OperatingSystem.LINUX) {
139+
Path dbusSend = SystemUtils.which("dbus-send");
140+
if (dbusSend != null) {
141+
try {
142+
String[] result = SystemUtils.run(List.of(
143+
FileUtils.getAbsolutePath(dbusSend),
144+
"--session",
145+
"--print-reply=literal",
146+
"--reply-timeout=1000",
147+
"--dest=org.freedesktop.portal.Desktop",
148+
"/org/freedesktop/portal/desktop",
149+
"org.freedesktop.portal.Settings.Read",
150+
"string:org.freedesktop.appearance",
151+
"string:color-scheme"
152+
), Duration.ofSeconds(2)).trim().split(" ");
153+
154+
if (result.length > 0) {
155+
String value = result[result.length - 1];
156+
// 1: prefer dark
157+
// 2: prefer light
158+
if ("1".equals(value)) {
159+
brightness = Brightness.DARK;
160+
} else if ("2".equals(value)) {
161+
brightness = Brightness.LIGHT;
162+
}
163+
}
164+
} catch (Exception e) {
165+
LOG.warning("Failed to get system theme from D-Bus", e);
166+
}
167+
}
133168
}
169+
LOG.info("Detected system theme brightness: " + brightness);
134170

135171
return defaultBrightness = brightness;
136172
}

HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/SystemUtils.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.nio.file.Files;
3030
import java.nio.file.Path;
3131
import java.nio.file.Paths;
32+
import java.time.Duration;
3233
import java.util.*;
3334
import java.util.concurrent.CompletableFuture;
3435
import java.util.concurrent.TimeUnit;
@@ -75,12 +76,21 @@ public static int callExternalProcess(ProcessBuilder processBuilder) throws IOEx
7576
return managedProcess.getProcess().waitFor();
7677
}
7778

79+
private static final Duration DEFAULT_MAX_WAIT_TIME = Duration.ofSeconds(15);
80+
7881
public static String run(String... command) throws Exception {
79-
return run(Arrays.asList(command),
80-
inputStream -> IOUtils.readFullyAsString(inputStream, OperatingSystem.NATIVE_CHARSET));
82+
return run(List.of(command), DEFAULT_MAX_WAIT_TIME);
83+
}
84+
85+
public static String run(List<String> command, Duration maxWaitTime) throws Exception {
86+
return run(command, inputStream -> IOUtils.readFullyAsString(inputStream, OperatingSystem.NATIVE_CHARSET), maxWaitTime);
8187
}
8288

8389
public static <T> T run(List<String> command, ExceptionalFunction<InputStream, T, ?> convert) throws Exception {
90+
return run(command, convert, DEFAULT_MAX_WAIT_TIME);
91+
}
92+
93+
public static <T> T run(List<String> command, ExceptionalFunction<InputStream, T, ?> convert, Duration maxWaitTime) throws Exception {
8494
Process process = new ProcessBuilder(command)
8595
.redirectError(ProcessBuilder.Redirect.DISCARD)
8696
.start();
@@ -90,7 +100,7 @@ public static <T> T run(List<String> command, ExceptionalFunction<InputStream, T
90100
Lang.wrap(() -> convert.apply(inputStream)),
91101
Schedulers.io());
92102

93-
if (!process.waitFor(15, TimeUnit.SECONDS))
103+
if (!process.waitFor(maxWaitTime.toMillis(), TimeUnit.MILLISECONDS))
94104
throw new TimeoutException();
95105

96106
if (process.exitValue() != 0)

0 commit comments

Comments
 (0)