From 1196e27e996bedfa52cf74123217addce23b73c2 Mon Sep 17 00:00:00 2001 From: mineDiamond Date: Thu, 9 Apr 2026 11:00:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E6=8B=96=E5=8A=A8=E5=88=B0=E4=B8=8D=E6=94=AF=E6=8C=81=E7=9A=84?= =?UTF-8?q?=E5=9C=B0=E6=96=B9=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hmcl/ui/decorator/DecoratorSkin.java | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorSkin.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorSkin.java index 69f06950cf..d3d403dab1 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorSkin.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorSkin.java @@ -25,11 +25,14 @@ import javafx.beans.InvalidationListener; import javafx.beans.WeakInvalidationListener; import javafx.beans.binding.Bindings; +import javafx.beans.value.ObservableBooleanValue; import javafx.collections.ListChangeListener; +import javafx.collections.ObservableList; import javafx.event.EventHandler; import javafx.geometry.Bounds; import javafx.geometry.Insets; import javafx.geometry.Pos; +import javafx.geometry.Rectangle2D; import javafx.scene.Cursor; import javafx.scene.Node; import javafx.scene.control.Label; @@ -41,6 +44,7 @@ import javafx.scene.layout.*; import javafx.scene.paint.Color; import javafx.scene.shape.Rectangle; +import javafx.stage.Screen; import javafx.stage.Stage; import javafx.util.Duration; @@ -54,6 +58,8 @@ import org.jackhuang.hmcl.ui.wizard.Navigation; import org.jackhuang.hmcl.util.platform.OperatingSystem; +import java.util.Objects; + public class DecoratorSkin extends SkinBase { private final StackPane root, parent; private final StackPane titleContainer; @@ -65,6 +71,8 @@ public class DecoratorSkin extends SkinBase { private final EventHandler onTitleBarDoubleClick; private double mouseInitX, mouseInitY, stageInitX, stageInitY, stageInitWidth, stageInitHeight; + private final ObservableBooleanValue isDisplayScalingUniform; + private Rectangle2D currentMouseVisualBounds; /** * Constructor for all SkinBase instances. @@ -94,6 +102,12 @@ public DecoratorSkin(Decorator control) { skinnable.getSnackbar().registerSnackbarContainer(parent); + ObservableList screens = Screen.getScreens(); + isDisplayScalingUniform = Bindings.createBooleanBinding(() -> { + Screen firstScreen = screens.get(0); + return screens.stream().allMatch(screen -> Objects.equals(firstScreen.getOutputScaleX(), screen.getOutputScaleX()) && Objects.equals(firstScreen.getOutputScaleY(), screen.getOutputScaleY())); + }, screens); + EventHandler onMouseReleased = this::onMouseReleased; EventHandler onMouseDragged = this::onMouseDragged; EventHandler onMouseMoved = this::onMouseMoved; @@ -470,8 +484,17 @@ private void onMouseDragged(MouseEvent mouseEvent) { Cursor cursor = root.getCursor(); if (getSkinnable().isAllowMove()) { if (cursor == Cursor.DEFAULT) { - primaryStage.setX(stageInitX + dx); - primaryStage.setY(stageInitY + dy); + if (!isDisplayScalingUniform.get()) { + primaryStage.setX(stageInitX + dx); + primaryStage.setY(stageInitY + dy); + } else { + if (currentMouseVisualBounds == null || !currentMouseVisualBounds.contains(mouseEvent.getScreenX(), mouseEvent.getScreenY())) { + currentMouseVisualBounds = Screen.getScreensForRectangle(new Rectangle2D(mouseEvent.getScreenX(), mouseEvent.getScreenY(), 1, 1)).get(0).getVisualBounds(); + } + primaryStage.setX(stageInitX + dx); + primaryStage.setY(Math.max(Math.min(stageInitY + dy, currentMouseVisualBounds.getMaxY() - titleContainer.getHeight()), currentMouseVisualBounds.getMinY() - titleContainer.getHeight())); + + } mouseEvent.consume(); } }