From 56d20a5d0845adb1f18d2634312c9102aea71d01 Mon Sep 17 00:00:00 2001 From: Haowei Wen Date: Sat, 4 Jan 2025 00:34:48 +0800 Subject: [PATCH] Fix problems with window resizing in Linux --- .../hmcl/ui/decorator/DecoratorSkin.java | 251 ++++++++---------- 1 file changed, 114 insertions(+), 137 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 b65c0b3c0..d179cedb4 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 @@ -48,8 +48,7 @@ public class DecoratorSkin extends SkinBase { private final Stage primaryStage; private final TransitionPane navBarPane; - private double xOffset, yOffset, newX, newY, initX, initY; - private boolean titleBarTransparent = true; + private double mouseInitX, mouseInitY, stageInitX, stageInitY, stageInitWidth, stageInitHeight; /** * Constructor for all SkinBase instances. @@ -299,13 +298,6 @@ public class DecoratorSkin extends SkinBase { return navBar; } - private void updateInitMouseValues(MouseEvent mouseEvent) { - initX = mouseEvent.getScreenX(); - initY = mouseEvent.getScreenY(); - xOffset = mouseEvent.getSceneX(); - yOffset = mouseEvent.getSceneY(); - } - private boolean isRightEdge(double x, double y, Bounds boundsInParent) { return x < root.getWidth() && x >= root.getWidth() - root.snappedLeftInset(); } @@ -322,154 +314,139 @@ public class DecoratorSkin extends SkinBase { return x >= 0 && x <= root.snappedLeftInset(); } - private boolean setStageWidth(double width) { - if (width >= primaryStage.getMinWidth() && width >= titleContainer.getMinWidth()) { - // Workaround for JDK-8344372 (https://github.com/openjdk/jfx/pull/1654) - // Width and height must be set simultaneously to avoid the bug - primaryStage.setWidth(width); - primaryStage.setHeight(primaryStage.getHeight()); - initX = newX; - return true; - } else { - if (width >= primaryStage.getMinWidth() && width <= titleContainer.getMinWidth()) { - primaryStage.setWidth(titleContainer.getMinWidth()); - primaryStage.setHeight(primaryStage.getHeight()); - } + private void resizeStage(double newWidth, double newHeight) { + if (newWidth < 0) + newWidth = primaryStage.getWidth(); + if (newWidth < primaryStage.getMinWidth()) + newWidth = primaryStage.getMinWidth(); + if (newWidth < titleContainer.getMinWidth()) + newWidth = titleContainer.getMinWidth(); - return false; - } + if (newHeight < 0) + newHeight = primaryStage.getHeight(); + if (newHeight < primaryStage.getMinHeight()) + newHeight = primaryStage.getMinHeight(); + if (newHeight < titleContainer.getMinHeight()) + newHeight = titleContainer.getMinHeight(); + + // Width and height must be set simultaneously to avoid JDK-8344372 (https://github.com/openjdk/jfx/pull/1654) + primaryStage.setWidth(newWidth); + primaryStage.setHeight(newHeight); } - private boolean setStageHeight(double height) { - if (height >= primaryStage.getMinHeight() && height >= titleContainer.getHeight()) { - primaryStage.setHeight(height); - primaryStage.setWidth(primaryStage.getWidth()); - initY = newY; - return true; - } else { - if (height >= primaryStage.getMinHeight() && height <= titleContainer.getHeight()) { - primaryStage.setHeight(titleContainer.getHeight()); - primaryStage.setWidth(primaryStage.getWidth()); - } - - return false; - } - } - - // ==== - - protected void onMouseMoved(MouseEvent mouseEvent) { - if (!primaryStage.isFullScreen()) { - updateInitMouseValues(mouseEvent); - if (primaryStage.isResizable()) { - double x = mouseEvent.getX(), y = mouseEvent.getY(); - Bounds boundsInParent = root.getBoundsInParent(); - double diagonalSize = root.snappedLeftInset() + 10; - if (this.isRightEdge(x, y, boundsInParent)) { - if (y < diagonalSize) { - root.setCursor(Cursor.NE_RESIZE); - } else if (y > root.getHeight() - diagonalSize) { - root.setCursor(Cursor.SE_RESIZE); - } else { - root.setCursor(Cursor.E_RESIZE); - } - } else if (this.isLeftEdge(x, y, boundsInParent)) { - if (y < diagonalSize) { - root.setCursor(Cursor.NW_RESIZE); - } else if (y > root.getHeight() - diagonalSize) { - root.setCursor(Cursor.SW_RESIZE); - } else { - root.setCursor(Cursor.W_RESIZE); - } - } else if (this.isTopEdge(x, y, boundsInParent)) { - if (x < diagonalSize) { - root.setCursor(Cursor.NW_RESIZE); - } else if (x > root.getWidth() - diagonalSize) { - root.setCursor(Cursor.NE_RESIZE); - } else { - root.setCursor(Cursor.N_RESIZE); - } - } else if (this.isBottomEdge(x, y, boundsInParent)) { - if (x < diagonalSize) { - root.setCursor(Cursor.SW_RESIZE); - } else if (x > root.getWidth() - diagonalSize) { - root.setCursor(Cursor.SE_RESIZE); - } else { - root.setCursor(Cursor.S_RESIZE); - } + private void onMouseMoved(MouseEvent mouseEvent) { + if (!primaryStage.isFullScreen() && primaryStage.isResizable()) { + double x = mouseEvent.getX(), y = mouseEvent.getY(); + Bounds boundsInParent = root.getBoundsInParent(); + double diagonalSize = root.snappedLeftInset() + 10; + if (this.isRightEdge(x, y, boundsInParent)) { + if (y < diagonalSize) { + root.setCursor(Cursor.NE_RESIZE); + } else if (y > root.getHeight() - diagonalSize) { + root.setCursor(Cursor.SE_RESIZE); } else { - root.setCursor(Cursor.DEFAULT); + root.setCursor(Cursor.E_RESIZE); } + } else if (this.isLeftEdge(x, y, boundsInParent)) { + if (y < diagonalSize) { + root.setCursor(Cursor.NW_RESIZE); + } else if (y > root.getHeight() - diagonalSize) { + root.setCursor(Cursor.SW_RESIZE); + } else { + root.setCursor(Cursor.W_RESIZE); + } + } else if (this.isTopEdge(x, y, boundsInParent)) { + if (x < diagonalSize) { + root.setCursor(Cursor.NW_RESIZE); + } else if (x > root.getWidth() - diagonalSize) { + root.setCursor(Cursor.NE_RESIZE); + } else { + root.setCursor(Cursor.N_RESIZE); + } + } else if (this.isBottomEdge(x, y, boundsInParent)) { + if (x < diagonalSize) { + root.setCursor(Cursor.SW_RESIZE); + } else if (x > root.getWidth() - diagonalSize) { + root.setCursor(Cursor.SE_RESIZE); + } else { + root.setCursor(Cursor.S_RESIZE); + } + } else { + root.setCursor(Cursor.DEFAULT); } } else { root.setCursor(Cursor.DEFAULT); } } - protected void onMouseReleased(MouseEvent mouseEvent) { + private void onMouseReleased(MouseEvent mouseEvent) { getSkinnable().setDragging(false); } - protected void onMouseDragged(MouseEvent mouseEvent) { - getSkinnable().setDragging(true); - if (mouseEvent.isPrimaryButtonDown() && (this.xOffset != -1.0 || this.yOffset != -1.0)) { - if (!this.primaryStage.isFullScreen() && !mouseEvent.isStillSincePress()) { - this.newX = mouseEvent.getScreenX(); - this.newY = mouseEvent.getScreenY(); - double deltaX = this.newX - this.initX; - double deltaY = this.newY - this.initY; - Cursor cursor = root.getCursor(); - if (Cursor.E_RESIZE == cursor) { - this.setStageWidth(this.primaryStage.getWidth() + deltaX); - mouseEvent.consume(); - } else if (Cursor.NE_RESIZE == cursor) { - if (this.setStageHeight(this.primaryStage.getHeight() - deltaY)) { - this.primaryStage.setY(this.primaryStage.getY() + deltaY); - } + private void onMouseDragged(MouseEvent mouseEvent) { + if (!getSkinnable().isDragging()) { + getSkinnable().setDragging(true); + mouseInitX = mouseEvent.getScreenX(); + mouseInitY = mouseEvent.getScreenY(); + stageInitX = primaryStage.getX(); + stageInitY = primaryStage.getY(); + stageInitWidth = primaryStage.getWidth(); + stageInitHeight = primaryStage.getHeight(); + } - this.setStageWidth(this.primaryStage.getWidth() + deltaX); - mouseEvent.consume(); - } else if (Cursor.SE_RESIZE == cursor) { - this.setStageWidth(this.primaryStage.getWidth() + deltaX); - this.setStageHeight(this.primaryStage.getHeight() + deltaY); - mouseEvent.consume(); - } else if (Cursor.S_RESIZE == cursor) { - this.setStageHeight(this.primaryStage.getHeight() + deltaY); - mouseEvent.consume(); - } else if (Cursor.W_RESIZE == cursor) { - if (this.setStageWidth(this.primaryStage.getWidth() - deltaX)) { - this.primaryStage.setX(this.primaryStage.getX() + deltaX); - } + if (primaryStage.isFullScreen() || !mouseEvent.isPrimaryButtonDown() || mouseEvent.isStillSincePress()) + return; - mouseEvent.consume(); - } else if (Cursor.SW_RESIZE == cursor) { - if (this.setStageWidth(this.primaryStage.getWidth() - deltaX)) { - this.primaryStage.setX(this.primaryStage.getX() + deltaX); - } + double dx = mouseEvent.getScreenX() - mouseInitX; + double dy = mouseEvent.getScreenY() - mouseInitY; - this.setStageHeight(this.primaryStage.getHeight() + deltaY); - mouseEvent.consume(); - } else if (Cursor.NW_RESIZE == cursor) { - if (this.setStageWidth(this.primaryStage.getWidth() - deltaX)) { - this.primaryStage.setX(this.primaryStage.getX() + deltaX); - } + Cursor cursor = root.getCursor(); + if (getSkinnable().isAllowMove()) { + if (cursor == Cursor.DEFAULT) { + primaryStage.setX(stageInitX + dx); + primaryStage.setY(stageInitY + dy); + mouseEvent.consume(); + } + } - if (this.setStageHeight(this.primaryStage.getHeight() - deltaY)) { - this.primaryStage.setY(this.primaryStage.getY() + deltaY); - } + if (getSkinnable().isResizable()) { + if (cursor == Cursor.E_RESIZE) { + resizeStage(stageInitWidth + dx, -1); + mouseEvent.consume(); - mouseEvent.consume(); - } else if (Cursor.N_RESIZE == cursor) { - if (this.setStageHeight(this.primaryStage.getHeight() - deltaY)) { - this.primaryStage.setY(this.primaryStage.getY() + deltaY); - } + } else if (cursor == Cursor.S_RESIZE) { + resizeStage(-1, stageInitHeight + dy); + mouseEvent.consume(); - mouseEvent.consume(); - } else if (getSkinnable().isAllowMove()) { - this.primaryStage.setX(mouseEvent.getScreenX() - this.xOffset); - this.primaryStage.setY(mouseEvent.getScreenY() - this.yOffset); - mouseEvent.consume(); - } + } else if (cursor == Cursor.W_RESIZE) { + resizeStage(stageInitWidth - dx, -1); + primaryStage.setX(stageInitX + stageInitWidth - primaryStage.getWidth()); + mouseEvent.consume(); + + } else if (cursor == Cursor.N_RESIZE) { + resizeStage(-1, stageInitHeight - dy); + primaryStage.setY(stageInitY + stageInitHeight - primaryStage.getHeight()); + mouseEvent.consume(); + + } else if (cursor == Cursor.SE_RESIZE) { + resizeStage(stageInitWidth + dx, stageInitHeight + dy); + mouseEvent.consume(); + + } else if (cursor == Cursor.SW_RESIZE) { + resizeStage(stageInitWidth - dx, stageInitHeight + dy); + primaryStage.setX(stageInitX + stageInitWidth - primaryStage.getWidth()); + mouseEvent.consume(); + + } else if (cursor == Cursor.NW_RESIZE) { + resizeStage(stageInitWidth - dx, stageInitHeight - dy); + primaryStage.setX(stageInitX + stageInitWidth - primaryStage.getWidth()); + primaryStage.setY(stageInitY + stageInitHeight - primaryStage.getHeight()); + mouseEvent.consume(); + + } else if (cursor == Cursor.NE_RESIZE) { + resizeStage(stageInitWidth + dx, stageInitHeight - dy); + primaryStage.setY(stageInitY + stageInitHeight - primaryStage.getHeight()); + mouseEvent.consume(); } } }