Skip to content

Commit

Permalink
Window decorations: fixed black line sometimes painted on top of (nat…
Browse files Browse the repository at this point in the history
…ive) window border on Windows 11 (issue #852)

Windows binaries built and signed locally in clean workspace
  • Loading branch information
DevCharly committed Jun 21, 2024
1 parent c95e95e commit 72a4c00
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ FlatLaf Change Log
updated when table width changed and was painted on wrong side in
right-to-left component orientation).
- Theme Editor: Fixed occasional empty window on startup on macOS.
- FlatLaf window decorations: Fixed black line sometimes painted on top of
(native) window border on Windows 11. (issue #852)

#### Incompatibilities

Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,11 @@
import com.sun.jna.platform.win32.WinDef.RECT;
import com.sun.jna.platform.win32.WinDef.UINT_PTR;
import com.sun.jna.platform.win32.WinDef.WPARAM;
import com.sun.jna.platform.win32.WinError;
import com.sun.jna.platform.win32.WinUser.HMONITOR;
import com.sun.jna.platform.win32.WinUser.WindowProc;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

//
Expand Down Expand Up @@ -615,6 +618,14 @@ private LRESULT WmNcCalcSize( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam
if( hasAutohideTaskbar( ABE_RIGHT, monitorInfo.rcMonitor ) )
params.rgrc[0].right--;
}
} else if( SystemInfo.isWindows_11_orLater ) {
// For Windows 11, add border thickness to top, which is necessary to make the whole Java area visible.
// This also avoids that a black line is sometimes painted on top window border.
// Note: Do not increase top on Windows 10 because this would not hide Windows title bar.
IntByReference borderThickness = new IntByReference();
if( DWMApi.INSTANCE.DwmGetWindowAttribute( hwnd, DWMApi.DWMWA_VISIBLE_FRAME_BORDER_THICKNESS,
borderThickness.getPointer(), 4 ) == WinError.S_OK.intValue() )
params.rgrc[0].top += borderThickness.getValue();
}

// write changed params back to native memory
Expand Down Expand Up @@ -898,6 +909,18 @@ private interface GDI32Ex
HBRUSH CreateSolidBrush( DWORD color );
}

//---- interface DWMApi ---------------------------------------------------

private interface DWMApi
extends StdCallLibrary
{
DWMApi INSTANCE = Native.load( "dwmapi", DWMApi.class, W32APIOptions.DEFAULT_OPTIONS );

int DWMWA_VISIBLE_FRAME_BORDER_THICKNESS = 37;

int DwmGetWindowAttribute( HWND hwnd, int dwAttribute, Pointer pvAttribute, int cbAttribute );
}

//---- class NCCALCSIZE_PARAMS --------------------------------------------

@FieldOrder( { "rgrc" } )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <windows.h>
#include <windowsx.h>
#include <shellapi.h>
#include <dwmapi.h>
#include <jawt.h>
#include <jawt_md.h>
#include "FlatWndProc.h"
Expand Down Expand Up @@ -76,6 +77,7 @@ jmethodID FlatWndProc::isFullscreenMID;
jmethodID FlatWndProc::fireStateChangedLaterOnceMID;

HWNDMap* FlatWndProc::hwndMap;
DWORD FlatWndProc::osBuildNumber = 0;

#define java_awt_Frame_ICONIFIED 1
#define java_awt_Frame_MAXIMIZED_BOTH (4 | 2)
Expand Down Expand Up @@ -107,6 +109,14 @@ HWND FlatWndProc::install( JNIEnv *env, jobject obj, jobject window ) {
return 0;
}

// get OS build number
if( osBuildNumber == 0 ) {
OSVERSIONINFO info;
info.dwOSVersionInfoSize = sizeof( info );
if( ::GetVersionEx( &info ) )
osBuildNumber = info.dwBuildNumber;
}

// get window handle
HWND hwnd = getWindowHandle( env, window );
if( hwnd == NULL || hwndMap->get( hwnd ) != NULL )
Expand Down Expand Up @@ -391,6 +401,13 @@ LRESULT FlatWndProc::WmNcCalcSize( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lP
if( hasAutohideTaskbar( ABE_RIGHT, monitorInfo.rcMonitor ) )
params->rgrc[0].right--;
}
} else if( osBuildNumber >= 22000 ) {
// For Windows 11, add border thickness to top, which is necessary to make the whole Java area visible.
// This also avoids that a black line is sometimes painted on top window border.
// Note: Do not increase top on Windows 10 because this would not hide Windows title bar.
UINT borderThickness = 0;
if( ::DwmGetWindowAttribute( hwnd, DWMWA_VISIBLE_FRAME_BORDER_THICKNESS, &borderThickness, sizeof( borderThickness ) ) == S_OK )
params->rgrc[0].top += borderThickness;
}

return lResult;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class FlatWndProc
static jmethodID fireStateChangedLaterOnceMID;

static HWNDMap* hwndMap;
static DWORD osBuildNumber;

JavaVM* jvm;
JNIEnv* env; // attached to AWT-Windows/Win32 thread
Expand Down

0 comments on commit 72a4c00

Please sign in to comment.