Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 57 additions & 8 deletions HMCL/src/main/java/org/jackhuang/hmcl/EntryPoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.jackhuang.hmcl.util.io.FileUtils;
import org.jackhuang.hmcl.util.io.JarUtils;
import org.jackhuang.hmcl.util.platform.OperatingSystem;
import org.jackhuang.hmcl.util.platform.SystemUtils;

import javax.swing.JOptionPane;
import java.io.IOException;
Expand All @@ -32,6 +33,9 @@
import java.lang.invoke.MethodType;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CancellationException;

import static org.jackhuang.hmcl.util.logging.Logger.LOG;
Expand Down Expand Up @@ -94,8 +98,49 @@ private static void setupJavaFXVMOptions() {
}
}

double scale = Double.NEGATIVE_INFINITY;

String uiScale = System.getProperty("hmcl.uiScale", System.getenv("HMCL_UI_SCALE"));
if (uiScale != null) {
if (uiScale == null) {
if (OperatingSystem.CURRENT_OS.isLinuxOrBSD()) {
String sessionType = System.getenv("XDG_SESSION_TYPE");
String currentDesktop = Objects.requireNonNullElse(System.getenv("XDG_CURRENT_DESKTOP"), "");

// On KDE Wayland, JavaFX cannot read the UI scale correctly.
if ("wayland".equals(sessionType) && currentDesktop.startsWith("kde")) {
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.kde.kdeglobals.KScreen",
"string:ScaleFactor"
), Duration.ofSeconds(2)).trim().split(" ");

if (result.length > 0) {
String value = result[result.length - 1];

try {
double scaleValue = Double.parseDouble(value.trim());
if (scaleValue > 1.0 && scaleValue <= 4) {
scale = scaleValue;
}
} catch (NumberFormatException ignored) {
}
}
} catch (Exception e) {
LOG.warning("Failed to get UI scale from D-Bus", e);
}
}
}
}
} else {
uiScale = uiScale.trim();

LOG.info("HMCL_UI_SCALE: " + uiScale);
Expand Down Expand Up @@ -123,20 +168,24 @@ private static void setupJavaFXVMOptions() {
}

if (scaleValue >= lowerBound && scaleValue <= upperBound) {
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
System.getProperties().putIfAbsent("glass.win.uiScale", uiScale);
} else if (OperatingSystem.CURRENT_OS == OperatingSystem.MACOS) {
LOG.warning("macOS does not support setting UI scale, so it will be ignored");
} else {
System.getProperties().putIfAbsent("glass.gtk.uiScale", uiScale);
}
scale = scaleValue;
} else {
LOG.warning("UI scale out of range: " + uiScale);
}
} catch (Throwable e) {
LOG.warning("Invalid UI scale: " + uiScale);
}
}

if (scale > 0) {
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
System.getProperties().putIfAbsent("glass.win.uiScale", uiScale);
} else if (OperatingSystem.CURRENT_OS == OperatingSystem.MACOS) {
LOG.warning("macOS does not support setting UI scale, so it will be ignored");
} else {
System.getProperties().putIfAbsent("glass.gtk.uiScale", uiScale);
}
}
Comment on lines +180 to +188
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

在通过 D-Bus 获取缩放比例的分支中(第 104-142 行),uiScale 变量保持为 null。由于 System.getProperties() 返回的是 Hashtable,调用 putIfAbsent 时传入 null 值会抛出 NullPointerException。此外,即使不抛出异常,也应该使用计算出的 scale 值,因为 JavaFX 的 uiScale 属性通常期望一个数值字符串,而不一定支持原始输入中的 %dpi 后缀。

        if (scale > 0) {
            String scaleString = String.valueOf(scale);
            if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
                System.getProperties().putIfAbsent("glass.win.uiScale", scaleString);
            } else if (OperatingSystem.CURRENT_OS == OperatingSystem.MACOS) {
                LOG.warning("macOS does not support setting UI scale, so it will be ignored");
            } else {
                System.getProperties().putIfAbsent("glass.gtk.uiScale", scaleString);
            }
        }

}

private static void createHMCLDirectories() {
Expand Down