mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-07 14:30:56 +03:00
Native window decorations: when resizing a window to the right or to the bottom, then first fill the new space with the window background color (instead of black) before the layout is updated (issue #339)
This commit is contained in:
@@ -9,8 +9,11 @@ FlatLaf Change Log
|
|||||||
honor maximum size of internal frame. (issue #362)
|
honor maximum size of internal frame. (issue #362)
|
||||||
- Popup: Fixed incorrectly placed drop shadow for medium-weight popups in
|
- Popup: Fixed incorrectly placed drop shadow for medium-weight popups in
|
||||||
maximized windows. (issue #358)
|
maximized windows. (issue #358)
|
||||||
- Native window decorations: Fixed occasional application crash on Windows 10 in
|
- Native window decorations (Windows 10 only):
|
||||||
`flatlaf-windows.dll`. (issue #357)
|
- Fixed occasional application crash in `flatlaf-windows.dll`. (issue #357)
|
||||||
|
- When resizing a window to the right or to the bottom, then first fill the
|
||||||
|
new space with the window background color (instead of black) before the
|
||||||
|
layout is updated.
|
||||||
|
|
||||||
|
|
||||||
## 1.4
|
## 1.4
|
||||||
@@ -25,7 +28,7 @@ FlatLaf Change Log
|
|||||||
- Table and PopupFactory: Use `StackWalker` in Java 9+ for better performance.
|
- Table and PopupFactory: Use `StackWalker` in Java 9+ for better performance.
|
||||||
(issue #334)
|
(issue #334)
|
||||||
- ToolBar: Paint focus indicator for focused button in toolbar. (issue #346)
|
- ToolBar: Paint focus indicator for focused button in toolbar. (issue #346)
|
||||||
- ToolBar: Support focusable buttons in toolbar (set UI values
|
- ToolBar: Support focusable buttons in toolbar (set UI value
|
||||||
`ToolBar.focusableButtons` to `true`). (issue #346)
|
`ToolBar.focusableButtons` to `true`). (issue #346)
|
||||||
|
|
||||||
#### Fixed bugs
|
#### Fixed bugs
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import java.awt.Point;
|
|||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.Window;
|
import java.awt.Window;
|
||||||
import java.awt.geom.AffineTransform;
|
import java.awt.geom.AffineTransform;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -289,6 +291,7 @@ class FlatWindowsNativeWindowBorder
|
|||||||
//---- class WndProc ------------------------------------------------------
|
//---- class WndProc ------------------------------------------------------
|
||||||
|
|
||||||
private class WndProc
|
private class WndProc
|
||||||
|
implements PropertyChangeListener
|
||||||
{
|
{
|
||||||
// WM_NCHITTEST mouse position codes
|
// WM_NCHITTEST mouse position codes
|
||||||
private static final int
|
private static final int
|
||||||
@@ -313,18 +316,36 @@ class FlatWindowsNativeWindowBorder
|
|||||||
|
|
||||||
// remove the OS window title bar
|
// remove the OS window title bar
|
||||||
updateFrame( hwnd, (window instanceof JFrame) ? ((JFrame)window).getExtendedState() : 0 );
|
updateFrame( hwnd, (window instanceof JFrame) ? ((JFrame)window).getExtendedState() : 0 );
|
||||||
|
|
||||||
|
// set window background (used when resizing window)
|
||||||
|
updateWindowBackground();
|
||||||
|
window.addPropertyChangeListener( "background", this );
|
||||||
}
|
}
|
||||||
|
|
||||||
void uninstall() {
|
void uninstall() {
|
||||||
|
window.removePropertyChangeListener( "background", this );
|
||||||
|
|
||||||
uninstallImpl( hwnd );
|
uninstallImpl( hwnd );
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
window = null;
|
window = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void propertyChange( PropertyChangeEvent e ) {
|
||||||
|
updateWindowBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateWindowBackground() {
|
||||||
|
Color bg = window.getBackground();
|
||||||
|
if( bg != null )
|
||||||
|
setWindowBackground( hwnd, bg.getRed(), bg.getGreen(), bg.getBlue() );
|
||||||
|
}
|
||||||
|
|
||||||
private native long installImpl( Window window );
|
private native long installImpl( Window window );
|
||||||
private native void uninstallImpl( long hwnd );
|
private native void uninstallImpl( long hwnd );
|
||||||
private native void updateFrame( long hwnd, int state );
|
private native void updateFrame( long hwnd, int state );
|
||||||
|
private native void setWindowBackground( long hwnd, int r, int g, int b );
|
||||||
private native void showWindow( long hwnd, int cmd );
|
private native void showWindow( long hwnd, int cmd );
|
||||||
|
|
||||||
// invoked from native code
|
// invoked from native code
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ import java.awt.Point;
|
|||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.Window;
|
import java.awt.Window;
|
||||||
import java.awt.geom.AffineTransform;
|
import java.awt.geom.AffineTransform;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -47,6 +49,7 @@ import com.sun.jna.Structure.FieldOrder;
|
|||||||
import com.sun.jna.platform.win32.Advapi32Util;
|
import com.sun.jna.platform.win32.Advapi32Util;
|
||||||
import com.sun.jna.platform.win32.BaseTSD;
|
import com.sun.jna.platform.win32.BaseTSD;
|
||||||
import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR;
|
import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR;
|
||||||
|
import com.sun.jna.platform.win32.GDI32;
|
||||||
import com.sun.jna.platform.win32.Shell32;
|
import com.sun.jna.platform.win32.Shell32;
|
||||||
import com.sun.jna.platform.win32.User32;
|
import com.sun.jna.platform.win32.User32;
|
||||||
import com.sun.jna.platform.win32.WTypes.LPWSTR;
|
import com.sun.jna.platform.win32.WTypes.LPWSTR;
|
||||||
@@ -57,6 +60,7 @@ import com.sun.jna.platform.win32.WinDef.LRESULT;
|
|||||||
import com.sun.jna.platform.win32.WinDef.RECT;
|
import com.sun.jna.platform.win32.WinDef.RECT;
|
||||||
import com.sun.jna.platform.win32.WinDef.UINT_PTR;
|
import com.sun.jna.platform.win32.WinDef.UINT_PTR;
|
||||||
import com.sun.jna.platform.win32.WinDef.WPARAM;
|
import com.sun.jna.platform.win32.WinDef.WPARAM;
|
||||||
|
import com.sun.jna.platform.win32.WinNT.HANDLE;
|
||||||
import com.sun.jna.platform.win32.WinUser.HMONITOR;
|
import com.sun.jna.platform.win32.WinUser.HMONITOR;
|
||||||
import com.sun.jna.platform.win32.WinUser.WindowProc;
|
import com.sun.jna.platform.win32.WinUser.WindowProc;
|
||||||
import com.sun.jna.win32.W32APIOptions;
|
import com.sun.jna.win32.W32APIOptions;
|
||||||
@@ -282,7 +286,7 @@ public class FlatWindowsNativeWindowBorder
|
|||||||
//---- class WndProc ------------------------------------------------------
|
//---- class WndProc ------------------------------------------------------
|
||||||
|
|
||||||
private class WndProc
|
private class WndProc
|
||||||
implements WindowProc
|
implements WindowProc, PropertyChangeListener
|
||||||
{
|
{
|
||||||
private static final int GWLP_WNDPROC = -4;
|
private static final int GWLP_WNDPROC = -4;
|
||||||
|
|
||||||
@@ -345,9 +349,15 @@ public class FlatWindowsNativeWindowBorder
|
|||||||
|
|
||||||
// remove the OS window title bar
|
// remove the OS window title bar
|
||||||
updateFrame( (window instanceof JFrame) ? ((JFrame)window).getExtendedState() : 0 );
|
updateFrame( (window instanceof JFrame) ? ((JFrame)window).getExtendedState() : 0 );
|
||||||
|
|
||||||
|
// set window background (used when resizing window)
|
||||||
|
updateWindowBackground();
|
||||||
|
window.addPropertyChangeListener( "background", this );
|
||||||
}
|
}
|
||||||
|
|
||||||
void uninstall() {
|
void uninstall() {
|
||||||
|
window.removePropertyChangeListener( "background", this );
|
||||||
|
|
||||||
// restore original window procedure
|
// restore original window procedure
|
||||||
if( SystemInfo.isX86_64 )
|
if( SystemInfo.isX86_64 )
|
||||||
User32Ex.INSTANCE.SetWindowLongPtr( hwnd, GWLP_WNDPROC, defaultWndProc );
|
User32Ex.INSTANCE.SetWindowLongPtr( hwnd, GWLP_WNDPROC, defaultWndProc );
|
||||||
@@ -382,6 +392,28 @@ public class FlatWindowsNativeWindowBorder
|
|||||||
wmSizeWParam = -1;
|
wmSizeWParam = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void propertyChange( PropertyChangeEvent evt ) {
|
||||||
|
updateWindowBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateWindowBackground() {
|
||||||
|
Color bg = window.getBackground();
|
||||||
|
if( bg != null )
|
||||||
|
setWindowBackground( bg.getRed(), bg.getGreen(), bg.getBlue() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setWindowBackground( int r, int g, int b ) {
|
||||||
|
// delete old background brush
|
||||||
|
ULONG_PTR oldBrush = User32.INSTANCE.GetClassLongPtr( hwnd, GCLP_HBRBACKGROUND );
|
||||||
|
if( oldBrush != null && oldBrush.longValue() != 0 )
|
||||||
|
GDI32.INSTANCE.DeleteObject( new HANDLE( oldBrush.toPointer() ) );
|
||||||
|
|
||||||
|
// create new background brush
|
||||||
|
HBRUSH brush = GDI32Ex.INSTANCE.CreateSolidBrush( RGB( r, g, b ) );
|
||||||
|
User32Ex.INSTANCE.SetClassLongPtr( hwnd, GCLP_HBRBACKGROUND, brush );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NOTE: This method is invoked on the AWT-Windows thread (not the AWT-EventQueue thread).
|
* NOTE: This method is invoked on the AWT-Windows thread (not the AWT-EventQueue thread).
|
||||||
*/
|
*/
|
||||||
@@ -637,6 +669,13 @@ public class FlatWindowsNativeWindowBorder
|
|||||||
return (short) ((lParam.longValue() >> 16) & 0xffff);
|
return (short) ((lParam.longValue() >> 16) & 0xffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same implementation as RGB(r,g,b) macro in wingdi.h.
|
||||||
|
*/
|
||||||
|
private DWORD RGB( int r, int g, int b ) {
|
||||||
|
return new DWORD( (r & 0xff) | ((g & 0xff) << 8) | ((b & 0xff) << 16) );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the window's system menu.
|
* Opens the window's system menu.
|
||||||
* The system menu is the menu that opens when the user presses Alt+Space or
|
* The system menu is the menu that opens when the user presses Alt+Space or
|
||||||
@@ -690,6 +729,8 @@ public class FlatWindowsNativeWindowBorder
|
|||||||
LONG_PTR SetWindowLong( HWND hWnd, int nIndex, LONG_PTR wndProc );
|
LONG_PTR SetWindowLong( HWND hWnd, int nIndex, LONG_PTR wndProc );
|
||||||
LRESULT CallWindowProc( LONG_PTR lpPrevWndFunc, HWND hWnd, int uMsg, WPARAM wParam, LPARAM lParam );
|
LRESULT CallWindowProc( LONG_PTR lpPrevWndFunc, HWND hWnd, int uMsg, WPARAM wParam, LPARAM lParam );
|
||||||
|
|
||||||
|
LONG_PTR SetClassLongPtr( HWND hWnd, int nIndex, HANDLE wndProc );
|
||||||
|
|
||||||
int GetDpiForWindow( HWND hwnd );
|
int GetDpiForWindow( HWND hwnd );
|
||||||
int GetSystemMetricsForDpi( int nIndex, int dpi );
|
int GetSystemMetricsForDpi( int nIndex, int dpi );
|
||||||
|
|
||||||
@@ -702,6 +743,16 @@ public class FlatWindowsNativeWindowBorder
|
|||||||
BOOL TrackPopupMenu( HMENU hMenu, int uFlags, int x, int y, int nReserved, HWND hWnd, RECT prcRect );
|
BOOL TrackPopupMenu( HMENU hMenu, int uFlags, int x, int y, int nReserved, HWND hWnd, RECT prcRect );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- interface GDI32Ex --------------------------------------------------
|
||||||
|
|
||||||
|
private interface GDI32Ex
|
||||||
|
extends GDI32
|
||||||
|
{
|
||||||
|
GDI32Ex INSTANCE = Native.load( "gdi32", GDI32Ex.class, W32APIOptions.DEFAULT_OPTIONS );
|
||||||
|
|
||||||
|
HBRUSH CreateSolidBrush( DWORD color );
|
||||||
|
}
|
||||||
|
|
||||||
//---- class NCCALCSIZE_PARAMS --------------------------------------------
|
//---- class NCCALCSIZE_PARAMS --------------------------------------------
|
||||||
|
|
||||||
@FieldOrder( { "rgrc" } )
|
@FieldOrder( { "rgrc" } )
|
||||||
|
|||||||
@@ -73,8 +73,8 @@ library {
|
|||||||
|
|
||||||
linkerArgs.addAll( toolChain.map {
|
linkerArgs.addAll( toolChain.map {
|
||||||
when( it ) {
|
when( it ) {
|
||||||
is Gcc, is Clang -> listOf( "-l${jawt}", "-lUser32", "-lshell32", "-lAdvAPI32", "-lKernel32" )
|
is Gcc, is Clang -> listOf( "-l${jawt}", "-lUser32", "-lGdi32", "-lshell32", "-lAdvAPI32", "-lKernel32" )
|
||||||
is VisualCpp -> listOf( "${jawt}.lib", "User32.lib", "shell32.lib", "AdvAPI32.lib", "Kernel32.lib", "/NODEFAULTLIB" )
|
is VisualCpp -> listOf( "${jawt}.lib", "User32.lib", "Gdi32.lib", "shell32.lib", "AdvAPI32.lib", "Kernel32.lib", "/NODEFAULTLIB" )
|
||||||
else -> emptyList()
|
else -> emptyList()
|
||||||
}
|
}
|
||||||
} )
|
} )
|
||||||
|
|||||||
@@ -52,6 +52,13 @@ JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder
|
|||||||
FlatWndProc::updateFrame( reinterpret_cast<HWND>( hwnd ), state );
|
FlatWndProc::updateFrame( reinterpret_cast<HWND>( hwnd ), state );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_00024WndProc_setWindowBackground
|
||||||
|
( JNIEnv* env, jobject obj, jlong hwnd, jint r, jint g, jint b )
|
||||||
|
{
|
||||||
|
FlatWndProc::setWindowBackground( reinterpret_cast<HWND>( hwnd ), r, g, b );
|
||||||
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_00024WndProc_showWindow
|
JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_00024WndProc_showWindow
|
||||||
( JNIEnv* env, jobject obj, jlong hwnd, jint cmd )
|
( JNIEnv* env, jobject obj, jlong hwnd, jint cmd )
|
||||||
@@ -174,6 +181,17 @@ void FlatWndProc::updateFrame( HWND hwnd, int state ) {
|
|||||||
fwp->wmSizeWParam = -1;
|
fwp->wmSizeWParam = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FlatWndProc::setWindowBackground( HWND hwnd, int r, int g, int b ) {
|
||||||
|
// delete old background brush
|
||||||
|
HBRUSH oldBrush = (HBRUSH) ::GetClassLongPtr( hwnd, GCLP_HBRBACKGROUND );
|
||||||
|
if( oldBrush != NULL )
|
||||||
|
::DeleteObject( oldBrush );
|
||||||
|
|
||||||
|
// create new background brush
|
||||||
|
HBRUSH brush = ::CreateSolidBrush( RGB( r, g, b ) );
|
||||||
|
::SetClassLongPtr( hwnd, GCLP_HBRBACKGROUND, (LONG_PTR) brush );
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK FlatWndProc::StaticWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
|
LRESULT CALLBACK FlatWndProc::StaticWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
|
||||||
FlatWndProc* fwp = (FlatWndProc*) hwndMap->get( hwnd );
|
FlatWndProc* fwp = (FlatWndProc*) hwndMap->get( hwnd );
|
||||||
if( fwp == NULL )
|
if( fwp == NULL )
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ public:
|
|||||||
static HWND install( JNIEnv *env, jobject obj, jobject window );
|
static HWND install( JNIEnv *env, jobject obj, jobject window );
|
||||||
static void uninstall( JNIEnv *env, jobject obj, HWND hwnd );
|
static void uninstall( JNIEnv *env, jobject obj, HWND hwnd );
|
||||||
static void updateFrame( HWND hwnd, int state );
|
static void updateFrame( HWND hwnd, int state );
|
||||||
|
static void setWindowBackground( HWND hwnd, int r, int g, int b );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int initialized;
|
static int initialized;
|
||||||
|
|||||||
@@ -39,6 +39,14 @@ JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder
|
|||||||
JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_00024WndProc_updateFrame
|
JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_00024WndProc_updateFrame
|
||||||
(JNIEnv *, jobject, jlong, jint);
|
(JNIEnv *, jobject, jlong, jint);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc
|
||||||
|
* Method: setWindowBackground
|
||||||
|
* Signature: (JIII)V
|
||||||
|
*/
|
||||||
|
JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_00024WndProc_setWindowBackground
|
||||||
|
(JNIEnv *, jobject, jlong, jint, jint, jint);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc
|
* Class: com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc
|
||||||
* Method: showWindow
|
* Method: showWindow
|
||||||
|
|||||||
Reference in New Issue
Block a user