Window decorations: fixed wrong window bounds when resizing window to another screen with different scaling factor (issue #166)

This commit is contained in:
Karl Tauber
2020-09-04 09:46:12 +02:00
parent 02473080a5
commit 98b9df06fe
2 changed files with 53 additions and 55 deletions

View File

@@ -12,6 +12,8 @@ FlatLaf Change Log
- Custom window decorations: Fixed wrong window placement when moving window to - Custom window decorations: Fixed wrong window placement when moving window to
another screen with different scaling factor. (issue #166) another screen with different scaling factor. (issue #166)
- Custom window decorations: Fixed wrong window bounds when resizing window to
another screen with different scaling factor. (issue #166)
## 0.41 ## 0.41

View File

@@ -212,9 +212,12 @@ public class FlatWindowResizer
private final int trailingResizeDir; private final int trailingResizeDir;
private int resizeDir = -1; private int resizeDir = -1;
private int dragStartMouseX;
private int dragStartMouseY; // offsets of mouse position to window edges
private Rectangle dragStartWindowBounds; private int dragLeftOffset;
private int dragRightOffset;
private int dragTopOffset;
private int dragBottomOffset;
protected DragBorderComponent( int leadingResizeDir, int centerResizeDir, int trailingResizeDir ) { protected DragBorderComponent( int leadingResizeDir, int centerResizeDir, int trailingResizeDir ) {
this.leadingResizeDir = leadingResizeDir; this.leadingResizeDir = leadingResizeDir;
@@ -265,23 +268,20 @@ debug*/
if( window == null ) if( window == null )
return; return;
dragStartMouseX = e.getXOnScreen(); int xOnScreen = e.getXOnScreen();
dragStartMouseY = e.getYOnScreen(); int yOnScreen = e.getYOnScreen();
dragStartWindowBounds = window.getBounds(); Rectangle windowBounds = window.getBounds();
// compute offsets of mouse position to window edges
dragLeftOffset = xOnScreen - windowBounds.x;
dragTopOffset = yOnScreen - windowBounds.y;
dragRightOffset = windowBounds.x + windowBounds.width - xOnScreen;
dragBottomOffset = windowBounds.y + windowBounds.height - yOnScreen;
} }
@Override @Override public void mouseReleased( MouseEvent e ) {}
public void mouseReleased( MouseEvent e ) { @Override public void mouseEntered( MouseEvent e ) {}
dragStartWindowBounds = null; @Override public void mouseExited( MouseEvent e ) {}
}
@Override
public void mouseEntered( MouseEvent e ) {
}
@Override
public void mouseExited( MouseEvent e ) {
}
@Override @Override
public void mouseMoved( MouseEvent e ) { public void mouseMoved( MouseEvent e ) {
@@ -299,46 +299,42 @@ debug*/
@Override @Override
public void mouseDragged( MouseEvent e ) { public void mouseDragged( MouseEvent e ) {
if( dragStartWindowBounds == null )
return;
if( !isWindowResizable() ) if( !isWindowResizable() )
return; return;
int mouseDeltaX = e.getXOnScreen() - dragStartMouseX; int xOnScreen = e.getXOnScreen();
int mouseDeltaY = e.getYOnScreen() - dragStartMouseY; int yOnScreen = e.getYOnScreen();
int deltaX = 0; // Get current window bounds and compute new bounds based them.
int deltaY = 0; // This is necessary because window manager may alter window bounds while resizing.
int deltaWidth = 0; // E.g. when having two monitors with different scale factors and resizing
int deltaHeight = 0; // a window on first screen to the second screen, then the window manager may
// decide at some point that the window should be only on second screen
// north // and adjusts its bounds.
if( resizeDir == N_RESIZE_CURSOR || resizeDir == NW_RESIZE_CURSOR || resizeDir == NE_RESIZE_CURSOR ) { Rectangle oldBounds = window.getBounds();
deltaY = mouseDeltaY; Rectangle newBounds = new Rectangle( oldBounds );
deltaHeight = -mouseDeltaY;
}
// south
if( resizeDir == S_RESIZE_CURSOR || resizeDir == SW_RESIZE_CURSOR || resizeDir == SE_RESIZE_CURSOR )
deltaHeight = mouseDeltaY;
// west
if( resizeDir == W_RESIZE_CURSOR || resizeDir == NW_RESIZE_CURSOR || resizeDir == SW_RESIZE_CURSOR ) {
deltaX = mouseDeltaX;
deltaWidth = -mouseDeltaX;
}
// east
if( resizeDir == E_RESIZE_CURSOR || resizeDir == NE_RESIZE_CURSOR || resizeDir == SE_RESIZE_CURSOR )
deltaWidth = mouseDeltaX;
// compute new window bounds // compute new window bounds
Rectangle newBounds = new Rectangle( dragStartWindowBounds );
newBounds.x += deltaX; // top
newBounds.y += deltaY; if( resizeDir == N_RESIZE_CURSOR || resizeDir == NW_RESIZE_CURSOR || resizeDir == NE_RESIZE_CURSOR ) {
newBounds.width += deltaWidth; newBounds.y = yOnScreen - dragTopOffset;
newBounds.height += deltaHeight; newBounds.height += (oldBounds.y - newBounds.y);
}
// bottom
if( resizeDir == S_RESIZE_CURSOR || resizeDir == SW_RESIZE_CURSOR || resizeDir == SE_RESIZE_CURSOR )
newBounds.height = (yOnScreen + dragBottomOffset) - newBounds.y;
// left
if( resizeDir == W_RESIZE_CURSOR || resizeDir == NW_RESIZE_CURSOR || resizeDir == SW_RESIZE_CURSOR ) {
newBounds.x = xOnScreen - dragLeftOffset;
newBounds.width += (oldBounds.x - newBounds.x);
}
// right
if( resizeDir == E_RESIZE_CURSOR || resizeDir == NE_RESIZE_CURSOR || resizeDir == SE_RESIZE_CURSOR )
newBounds.width = (xOnScreen + dragRightOffset) - newBounds.x;
// apply minimum window size // apply minimum window size
boolean honorMinimumSizeOnResize = boolean honorMinimumSizeOnResize =
@@ -348,18 +344,18 @@ debug*/
if( minimumSize == null ) if( minimumSize == null )
minimumSize = UIScale.scale( new Dimension( 150, 50 ) ); minimumSize = UIScale.scale( new Dimension( 150, 50 ) );
if( newBounds.width < minimumSize.width ) { if( newBounds.width < minimumSize.width ) {
if( deltaX != 0 ) if( newBounds.x != oldBounds.x )
newBounds.x -= (minimumSize.width - newBounds.width); newBounds.x -= (minimumSize.width - newBounds.width);
newBounds.width = minimumSize.width; newBounds.width = minimumSize.width;
} }
if( newBounds.height < minimumSize.height ) { if( newBounds.height < minimumSize.height ) {
if( deltaY != 0 ) if( newBounds.y != oldBounds.y )
newBounds.y -= (minimumSize.height - newBounds.height); newBounds.y -= (minimumSize.height - newBounds.height);
newBounds.height = minimumSize.height; newBounds.height = minimumSize.height;
} }
// set window bounds // set window bounds
if( !newBounds.equals( dragStartWindowBounds ) ) { if( !newBounds.equals( oldBounds ) ) {
window.setBounds( newBounds ); window.setBounds( newBounds );
// immediately layout drag border components // immediately layout drag border components