Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import javax.swing.JRootPane;
import javax.swing.SwingUtilities;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Point;
import java.awt.event.InputEvent;
Expand Down Expand Up @@ -67,6 +68,23 @@ static Point draggedWindowLocation(Point windowOrigin, Point pointerOrigin, Poin
);
}

/**
* Native Windows behavior when a maximized window is dragged: restore it
* and place it so the pointer stays at the same relative position inside
* the window, instead of leaving it pinned against the maximized bounds.
*/
static Point restoredDragOrigin(Dimension maximizedSize, Dimension restoredSize,
Point windowOrigin, Point pointerScreen) {
double ratioX = maximizedSize.width <= 0 ? 0.5
: (double) (pointerScreen.x - windowOrigin.x) / maximizedSize.width;
double ratioY = maximizedSize.height <= 0 ? 0.5
: (double) (pointerScreen.y - windowOrigin.y) / maximizedSize.height;
return new Point(
pointerScreen.x - (int) Math.round(ratioX * restoredSize.width),
pointerScreen.y - (int) Math.round(ratioY * restoredSize.height)
);
}

private static final class BrowserWindowDragHandler extends MouseAdapter {

private final Frame frame;
Expand Down Expand Up @@ -96,7 +114,14 @@ public void mouseDragged(MouseEvent event) {
|| (event.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) == 0) {
return;
}
frame.setLocation(draggedWindowLocation(windowOrigin, pointerOrigin, event.getLocationOnScreen()));
Point pointer = event.getLocationOnScreen();
if ((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH) {
Dimension maximizedSize = frame.getSize();
frame.setExtendedState(frame.getExtendedState() & ~Frame.MAXIMIZED_BOTH);
windowOrigin = restoredDragOrigin(maximizedSize, frame.getSize(), windowOrigin, pointer);
pointerOrigin = pointer;
}
frame.setLocation(draggedWindowLocation(windowOrigin, pointerOrigin, pointer));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import java.awt.Dimension;
import java.awt.Point;
import java.util.function.Function;

Expand Down Expand Up @@ -77,4 +78,33 @@ void shouldMoveWindowByThePointerDelta() {
)
);
}

@Test
void shouldAnchorRestoredWindowUnderThePointer() {
// Maximized 1000x800 at (0,0); the drag started with the pointer a
// quarter across and 5% down. After restoring to 800x600 the window
// must jump so the pointer keeps that relative position.
assertEquals(
new Point(250 - 200, 40 - 30),
WindowsDesktopWindowChrome.restoredDragOrigin(
new Dimension(1000, 800),
new Dimension(800, 600),
new Point(0, 0),
new Point(250, 40)
)
);
}

@Test
void shouldFallBackToCenterAnchorsWhenMaximizedSizeIsUnknown() {
assertEquals(
new Point(600 - 400, 300 - 300),
WindowsDesktopWindowChrome.restoredDragOrigin(
new Dimension(0, 0),
new Dimension(800, 600),
new Point(0, 0),
new Point(600, 300)
)
);
}
}
Loading