diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java index b283d27fd..570ef874b 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java @@ -216,7 +216,9 @@ public final class Controllers { if (targetProperty != null && Controllers.stage != null - && !Controllers.stage.isIconified()) { + && !Controllers.stage.isIconified() + && !Controllers.stage.isFullScreen() + && !Controllers.stage.isMaximized()) { targetProperty.set(sourceProperty.get()); } }; diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorController.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorController.java index 18c534793..e8a2a03ec 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorController.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorController.java @@ -34,10 +34,7 @@ import javafx.scene.image.Image; import javafx.scene.image.PixelReader; import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; -import javafx.scene.input.DragEvent; -import javafx.scene.input.KeyEvent; -import javafx.scene.input.MouseButton; -import javafx.scene.input.MouseEvent; +import javafx.scene.input.*; import javafx.scene.layout.*; import javafx.scene.paint.Color; import javafx.scene.paint.Paint; @@ -167,6 +164,14 @@ public class DecoratorController { // press ESC to go back onEscPressed(navigator, this::back); + // press F11 to toggle full screen + navigator.addEventHandler(KeyEvent.KEY_PRESSED, e -> { + if (e.getCode() == KeyCode.F11) { + stage.setFullScreen(!stage.isFullScreen()); + e.consume(); + } + }); + try { // For JavaFX 12+ MouseButton button = MouseButton.valueOf("BACK"); 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 4d0a3f9b2..c182dbcb4 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 @@ -18,8 +18,11 @@ package org.jackhuang.hmcl.ui.decorator; import com.jfoenix.controls.JFXButton; +import javafx.beans.InvalidationListener; +import javafx.beans.WeakInvalidationListener; import javafx.beans.binding.Bindings; import javafx.collections.ListChangeListener; +import javafx.event.EventHandler; import javafx.geometry.Bounds; import javafx.geometry.Insets; import javafx.geometry.Pos; @@ -29,6 +32,7 @@ import javafx.scene.control.Label; import javafx.scene.control.SkinBase; import javafx.scene.effect.BlurType; import javafx.scene.effect.DropShadow; +import javafx.scene.input.MouseButton; import javafx.scene.input.MouseEvent; import javafx.scene.layout.*; import javafx.scene.paint.Color; @@ -50,6 +54,8 @@ public class DecoratorSkin extends SkinBase { private final Stage primaryStage; private final TransitionPane navBarPane; + private final InvalidationListener onWindowsStatusChange; + private double mouseInitX, mouseInitY, stageInitX, stageInitY, stageInitWidth, stageInitHeight; /** @@ -80,9 +86,25 @@ public class DecoratorSkin extends SkinBase { skinnable.getSnackbar().registerSnackbarContainer(parent); - root.addEventFilter(MouseEvent.MOUSE_RELEASED, this::onMouseReleased); - root.addEventFilter(MouseEvent.MOUSE_DRAGGED, this::onMouseDragged); - root.addEventFilter(MouseEvent.MOUSE_MOVED, this::onMouseMoved); + EventHandler onMouseReleased = this::onMouseReleased; + EventHandler onMouseDragged = this::onMouseDragged; + EventHandler onMouseMoved = this::onMouseMoved; + onWindowsStatusChange = observable -> { + if (primaryStage.isIconified() || primaryStage.isFullScreen() || primaryStage.isMaximized()) { + root.removeEventFilter(MouseEvent.MOUSE_RELEASED, onMouseReleased); + root.removeEventFilter(MouseEvent.MOUSE_DRAGGED, onMouseDragged); + root.removeEventFilter(MouseEvent.MOUSE_MOVED, onMouseMoved); + } else { + root.addEventFilter(MouseEvent.MOUSE_RELEASED, onMouseReleased); + root.addEventFilter(MouseEvent.MOUSE_DRAGGED, onMouseDragged); + root.addEventFilter(MouseEvent.MOUSE_MOVED, onMouseMoved); + } + }; + WeakInvalidationListener weakOnWindowsStatusChange = new WeakInvalidationListener(onWindowsStatusChange); + primaryStage.iconifiedProperty().addListener(weakOnWindowsStatusChange); + primaryStage.maximizedProperty().addListener(weakOnWindowsStatusChange); + primaryStage.fullScreenProperty().addListener(weakOnWindowsStatusChange); + onWindowsStatusChange.invalidated(null); shadowContainer.getChildren().setAll(parent); root.getChildren().setAll(shadowContainer); @@ -155,6 +177,12 @@ public class DecoratorSkin extends SkinBase { BorderPane titleBar = new BorderPane(); titleContainer.getChildren().add(titleBar); + titleBar.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> { + if (event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2) { + primaryStage.setMaximized(!primaryStage.isMaximized()); + event.consume(); + } + }); Rectangle buttonsContainerPlaceHolder = new Rectangle(); {