Skip to content

Commit 85da443

Browse files
committed
fix(desktop): restore maximized window dragged by the caption
Dragging the custom Windows title bar while the window is maximized kept calling setLocation against the maximized bounds, so the window stayed pinned instead of following the pointer until the user restored it by double-clicking. The drag handler now clears MAXIMIZED_BOTH on the first drag event and re-anchors the window under the pointer at the same relative position, matching native Windows behavior.
1 parent 811fca7 commit 85da443

2 files changed

Lines changed: 56 additions & 1 deletion

File tree

‎chat2db-community-server/chat2db-community-jcef/src/main/java/ai/chat2db/community/jcef/frame/WindowsCommunityWindowChrome.java‎

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import javax.swing.JRootPane;
77
import javax.swing.SwingUtilities;
88
import java.awt.Component;
9+
import java.awt.Dimension;
910
import java.awt.Frame;
1011
import java.awt.Point;
1112
import java.awt.event.InputEvent;
@@ -67,6 +68,23 @@ static Point draggedWindowLocation(Point windowOrigin, Point pointerOrigin, Poin
6768
);
6869
}
6970

71+
/**
72+
* Native Windows behavior when a maximized window is dragged: restore it
73+
* and place it so the pointer stays at the same relative position inside
74+
* the window, instead of leaving it pinned against the maximized bounds.
75+
*/
76+
static Point restoredDragOrigin(Dimension maximizedSize, Dimension restoredSize,
77+
Point windowOrigin, Point pointerScreen) {
78+
double ratioX = maximizedSize.width <= 0 ? 0.5
79+
: (double) (pointerScreen.x - windowOrigin.x) / maximizedSize.width;
80+
double ratioY = maximizedSize.height <= 0 ? 0.5
81+
: (double) (pointerScreen.y - windowOrigin.y) / maximizedSize.height;
82+
return new Point(
83+
pointerScreen.x - (int) Math.round(ratioX * restoredSize.width),
84+
pointerScreen.y - (int) Math.round(ratioY * restoredSize.height)
85+
);
86+
}
87+
7088
private static final class BrowserWindowDragHandler extends MouseAdapter {
7189

7290
private final Frame frame;
@@ -96,7 +114,14 @@ public void mouseDragged(MouseEvent event) {
96114
|| (event.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) == 0) {
97115
return;
98116
}
99-
frame.setLocation(draggedWindowLocation(windowOrigin, pointerOrigin, event.getLocationOnScreen()));
117+
Point pointer = event.getLocationOnScreen();
118+
if ((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH) {
119+
Dimension maximizedSize = frame.getSize();
120+
frame.setExtendedState(frame.getExtendedState() & ~Frame.MAXIMIZED_BOTH);
121+
windowOrigin = restoredDragOrigin(maximizedSize, frame.getSize(), windowOrigin, pointer);
122+
pointerOrigin = pointer;
123+
}
124+
frame.setLocation(draggedWindowLocation(windowOrigin, pointerOrigin, pointer));
100125
}
101126

102127
@Override

‎chat2db-community-server/chat2db-community-jcef/src/test/java/ai/chat2db/community/jcef/frame/WindowsCommunityWindowChromeTest.java‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import javax.swing.JComponent;
77
import javax.swing.JPanel;
88
import javax.swing.JRootPane;
9+
import java.awt.Dimension;
910
import java.awt.Point;
1011
import java.util.function.Function;
1112

@@ -78,4 +79,33 @@ void shouldMoveWindowByThePointerDelta() {
7879
)
7980
);
8081
}
82+
83+
@Test
84+
void shouldAnchorRestoredWindowUnderThePointer() {
85+
// Maximized 1000x800 at (0,0); the drag started with the pointer a
86+
// quarter across and 5% down. After restoring to 800x600 the window
87+
// must jump so the pointer keeps that relative position.
88+
assertEquals(
89+
new Point(250 - 200, 40 - 30),
90+
WindowsCommunityWindowChrome.restoredDragOrigin(
91+
new Dimension(1000, 800),
92+
new Dimension(800, 600),
93+
new Point(0, 0),
94+
new Point(250, 40)
95+
)
96+
);
97+
}
98+
99+
@Test
100+
void shouldFallBackToCenterAnchorsWhenMaximizedSizeIsUnknown() {
101+
assertEquals(
102+
new Point(600 - 400, 300 - 300),
103+
WindowsCommunityWindowChrome.restoredDragOrigin(
104+
new Dimension(0, 0),
105+
new Dimension(800, 600),
106+
new Point(0, 0),
107+
new Point(600, 300)
108+
)
109+
);
110+
}
81111
}

0 commit comments

Comments
 (0)