Skip to content
Open
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions .gitignore
Comment thread
aftree-sp marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,4 @@ language-subtag-registry
!/.gemini/config.yaml
.codex
/.gradle-*/

31 changes: 31 additions & 0 deletions HMCL/src/main/java/org/jackhuang/hmcl/EntryPoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/
package org.jackhuang.hmcl;

import org.jackhuang.hmcl.setting.ConfigHolder;
import org.jackhuang.hmcl.util.FileSaver;
import org.jackhuang.hmcl.util.SelfDependencyPatcher;
import org.jackhuang.hmcl.util.SwingUtils;
Expand All @@ -25,6 +26,8 @@
import org.jackhuang.hmcl.util.io.JarUtils;
import org.jackhuang.hmcl.util.platform.OperatingSystem;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import javax.swing.JOptionPane;
import java.io.IOException;
import java.lang.invoke.MethodHandle;
Expand Down Expand Up @@ -52,6 +55,7 @@ public static void main(String[] args) {

checkWine();

applyUiScaleFromGlobalConfig();
setupJavaFXVMOptions();

if (OperatingSystem.CURRENT_OS == OperatingSystem.MACOS) {
Expand All @@ -74,6 +78,33 @@ public static void exit(int exitCode) {
System.exit(exitCode);
}

/// Reads the UI scale from the global config file and sets it as the {@code hmcl.uiScale} system property,
/// so that {@link #setupJavaFXVMOptions()} can apply it before JavaFX initializes.
/// This is needed because the config is normally loaded after JavaFX starts.
private static void applyUiScaleFromGlobalConfig() {
if (System.getProperty("hmcl.uiScale") != null || System.getenv("HMCL_UI_SCALE") != null) {
return; // already set via command line or environment variable
}

try {
if (!Files.isRegularFile(ConfigHolder.GLOBAL_CONFIG_PATH)) {
return;
}

String content = Files.readString(ConfigHolder.GLOBAL_CONFIG_PATH);
JsonObject json = JsonParser.parseString(content).getAsJsonObject();
if (json.has("uiScale") && !json.get("uiScale").isJsonNull()) {
String uiScale = json.get("uiScale").getAsString();
if (uiScale != null && !uiScale.isEmpty()) {
System.setProperty("hmcl.uiScale", uiScale);
LOG.info("Applied UI scale from global config: " + uiScale);
}
}
} catch (Throwable e) {
LOG.warning("Failed to read UI scale from global config", e);
}
}

private static void setupJavaFXVMOptions() {
if ("true".equalsIgnoreCase(System.getenv("HMCL_FORCE_GPU"))) {
LOG.info("HMCL_FORCE_GPU: true");
Expand Down
18 changes: 18 additions & 0 deletions HMCL/src/main/java/org/jackhuang/hmcl/setting/GlobalConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,24 @@ public void setFontAntiAliasing(String value) {
this.fontAntiAliasing.set(value);
}

/// The UI scale factor for the launcher.
/// Stored as a percentage string (e.g. `"150%"`), or `null` for auto (system default).
/// This setting requires a restart to take effect, as it configures JavaFX Glass properties before toolkit initialization.
@SerializedName("uiScale")
private final StringProperty uiScale = new SimpleStringProperty();

public StringProperty uiScaleProperty() {
return uiScale;
}

public @Nullable String getUiScale() {
return uiScale.get();
}

public void setUiScale(String value) {
this.uiScale.set(value);
}

@SerializedName("userJava")
private final ObservableSet<String> userJava = FXCollections.observableSet(new LinkedHashSet<>());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.jackhuang.hmcl.ui.construct.*;
import org.jackhuang.hmcl.util.Lang;
import org.jackhuang.hmcl.util.javafx.SafeStringConverter;
import org.jackhuang.hmcl.util.platform.OperatingSystem;

import java.util.Arrays;
import java.util.Locale;
Expand Down Expand Up @@ -117,6 +118,28 @@ public PersonalizationPage() {
animationButton.setTitle(i18n("settings.launcher.turn_off_animations"));
animationButton.setSubtitle(i18n("settings.take_effect_after_restart"));
}
{
var uiScalePane = new LineSelectButton<String>();
uiScalePane.setTitle(i18n("settings.launcher.ui_scale"));
uiScalePane.setSubtitle(OperatingSystem.CURRENT_OS == OperatingSystem.MACOS
? i18n("settings.launcher.ui_scale.unsupported")
: i18n("settings.take_effect_after_restart"));
uiScalePane.setConverter(name -> "auto".equals(name)
? i18n("settings.launcher.ui_scale.auto")
: name);
uiScalePane.setItems("auto", "100%", "125%", "150%", "175%", "200%", "250%", "300%");

String currentScale = globalConfig().getUiScale();
uiScalePane.setValue(currentScale != null ? currentScale : "auto");
FXUtils.onChange(uiScalePane.valueProperty(), value ->
globalConfig().setUiScale("auto".equals(value) ? null : value));

if (OperatingSystem.CURRENT_OS == OperatingSystem.MACOS) {
uiScalePane.setDisable(true);
}

themeList.getContent().add(uiScalePane);
}
content.getChildren().addAll(ComponentList.createComponentListTitle(i18n("settings.launcher.appearance")), themeList);

{
Expand Down
3 changes: 3 additions & 0 deletions HMCL/src/main/resources/assets/lang/I18N.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1510,6 +1510,9 @@ settings.launcher.proxy.username=Username
settings.launcher.theme=Theme Color
settings.launcher.title_transparent=Transparent Titlebar
settings.launcher.turn_off_animations=Disable Animation
settings.launcher.ui_scale=UI Scale
settings.launcher.ui_scale.auto=Auto
settings.launcher.ui_scale.unsupported=Not supported on macOS
settings.launcher.version_list_source=Version List
settings.launcher.background.settings.opacity=Opacity

Expand Down
3 changes: 3 additions & 0 deletions HMCL/src/main/resources/assets/lang/I18N_zh.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1300,6 +1300,9 @@ settings.launcher.proxy.username=帳戶
settings.launcher.theme=主題色
settings.launcher.title_transparent=標題欄透明
settings.launcher.turn_off_animations=關閉動畫
settings.launcher.ui_scale=介面縮放
settings.launcher.ui_scale.auto=自動
settings.launcher.ui_scale.unsupported=macOS 不支援
settings.launcher.version_list_source=版本清單來源
settings.launcher.background.settings.opacity=不透明度

Expand Down
3 changes: 3 additions & 0 deletions HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1305,6 +1305,9 @@ settings.launcher.proxy.username=账户
settings.launcher.theme=主题色
settings.launcher.title_transparent=标题栏透明
settings.launcher.turn_off_animations=关闭动画
settings.launcher.ui_scale=界面缩放
settings.launcher.ui_scale.auto=自动
settings.launcher.ui_scale.unsupported=macOS 不支持
settings.launcher.version_list_source=版本列表源
settings.launcher.background.settings.opacity=不透明度

Expand Down