Native window decorations: show Windows 11 snap layouts menu when hovering the mouse over the maximize button (issues #397 and #407)

This commit is contained in:
Karl Tauber
2021-11-09 15:36:21 +01:00
parent 33b25c1129
commit 54e6cefa67
9 changed files with 180 additions and 64 deletions

View File

@@ -215,6 +215,26 @@ LRESULT CALLBACK FlatWndProc::WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, L
case WM_NCHITTEST:
return WmNcHitTest( hwnd, uMsg, wParam, lParam );
case WM_NCMOUSEMOVE:
// if mouse is moved over some non-client areas,
// send it also to the client area to allow Swing to process it
// (required for Windows 11 maximize button)
if( wParam == HTMAXBUTTON || wParam == HTCAPTION || wParam == HTSYSMENU )
sendMessageToClientArea( hwnd, WM_MOUSEMOVE, lParam );
break;
case WM_NCLBUTTONDOWN:
case WM_NCLBUTTONUP:
// if left mouse was pressed/released over maximize button,
// send it also to the client area to allow Swing to process it
// (required for Windows 11 maximize button)
if( wParam == HTMAXBUTTON ) {
int uClientMsg = (uMsg == WM_NCLBUTTONDOWN) ? WM_LBUTTONDOWN : WM_LBUTTONUP;
sendMessageToClientArea( hwnd, uClientMsg, lParam );
return 0;
}
break;
case WM_NCRBUTTONUP:
if( wParam == HTCAPTION || wParam == HTSYSMENU )
openSystemMenu( hwnd, GET_X_LPARAM( lParam ), GET_Y_LPARAM( lParam ) );
@@ -305,7 +325,7 @@ LRESULT FlatWndProc::WmNcCalcSize( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lP
bool isMaximized = ::IsZoomed( hwnd );
if( isMaximized && !isFullscreen() ) {
// When a window is maximized, its size is actually a little bit more
// When a window is maximized, its size is actually a little bit larger
// than the monitor's work area. The window is positioned and sized in
// such a way that the resize handles are outside of the monitor and
// then the window is clipped to the monitor so that the resize handle
@@ -354,6 +374,22 @@ LRESULT FlatWndProc::WmNcHitTest( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lPa
if( lResult != HTCLIENT )
return lResult;
// get mouse x/y in window coordinates
LRESULT xy = screen2windowCoordinates( hwnd, lParam );
int x = GET_X_LPARAM( xy );
int y = GET_Y_LPARAM( xy );
int resizeBorderHeight = getResizeHandleHeight();
bool isOnResizeBorder = (y < resizeBorderHeight) &&
(::GetWindowLong( hwnd, GWL_STYLE ) & WS_THICKFRAME) != 0;
return onNcHitTest( x, y, isOnResizeBorder );
}
/**
* Converts screen coordinates to window coordinates.
*/
LRESULT FlatWndProc::screen2windowCoordinates( HWND hwnd, LPARAM lParam ) {
// get window rectangle needed to convert mouse x/y from screen to window coordinates
RECT rcWindow;
::GetWindowRect( hwnd, &rcWindow );
@@ -362,11 +398,7 @@ LRESULT FlatWndProc::WmNcHitTest( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lPa
int x = GET_X_LPARAM( lParam ) - rcWindow.left;
int y = GET_Y_LPARAM( lParam ) - rcWindow.top;
int resizeBorderHeight = getResizeHandleHeight();
bool isOnResizeBorder = (y < resizeBorderHeight) &&
(::GetWindowLong( hwnd, GWL_STYLE ) & WS_THICKFRAME) != 0;
return onNcHitTest( x, y, isOnResizeBorder );
return MAKELONG( x, y );
}
/**
@@ -429,6 +461,14 @@ JNIEnv* FlatWndProc::getEnv() {
return env;
}
void FlatWndProc::sendMessageToClientArea( HWND hwnd, int uMsg, LPARAM lParam ) {
// get mouse x/y in window coordinates
LRESULT xy = screen2windowCoordinates( hwnd, lParam );
// send message
::SendMessage( hwnd, uMsg, 0, xy );
}
/**
* Opens the window's system menu.
* The system menu is the menu that opens when the user presses Alt+Space or

View File

@@ -54,6 +54,7 @@ private:
LRESULT WmNcCalcSize( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam );
LRESULT WmNcHitTest( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam );
LRESULT screen2windowCoordinates( HWND hwnd, LPARAM lParam );
int getResizeHandleHeight();
bool hasAutohideTaskbar( UINT edge, RECT rcMonitor );
BOOL isFullscreen();
@@ -61,6 +62,7 @@ private:
void fireStateChangedLaterOnce();
JNIEnv* getEnv();
void sendMessageToClientArea( HWND hwnd, int uMsg, LPARAM lParam );
void openSystemMenu( HWND hwnd, int x, int y );
void setMenuItemState( HMENU systemMenu, int item, bool enabled );

View File

@@ -13,6 +13,8 @@ extern "C" {
#define com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTCAPTION 2L
#undef com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTSYSMENU
#define com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTSYSMENU 3L
#undef com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTMAXBUTTON
#define com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTMAXBUTTON 9L
#undef com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTTOP
#define com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTTOP 12L
/*