Native window decorations: support 32-bit JREs

This commit is contained in:
Karl Tauber
2021-03-13 23:41:38 +01:00
parent d2ccb97eba
commit 8eb44a68cb
11 changed files with 49 additions and 27 deletions

1
.gitattributes vendored
View File

@@ -19,6 +19,7 @@
*.dylib binary *.dylib binary
*.gif binary *.gif binary
*.jar binary *.jar binary
*.lib binary
*.png binary *.png binary
*.sketch binary *.sketch binary
*.so binary *.so binary

View File

@@ -144,7 +144,7 @@ public abstract class FlatLaf
* <p> * <p>
* Returns also {@code false} on Windows 10 if: * Returns also {@code false} on Windows 10 if:
* <ul> * <ul>
* <li>FlatLaf native window border support is available (requires Windows 10 64-bit)</li> * <li>FlatLaf native window border support is available (requires Windows 10)</li>
* <li>running in * <li>running in
* <a href="https://confluence.jetbrains.com/display/JBR/JetBrains+Runtime">JetBrains Runtime 11 (or later)</a> * <a href="https://confluence.jetbrains.com/display/JBR/JetBrains+Runtime">JetBrains Runtime 11 (or later)</a>
* (<a href="https://github.com/JetBrains/JetBrainsRuntime">source code on github</a>) * (<a href="https://github.com/JetBrains/JetBrainsRuntime">source code on github</a>)

View File

@@ -63,7 +63,7 @@ public interface FlatSystemProperties
* <p> * <p>
* Setting this to {@code false} disables using FlatLaf native window decorations. * Setting this to {@code false} disables using FlatLaf native window decorations.
* <p> * <p>
* (requires Window 10 64-bit) * (requires Window 10)
* <p> * <p>
* <strong>Allowed Values</strong> {@code false} and {@code true}<br> * <strong>Allowed Values</strong> {@code false} and {@code true}<br>
* <strong>Default</strong> none * <strong>Default</strong> none

View File

@@ -221,8 +221,8 @@ public class FlatNativeWindowBorder
return; return;
supported = false; supported = false;
// requires Windows 10 on x86_64 // requires Windows 10
if( !SystemInfo.isWindows_10_orLater || !SystemInfo.isX86_64 ) if( !SystemInfo.isWindows_10_orLater )
return; return;
// check whether disabled via system property // check whether disabled via system property

View File

