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(); } }