在 Linux 平台使用 dbus-send 检测深色模式设置 (#5317)
This commit is contained in:
@@ -36,6 +36,7 @@ import org.glavo.monetfx.beans.property.ColorSchemeProperty;
|
|||||||
import org.glavo.monetfx.beans.property.ReadOnlyColorSchemeProperty;
|
import org.glavo.monetfx.beans.property.ReadOnlyColorSchemeProperty;
|
||||||
import org.glavo.monetfx.beans.property.SimpleColorSchemeProperty;
|
import org.glavo.monetfx.beans.property.SimpleColorSchemeProperty;
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
|
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||||
import org.jackhuang.hmcl.ui.WindowsNativeUtils;
|
import org.jackhuang.hmcl.ui.WindowsNativeUtils;
|
||||||
import org.jackhuang.hmcl.util.platform.NativeUtils;
|
import org.jackhuang.hmcl.util.platform.NativeUtils;
|
||||||
import org.jackhuang.hmcl.util.platform.OSVersion;
|
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.WinReg;
|
||||||
import org.jackhuang.hmcl.util.platform.windows.WinTypes;
|
import org.jackhuang.hmcl.util.platform.windows.WinTypes;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
|
||||||
|
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||||
|
|
||||||
/// @author Glavo
|
/// @author Glavo
|
||||||
public final class Themes {
|
public final class Themes {
|
||||||
@@ -113,6 +117,7 @@ public final class Themes {
|
|||||||
if (defaultBrightness != null)
|
if (defaultBrightness != null)
|
||||||
return defaultBrightness;
|
return defaultBrightness;
|
||||||
|
|
||||||
|
LOG.info("Detecting system theme brightness");
|
||||||
Brightness brightness = Brightness.DEFAULT;
|
Brightness brightness = Brightness.DEFAULT;
|
||||||
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
|
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
|
||||||
WinReg reg = WinReg.INSTANCE;
|
WinReg reg = WinReg.INSTANCE;
|
||||||
@@ -130,7 +135,38 @@ public final class Themes {
|
|||||||
// If the key does not exist, it means Light mode is used
|
// If the key does not exist, it means Light mode is used
|
||||||
brightness = Brightness.LIGHT;
|
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;
|
return defaultBrightness = brightness;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import java.io.InputStream;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@@ -75,12 +76,21 @@ public final class SystemUtils {
|
|||||||
return managedProcess.getProcess().waitFor();
|
return managedProcess.getProcess().waitFor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Duration DEFAULT_MAX_WAIT_TIME = Duration.ofSeconds(15);
|
||||||
|
|
||||||
public static String run(String... command) throws Exception {
|
public static String run(String... command) throws Exception {
|
||||||
return run(Arrays.asList(command),
|
return run(List.of(command), DEFAULT_MAX_WAIT_TIME);
|
||||||
inputStream -> IOUtils.readFullyAsString(inputStream, OperatingSystem.NATIVE_CHARSET));
|
}
|
||||||
|
|
||||||
|
public static String run(List<String> command, Duration maxWaitTime) throws Exception {
|
||||||
|
return run(command, inputStream -> IOUtils.readFullyAsString(inputStream, OperatingSystem.NATIVE_CHARSET), maxWaitTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> T run(List<String> command, ExceptionalFunction<InputStream, T, ?> convert) throws Exception {
|
public static <T> T run(List<String> command, ExceptionalFunction<InputStream, T, ?> convert) throws Exception {
|
||||||
|
return run(command, convert, DEFAULT_MAX_WAIT_TIME);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T run(List<String> command, ExceptionalFunction<InputStream, T, ?> convert, Duration maxWaitTime) throws Exception {
|
||||||
Process process = new ProcessBuilder(command)
|
Process process = new ProcessBuilder(command)
|
||||||
.redirectError(ProcessBuilder.Redirect.DISCARD)
|
.redirectError(ProcessBuilder.Redirect.DISCARD)
|
||||||
.start();
|
.start();
|
||||||
@@ -90,7 +100,7 @@ public final class SystemUtils {
|
|||||||
Lang.wrap(() -> convert.apply(inputStream)),
|
Lang.wrap(() -> convert.apply(inputStream)),
|
||||||
Schedulers.io());
|
Schedulers.io());
|
||||||
|
|
||||||
if (!process.waitFor(15, TimeUnit.SECONDS))
|
if (!process.waitFor(maxWaitTime.toMillis(), TimeUnit.MILLISECONDS))
|
||||||
throw new TimeoutException();
|
throw new TimeoutException();
|
||||||
|
|
||||||
if (process.exitValue() != 0)
|
if (process.exitValue() != 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user