mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-12 23:07:15 -06:00
Native window decorations: fixed broken maximizing window (under special conditions) when restoring frame state at startup (issue #283)
This commit is contained in:
@@ -292,6 +292,11 @@ public class FlatWindowsNativeWindowBorder
|
||||
WM_NCRBUTTONUP = 0x00A5,
|
||||
WM_DWMCOLORIZATIONCOLORCHANGED = 0x0320;
|
||||
|
||||
// WM_SIZE wParam
|
||||
private static final int
|
||||
SIZE_MINIMIZED = 1,
|
||||
SIZE_MAXIMIZED = 2;
|
||||
|
||||
// WM_NCHITTEST mouse position codes
|
||||
private static final int
|
||||
HTCLIENT = 1,
|
||||
@@ -320,6 +325,7 @@ public class FlatWindowsNativeWindowBorder
|
||||
private Window window;
|
||||
private final HWND hwnd;
|
||||
private final BaseTSD.LONG_PTR defaultWndProc;
|
||||
private int wmSizeWParam = -1;
|
||||
|
||||
private int titleBarHeight;
|
||||
private Rectangle[] hitTestSpots;
|
||||
@@ -338,16 +344,7 @@ public class FlatWindowsNativeWindowBorder
|
||||
defaultWndProc = User32Ex.INSTANCE.SetWindowLong( hwnd, GWLP_WNDPROC, this );
|
||||
|
||||
// remove the OS window title bar
|
||||
if( window instanceof JFrame && ((JFrame)window).getExtendedState() != 0 ) {
|
||||
// In case that the frame should be maximized or minimized immediately
|
||||
// when showing, then it is necessary to defer ::SetWindowPos() invocation.
|
||||
// Otherwise the frame will not be maximized or minimized.
|
||||
// This occurs only if frame.pack() was no invoked.
|
||||
EventQueue.invokeLater( () -> {
|
||||
updateFrame();
|
||||
});
|
||||
} else
|
||||
updateFrame();
|
||||
updateFrame( (window instanceof JFrame) ? ((JFrame)window).getExtendedState() : 0 );
|
||||
}
|
||||
|
||||
void uninstall() {
|
||||
@@ -358,16 +355,31 @@ public class FlatWindowsNativeWindowBorder
|
||||
User32Ex.INSTANCE.SetWindowLong( hwnd, GWLP_WNDPROC, defaultWndProc );
|
||||
|
||||
// show the OS window title bar
|
||||
updateFrame();
|
||||
updateFrame( 0 );
|
||||
|
||||
// cleanup
|
||||
window = null;
|
||||
}
|
||||
|
||||
private void updateFrame() {
|
||||
private void updateFrame( int state ) {
|
||||
// Following SetWindowPos() sends a WM_SIZE(SIZE_RESTORED) message to the window
|
||||
// (although SWP_NOSIZE is set), which would prevent maximizing/minimizing
|
||||
// when making the frame visible.
|
||||
// AWT uses WM_SIZE wParam SIZE_RESTORED to update JFrame.extendedState and
|
||||
// removes MAXIMIZED_BOTH and ICONIFIED. (see method AwtFrame::WmSize() in awt_Frame.cpp)
|
||||
// To avoid this, change WM_SIZE wParam to SIZE_MAXIMIZED or SIZE_MINIMIZED if necessary.
|
||||
if( (state & JFrame.ICONIFIED) != 0 )
|
||||
wmSizeWParam = SIZE_MINIMIZED;
|
||||
else if( (state & JFrame.MAXIMIZED_BOTH) == JFrame.MAXIMIZED_BOTH )
|
||||
wmSizeWParam = SIZE_MAXIMIZED;
|
||||
else
|
||||
wmSizeWParam = -1;
|
||||
|
||||
// this sends WM_NCCALCSIZE and removes/shows the window title bar
|
||||
User32.INSTANCE.SetWindowPos( hwnd, hwnd, 0, 0, 0, 0,
|
||||
SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
|
||||
|
||||
wmSizeWParam = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -391,6 +403,11 @@ public class FlatWindowsNativeWindowBorder
|
||||
fireStateChangedLaterOnce();
|
||||
break;
|
||||
|
||||
case WM_SIZE:
|
||||
if( wmSizeWParam >= 0 )
|
||||
wParam = new WPARAM( wmSizeWParam );
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
return WmDestroy( hwnd, uMsg, wParam, lParam );
|
||||
}
|
||||
|
||||
@@ -47,9 +47,9 @@ JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_00024WndProc_updateFrame
|
||||
( JNIEnv* env, jobject obj, jlong hwnd )
|
||||
( JNIEnv* env, jobject obj, jlong hwnd, jint state )
|
||||
{
|
||||
FlatWndProc::updateFrame( reinterpret_cast<HWND>( hwnd ) );
|
||||
FlatWndProc::updateFrame( reinterpret_cast<HWND>( hwnd ), state );
|
||||
}
|
||||
|
||||
extern "C"
|
||||
@@ -68,6 +68,9 @@ jmethodID FlatWndProc::fireStateChangedLaterOnceMID;
|
||||
|
||||
HWNDMap* FlatWndProc::hwndMap;
|
||||
|
||||
#define java_awt_Frame_ICONIFIED 1
|
||||
#define java_awt_Frame_MAXIMIZED_BOTH (4 | 2)
|
||||
|
||||
//---- class FlatWndProc methods ----------------------------------------------
|
||||
|
||||
FlatWndProc::FlatWndProc() {
|
||||
@@ -76,6 +79,7 @@ FlatWndProc::FlatWndProc() {
|
||||
obj = NULL;
|
||||
hwnd = NULL;
|
||||
defaultWndProc = NULL;
|
||||
wmSizeWParam = -1;
|
||||
}
|
||||
|
||||
HWND FlatWndProc::install( JNIEnv *env, jobject obj, jobject window ) {
|
||||
@@ -120,7 +124,7 @@ void FlatWndProc::uninstall( JNIEnv *env, jobject obj, HWND hwnd ) {
|
||||
::SetWindowLongPtr( hwnd, GWLP_WNDPROC, (LONG_PTR) fwp->defaultWndProc );
|
||||
|
||||
// show the OS window title bar
|
||||
updateFrame( hwnd );
|
||||
updateFrame( hwnd, 0 );
|
||||
|
||||
// cleanup
|
||||
env->DeleteGlobalRef( fwp->obj );
|
||||
@@ -145,10 +149,29 @@ void FlatWndProc::initIDs( JNIEnv *env, jobject obj ) {
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
void FlatWndProc::updateFrame( HWND hwnd ) {
|
||||
void FlatWndProc::updateFrame( HWND hwnd, int state ) {
|
||||
// Following SetWindowPos() sends a WM_SIZE(SIZE_RESTORED) message to the window
|
||||
// (although SWP_NOSIZE is set), which would prevent maximizing/minimizing
|
||||
// when making the frame visible.
|
||||
// AWT uses WM_SIZE wParam SIZE_RESTORED to update JFrame.extendedState and
|
||||
// removes MAXIMIZED_BOTH and ICONIFIED. (see method AwtFrame::WmSize() in awt_Frame.cpp)
|
||||
// To avoid this, change WM_SIZE wParam to SIZE_MAXIMIZED or SIZE_MINIMIZED if necessary.
|
||||
FlatWndProc* fwp = (FlatWndProc*) hwndMap->get( hwnd );
|
||||
if( fwp != NULL ) {
|
||||
if( (state & java_awt_Frame_ICONIFIED) != 0 )
|
||||
fwp->wmSizeWParam = SIZE_MINIMIZED;
|
||||
else if( (state & java_awt_Frame_MAXIMIZED_BOTH) == java_awt_Frame_MAXIMIZED_BOTH )
|
||||
fwp->wmSizeWParam = SIZE_MAXIMIZED;
|
||||
else
|
||||
fwp->wmSizeWParam = -1;
|
||||
}
|
||||
|
||||
// this sends WM_NCCALCSIZE and removes/shows the window title bar
|
||||
::SetWindowPos( hwnd, hwnd, 0, 0, 0, 0,
|
||||
SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
|
||||
|
||||
if( fwp != NULL )
|
||||
fwp->wmSizeWParam = -1;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK FlatWndProc::StaticWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
|
||||
@@ -176,6 +199,11 @@ LRESULT CALLBACK FlatWndProc::WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, L
|
||||
fireStateChangedLaterOnce();
|
||||
break;
|
||||
|
||||
case WM_SIZE:
|
||||
if( wmSizeWParam >= 0 )
|
||||
wParam = wmSizeWParam;
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
return WmDestroy( hwnd, uMsg, wParam, lParam );
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ class FlatWndProc
|
||||
public:
|
||||
static HWND install( JNIEnv *env, jobject obj, jobject window );
|
||||
static void uninstall( JNIEnv *env, jobject obj, HWND hwnd );
|
||||
static void updateFrame( HWND hwnd );
|
||||
static void updateFrame( HWND hwnd, int state );
|
||||
|
||||
private:
|
||||
static int initialized;
|
||||
@@ -40,6 +40,7 @@ private:
|
||||
jobject obj;
|
||||
HWND hwnd;
|
||||
WNDPROC defaultWndProc;
|
||||
int wmSizeWParam;
|
||||
|
||||
FlatWndProc();
|
||||
static void initIDs( JNIEnv *env, jobject obj );
|
||||
|
||||
@@ -34,10 +34,10 @@ JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder
|
||||
/*
|
||||
* Class: com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc
|
||||
* Method: updateFrame
|
||||
* Signature: (J)V
|
||||
* Signature: (JI)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_00024WndProc_updateFrame
|
||||
(JNIEnv *, jobject, jlong);
|
||||
(JNIEnv *, jobject, jlong, jint);
|
||||
|
||||
/*
|
||||
* Class: com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc
|
||||
|
||||
Reference in New Issue
Block a user