2424import java .awt .EventQueue ;
2525import java .awt .Frame ;
2626import java .awt .GraphicsConfiguration ;
27+ import java .awt .Insets ;
2728import java .awt .Point ;
2829import java .awt .Rectangle ;
2930import java .awt .Window ;
4243import javax .swing .event .EventListenerList ;
4344import com .formdev .flatlaf .ui .FlatNativeWindowBorder ;
4445import com .formdev .flatlaf .util .SystemInfo ;
46+ import com .formdev .flatlaf .util .UIScale ;
4547import com .sun .jna .Native ;
4648import com .sun .jna .Pointer ;
4749import com .sun .jna .Structure ;
@@ -326,6 +328,8 @@ private class WndProc
326328 HTMINBUTTON = 8 ,
327329 HTMAXBUTTON = 9 ,
328330 HTTOP = 12 ,
331+ HTTOPLEFT = 13 ,
332+ HTTOPRIGHT = 14 ,
329333 HTCLOSE = 20 ;
330334
331335 private static final int ABS_AUTOHIDE = 0x0000001 ;
@@ -674,6 +678,35 @@ private LRESULT WmNcHitTest( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam )
674678 // scale-down mouse x/y because Swing coordinates/values may be scaled on a HiDPI screen
675679 Point pt = scaleDown ( x , y );
676680
681+ int resizeBorderHeight = getResizeHandleHeight ();
682+ boolean isOnResizeBorder = (y < resizeBorderHeight ) &&
683+ (User32 .INSTANCE .GetWindowLong ( hwnd , GWL_STYLE ) & WS_THICKFRAME ) != 0 ;
684+
685+ // limit top resize border to 4px, which seems to be standard for modern WinUI apps
686+ if ( isOnResizeBorder && pt .y > UIScale .scale ( 4 ) )
687+ isOnResizeBorder = false ;
688+
689+ if ( isOnResizeBorder ) {
690+ Insets insets = window .getInsets ();
691+
692+ // return HTTOPLEFT if mouse is over top resize border on left side
693+ // - hovering mouse shows top-left resize cursor
694+ // - left-click-and-drag resizes window
695+ if ( pt .x <= insets .left + UIScale .scale ( 12 ) )
696+ return new LRESULT ( HTTOPLEFT );
697+
698+ // return HTTOPRIGHT if mouse is over top resize border on right side
699+ // - hovering mouse shows top-right resize cursor
700+ // - left-click-and-drag resizes window
701+ if ( pt .x >= window .getWidth () - insets .right - UIScale .scale ( 12 ) )
702+ return new LRESULT ( HTTOPRIGHT );
703+
704+ // return HTTOP if mouse is over top resize border
705+ // - hovering mouse shows vertical resize cursor
706+ // - left-click-and-drag vertically resizes window
707+ return new LRESULT ( HTTOP );
708+ }
709+
677710 // return HTSYSMENU if mouse is over application icon
678711 // - left-click on HTSYSMENU area shows system menu
679712 // - double-left-click sends WM_CLOSE
@@ -697,16 +730,6 @@ private LRESULT WmNcHitTest( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam )
697730 if ( contains ( closeButtonBounds , pt ) )
698731 return new LRESULT ( HTCLOSE );
699732
700- int resizeBorderHeight = getResizeHandleHeight ();
701- boolean isOnResizeBorder = (y < resizeBorderHeight ) &&
702- (User32 .INSTANCE .GetWindowLong ( hwnd , GWL_STYLE ) & WS_THICKFRAME ) != 0 ;
703-
704- // return HTTOP if mouse is over top resize border
705- // - hovering mouse shows vertical resize cursor
706- // - left-click and drag vertically resizes window
707- if ( isOnResizeBorder )
708- return new LRESULT ( HTTOP );
709-
710733 boolean isOnTitleBar = (pt .y < titleBarHeight );
711734 if ( isOnTitleBar ) {
712735 // return HTCLIENT if mouse is over any Swing component in title bar
0 commit comments