@@ -79,8 +79,8 @@ class FlatWindowsNativeWindowBorder
private static FlatWindowsNativeWindowBorder instance; private static FlatWindowsNativeWindowBorder instance;
static FlatNativeWindowBorder.Provider getInstance() { static FlatNativeWindowBorder.Provider getInstance() {
// requires Windows 10 on x86_64 // requires Windows 10
if( !SystemInfo.isWindows_10_orLater || !SystemInfo.isX86_64 ) if( !SystemInfo.isWindows_10_orLater )
return null; return null;
// load native library // load native library
@@ -98,8 +98,11 @@ class FlatWindowsNativeWindowBorder
} }
} }
nativeLibrary = new NativeLibrary( String libraryName = "com/formdev/flatlaf/natives/flatlaf-windows-x86";
"com/formdev/flatlaf/natives/flatlaf-windows-x86_64", if( SystemInfo.isX86_64 )
libraryName += "_64";
nativeLibrary = new NativeLibrary( libraryName,
FlatWindowsNativeWindowBorder.class.getClassLoader(), true ); FlatWindowsNativeWindowBorder.class.getClassLoader(), true );
} }
@@ -135,8 +138,8 @@ class FlatWindowsNativeWindowBorder
} }
private void install( Window window ) { private void install( Window window ) {
// requires Windows 10 on x86_64 // requires Windows 10
if( !SystemInfo.isWindows_10_orLater || !SystemInfo.isX86_64 ) if( !SystemInfo.isWindows_10_orLater )
return; return;
// only JFrame and JDialog are supported // only JFrame and JDialog are supported

View File

@@ -127,8 +127,8 @@ public class FlatWindowsNativeWindowBorder
} }
private void install( Window window ) { private void install( Window window ) {
// requires Windows 10 on x86_64 // requires Windows 10
if( !SystemInfo.isWindows_10_orLater || !SystemInfo.isX86_64 ) if( !SystemInfo.isWindows_10_orLater )
return; return;
// only JFrame and JDialog are supported // only JFrame and JDialog are supported
@@ -321,7 +321,10 @@ public class FlatWindowsNativeWindowBorder
hwnd = new HWND( Native.getComponentPointer( window ) ); hwnd = new HWND( Native.getComponentPointer( window ) );
// replace window procedure // replace window procedure
if( SystemInfo.isX86_64 )
defaultWndProc = User32Ex.INSTANCE.SetWindowLongPtr( hwnd, GWLP_WNDPROC, this ); defaultWndProc = User32Ex.INSTANCE.SetWindowLongPtr( hwnd, GWLP_WNDPROC, this );
else
defaultWndProc = User32Ex.INSTANCE.SetWindowLong( hwnd, GWLP_WNDPROC, this );
// remove the OS window title bar // remove the OS window title bar
updateFrame(); updateFrame();
@@ -329,7 +332,10 @@ public class FlatWindowsNativeWindowBorder
void uninstall() { void uninstall() {
// restore original window procedure // restore original window procedure
if( SystemInfo.isX86_64 )
User32Ex.INSTANCE.SetWindowLongPtr( hwnd, GWLP_WNDPROC, defaultWndProc ); User32Ex.INSTANCE.SetWindowLongPtr( hwnd, GWLP_WNDPROC, defaultWndProc );
else
User32Ex.INSTANCE.SetWindowLong( hwnd, GWLP_WNDPROC, defaultWndProc );
// show the OS window title bar // show the OS window title bar
updateFrame(); updateFrame();
@@ -382,7 +388,10 @@ public class FlatWindowsNativeWindowBorder
LRESULT lResult = User32Ex.INSTANCE.CallWindowProc( defaultWndProc, hwnd, uMsg, wParam, lParam ); LRESULT lResult = User32Ex.INSTANCE.CallWindowProc( defaultWndProc, hwnd, uMsg, wParam, lParam );
// restore original window procedure // restore original window procedure
if( SystemInfo.isX86_64 )
User32Ex.INSTANCE.SetWindowLongPtr( hwnd, GWLP_WNDPROC, defaultWndProc ); User32Ex.INSTANCE.SetWindowLongPtr( hwnd, GWLP_WNDPROC, defaultWndProc );
else
User32Ex.INSTANCE.SetWindowLong( hwnd, GWLP_WNDPROC, defaultWndProc );
// cleanup // cleanup
windowsMap.remove( window ); windowsMap.remove( window );
@@ -640,6 +649,8 @@ public class FlatWindowsNativeWindowBorder
LONG_PTR SetWindowLongPtr( HWND hWnd, int nIndex, WindowProc wndProc ); LONG_PTR SetWindowLongPtr( HWND hWnd, int nIndex, WindowProc wndProc );
LONG_PTR SetWindowLongPtr( HWND hWnd, int nIndex, LONG_PTR wndProc ); LONG_PTR SetWindowLongPtr( HWND hWnd, int nIndex, LONG_PTR wndProc );
LONG_PTR SetWindowLong( HWND hWnd, int nIndex, WindowProc 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 );
int GetDpiForWindow( HWND hwnd ); int GetDpiForWindow( HWND hwnd );

View File

@@ -9,9 +9,9 @@ Tested only with Microsoft Visual C++ 2019 (comes with Visual Studio 2019).
To be able to build FlatLaf on any platform, and without C++ compiler, the To be able to build FlatLaf on any platform, and without C++ compiler, the
pre-built DLL is checked into Git at pre-built DLL is checked into Git at
`flatlaf-core/src/main/resources/com/formdev/flatlaf/natives/flatlaf-windows-x86_64.dll`. [flatlaf-core/src/main/resources/com/formdev/flatlaf/natives/](https://github.com/JFormDesigner/FlatLaf/tree/main/flatlaf-core/src/main/resources/com/formdev/flatlaf/natives).
This DLL was built on a GitHub server with the help of GitHub Actions. See: The DLL was built on a GitHub server with the help of GitHub Actions. See:
[Native Libraries](https://github.com/JFormDesigner/FlatLaf/actions/workflows/natives.yml) [Native Libraries](https://github.com/JFormDesigner/FlatLaf/actions/workflows/natives.yml)
workflow. Then the produced Artifacts ZIP was downloaded and the DLL checked workflow. Then the produced Artifacts ZIP was downloaded and the DLL checked
into Git. into Git.

View File

@@ -20,18 +20,16 @@ plugins {
} }
library { library {
targetMachines.set( listOf( machines.windows.x86_64 ) ) targetMachines.set( listOf( machines.windows.x86, machines.windows.x86_64 ) )
variants.configureEach { variants.configureEach {
// depend on :flatlaf-core:compileJava because this task generates the JNI headers
tasks.named( "compileCpp" ) {
dependsOn( ":flatlaf-core:compileJava" )
}
sharedLibrary { sharedLibrary {
compileTasks.configureEach { compileTasks.configureEach {
onlyIf { isBuildable } onlyIf { isBuildable }
// depend on :flatlaf-core:compileJava because it generates the JNI headers
dependsOn( ":flatlaf-core:compileJava" )
doFirst { doFirst {
println( "Used Tool Chain:" ) println( "Used Tool Chain:" )
println( " - ${toolChain.get()}" ) println( " - ${toolChain.get()}" )
@@ -67,11 +65,12 @@ library {
onlyIf { isBuildable } onlyIf { isBuildable }
val nativesDir = project( ":flatlaf-core" ).projectDir.resolve( "src/main/resources/com/formdev/flatlaf/natives" ) val nativesDir = project( ":flatlaf-core" ).projectDir.resolve( "src/main/resources/com/formdev/flatlaf/natives" )
val libraryName = "flatlaf-windows-x86_64.dll" val is64Bit = targetMachine.architecture.is64Bit
val libraryName = if( is64Bit ) "flatlaf-windows-x86_64.dll" else "flatlaf-windows-x86.dll"
val jawt = if( is64Bit ) "lib/jawt-x86_64" else "lib/jawt-x86"
outputs.file( "$nativesDir/$libraryName" ) outputs.file( "$nativesDir/$libraryName" )
val jawt = "${org.gradle.internal.jvm.Jvm.current().javaHome}/lib/jawt"
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", "-lshell32", "-lAdvAPI32", "-lKernel32" )
@@ -90,9 +89,11 @@ library {
} }
} }
tasks.named( "jar" ) { for( taskName in listOf( "jarX86", "jarX86-64" ) ) {
tasks.named( taskName ) {
onlyIf { false } onlyIf { false }
} }
} }
} }
}
} }

View File

@@ -0,0 +1,6 @@
Contains libraries used to compile FlatLaf Windows 10 native libraries (DLLs).
- `jawt-x86.lib` is `<jdk>/lib/jawt.lib` from AdoptOpenJDK jdk8u282-b08 32-bit,
which is required to build 32-bit DLL
- `jawt-x86_64.lib` is `<jdk>/lib/jawt.lib` from AdoptOpenJDK jdk8u282-b08
64-bit, which is required to build 64-bit DLL