|
@@ -19,9 +19,11 @@ import javafx.beans.property.ObjectProperty;
|
|
|
import javafx.beans.property.ReadOnlyBooleanProperty;
|
|
|
import javafx.beans.property.ReadOnlyObjectProperty;
|
|
|
import javafx.fxml.FXML;
|
|
|
+import javafx.geometry.Rectangle2D;
|
|
|
import javafx.scene.layout.StackPane;
|
|
|
import javafx.stage.Screen;
|
|
|
import javafx.stage.Stage;
|
|
|
+import javafx.stage.WindowEvent;
|
|
|
|
|
|
@MainWindowScoped
|
|
|
public class MainWindowController implements FxController {
|
|
@@ -68,18 +70,15 @@ public class MainWindowController implements FxController {
|
|
|
int y = settings.windowYPosition.get();
|
|
|
int width = settings.windowWidth.get();
|
|
|
int height = settings.windowHeight.get();
|
|
|
- if (windowPositionSaved(x, y, width, height) ) {
|
|
|
- if(isWithinDisplayBounds(x, y, width, height)) { //use stored window position
|
|
|
- window.setX(x);
|
|
|
- window.setY(y);
|
|
|
- window.setWidth(Math.clamp(width, window.getMinWidth(), window.getMaxWidth()));
|
|
|
- window.setHeight(Math.clamp(height, window.getMinHeight(), window.getMaxHeight()));
|
|
|
- } else if(isWithinDisplayBounds((int) window.getX(), (int) window.getY(), width, height)) { //just reset position of upper left corner, keep window size
|
|
|
- window.setWidth(Math.clamp(width, window.getMinWidth(), window.getMaxWidth()));
|
|
|
- window.setHeight(Math.clamp(height, window.getMinHeight(), window.getMaxHeight()));
|
|
|
- } //else reset window completely
|
|
|
+ if (windowPositionSaved(x, y, width, height)) {
|
|
|
+ window.setX(x);
|
|
|
+ window.setY(y);
|
|
|
+ window.setWidth(Math.clamp(width, window.getMinWidth(), window.getMaxWidth()));
|
|
|
+ window.setHeight(Math.clamp(height, window.getMinHeight(), window.getMaxHeight()));
|
|
|
}
|
|
|
|
|
|
+ window.setOnShowing(this::checkDisplayBounds);
|
|
|
+
|
|
|
settings.windowXPosition.bind(window.xProperty());
|
|
|
settings.windowYPosition.bind(window.yProperty());
|
|
|
settings.windowWidth.bind(window.widthProperty());
|
|
@@ -90,6 +89,39 @@ public class MainWindowController implements FxController {
|
|
|
return x != 0 || y != 0 || width != 0 || height != 0;
|
|
|
}
|
|
|
|
|
|
+ private void checkDisplayBounds(WindowEvent windowEvent) {
|
|
|
+ int x = settings.windowXPosition.get();
|
|
|
+ int y = settings.windowYPosition.get();
|
|
|
+ int width = settings.windowWidth.get();
|
|
|
+ int height = settings.windowHeight.get();
|
|
|
+
|
|
|
+ // Minimizing a window in Windows and closing it could result in an out of bounds position at (x, y) = (-32000, -32000)
|
|
|
+ // See https://devblogs.microsoft.com/oldnewthing/20041028-00/?p=37453
|
|
|
+ // If the position is (-32000, -32000), restore to the last saved position
|
|
|
+ if (window.getX() == -32000 && window.getY() == -32000) {
|
|
|
+ window.setX(x);
|
|
|
+ window.setY(y);
|
|
|
+ window.setWidth(width);
|
|
|
+ window.setHeight(height);
|
|
|
+ }
|
|
|
+
|
|
|
+ Rectangle2D primaryScreenBounds = Screen.getPrimary().getBounds();
|
|
|
+ if (!isWithinDisplayBounds(x, y, width, height)) { //use stored window position
|
|
|
+ LOG.debug("Resetting window position due to insufficient screen overlap");
|
|
|
+ var centeredX = (primaryScreenBounds.getWidth() - window.getMinWidth()) / 2;
|
|
|
+ var centeredY = (primaryScreenBounds.getHeight() - window.getMinHeight()) / 2;
|
|
|
+ //check if we can keep width and height
|
|
|
+ if (isWithinDisplayBounds((int) centeredX, (int) centeredY, width, height)) {
|
|
|
+ //if so, keep window size
|
|
|
+ window.setWidth(Math.clamp(width, window.getMinWidth(), window.getMaxWidth()));
|
|
|
+ window.setHeight(Math.clamp(height, window.getMinHeight(), window.getMaxHeight()));
|
|
|
+ }
|
|
|
+ //reset position of upper left corner
|
|
|
+ window.setX(centeredX);
|
|
|
+ window.setY(centeredY);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private boolean isWithinDisplayBounds(int x, int y, int width, int height) {
|
|
|
// define a rect which is inset on all sides from the window's rect:
|
|
|
final int shrinkedX = x + 20; // 20px left
|