From 02473080a5b73da4b7383532f829de06becef06c Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Thu, 3 Sep 2020 19:26:52 +0200 Subject: [PATCH] Window decorations: fixed wrong window placement when moving window to another screen with different scaling factor (issue #166) --- CHANGELOG.md | 5 ++ .../com/formdev/flatlaf/ui/FlatTitlePane.java | 48 +++++++++---------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b807b171..b011d45b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ FlatLaf Change Log - Demo: Improved "SplitPane & Tabs" and "Data Components" tabs. - Menu items "File > Open" and "File > Save As" now show file choosers. +#### Fixed bugs + +- Custom window decorations: Fixed wrong window placement when moving window to + another screen with different scaling factor. (issue #166) + ## 0.41 diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTitlePane.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTitlePane.java index f86cd12b..9e2e26b8 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTitlePane.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTitlePane.java @@ -754,8 +754,7 @@ debug*/ //---- interface MouseListener ---- - private int lastXOnScreen; - private int lastYOnScreen; + private Point dragOffset; @Override public void mouseClicked( MouseEvent e ) { @@ -779,8 +778,10 @@ debug*/ @Override public void mousePressed( MouseEvent e ) { - lastXOnScreen = e.getXOnScreen(); - lastYOnScreen = e.getYOnScreen(); + if( window == null ) + return; // should newer occur + + dragOffset = SwingUtilities.convertPoint( FlatTitlePane.this, e.getPoint(), window ); } @Override public void mouseReleased( MouseEvent e ) {} @@ -791,46 +792,45 @@ debug*/ @Override public void mouseDragged( MouseEvent e ) { + if( window == null ) + return; // should newer occur + if( hasJBRCustomDecoration() ) return; // do nothing if running in JBR - int xOnScreen = e.getXOnScreen(); - int yOnScreen = e.getYOnScreen(); - if( lastXOnScreen == xOnScreen && lastYOnScreen == yOnScreen ) - return; - // restore window if it is maximized if( window instanceof Frame ) { Frame frame = (Frame) window; int state = frame.getExtendedState(); if( (state & Frame.MAXIMIZED_BOTH) != 0 ) { - int maximizedX = window.getX(); - int maximizedY = window.getY(); + int maximizedWidth = window.getWidth(); // restore window size, which also moves window to pre-maximized location frame.setExtendedState( state & ~Frame.MAXIMIZED_BOTH ); + // fix drag offset to ensure that window remains under mouse position + // for the case that dragging starts in the right area of the maximized window int restoredWidth = window.getWidth(); - int newX = maximizedX; - JComponent rightComp = getComponentOrientation().isLeftToRight() ? buttonPanel : leftPanel; - if( xOnScreen >= maximizedX + restoredWidth - rightComp.getWidth() - 10 ) - newX = xOnScreen + rightComp.getWidth() + 10 - restoredWidth; - - // move window near mouse - window.setLocation( newX, maximizedY ); - return; + int center = restoredWidth / 2; + if( dragOffset.x > center ) { + // this is same/similar to what Windows 10 does + if( dragOffset.x > maximizedWidth - center ) + dragOffset.x = restoredWidth - (maximizedWidth - dragOffset.x); + else + dragOffset.x = center; + } } } // compute new window location - int newX = window.getX() + (xOnScreen - lastXOnScreen); - int newY = window.getY() + (yOnScreen - lastYOnScreen); + int newX = e.getXOnScreen() - dragOffset.x; + int newY = e.getYOnScreen() - dragOffset.y; + + if( newX == window.getX() && newY == window.getY() ) + return; // move window window.setLocation( newX, newY ); - - lastXOnScreen = xOnScreen; - lastYOnScreen = yOnScreen; } @Override public void mouseMoved( MouseEvent e ) {}