Closed remcopoelstra closed 3 months ago
It doesn't seem to be limited to just my development laptop, I was able to reproduce the issue on 2 more systems (surface go and a mini desktop pc).
Thanks for reporting and for the test case. Unfortunately I can not reproduce it on my Windows 11 PC. Tried various Java versions and various screen scalings.
Anybody else seen this?
Maybe there has something changed in some Windows 11 update. I have a relative old version here (21H2). What Windows 11 versions are you using? (see Settings > System > About > Windows specifications).
Does the top black line appear only for inactive windows?
... I have been trying to build the native windows library myself, I wanted to play around with the WM_NCCALCSIZE code for example ...
There is also a Java version of that code that uses JNA, which is easier to play around (and can be even debugged). See https://github.com/JFormDesigner/FlatLaf/blob/main/flatlaf-natives/flatlaf-natives-jna/src/main/java/com/formdev/flatlaf/natives/jna/windows/FlatWindowsNativeWindowBorder.java
To enable, build flatlaf-natives-jna project and add it as dependency to your project. Then comment out following line:
and un-comment following lines:
Thanks for the jna suggestion! It took me less than a minute to get this working and I'm already getting some interesting results. I will reply with more details later (i'm not sure about the windows versions on my other systems, but I think their probably all 23H2), but first I wanted to let you know my initial findings.
Without really having a idea what I'm doing I wanted to see what the WmNcCalcSize
method does so I started increasing the params.rgrc[0].top
value expecting to see a margin at the top of the window. I noticed I had to increase it with a value of 3 before I could see space being added between the windows control buttons and the top of the frame. I currently have the following code added at line 619 just before the params.write();
call:
params.rgrc[0].top += 2;
// write changed params back to native memory
params.write();
And this 'solves' the issue (the title bar looks good, there's no space between the controls/menus and the top of the frame, and there's no black line painted anymore). This is probably not the actual fix, but it gives the impression that the height of the title-bar (or the top border thickness) is not what it's expected to be.
I just remembered this issue was reported earlier in #618 by the way.
Thanks again for the helpful suggestions!
Seems that there is one pixel missing at top on Windows 11 with FlatLaf window decorations...
If I add a line border:
frame1.getRootPane().setBorder( new LineBorder( Color.red ) );
the top red border is missing (all screenshots at 100% screen scaling):
Adding one pixel to params.rgrc[0].top
makes the top red border visible:
Adding two pixels shows a gap between the window border and the red border (at 100%):
The gap is also there at 125%, but not at 150% or at 175%. But at 200%, I had to add two pixels to make the top red border visible...
On Windows 10, the red border is fully visible in current implementation:
Adding one pixel to params.rgrc[0].top
does not hide the Windows 10 title bar:
So increasing params.rgrc[0].top
on Windows 10 would be a bad idea 😄
Anyway, adding border thickness to params.rgrc[0].top
on Windows 11 seems to be a good idea.
Please try branch win11-top-border
.
There is one commit to the JNA code that uses DWMWA_VISIBLE_FRAME_BORDER_THICKNESS
to get border thickness and adds it to top:
https://github.com/JFormDesigner/FlatLaf/commits/win11-top-border
Border thickness is 1px at 100% and 125%, 2px at 150% to 225%, 3px at 250% and 300%, 4px at 350%
Does this fix the black top border?
That fixed it! 🍻🍺
I tested on all 3 systems that originally had the issue (all 23H2), and I checked at 100%, 125%, 150%, 175% and 200%, they all looked good, no more black lines and also no unexpected gaps, the reported border thickness corresponds to your list. Maximized windows also still look good.
It's difficult to say in what situations the black top border could appear, it seemed dependant of different factors like frame size, overlapping of frames, one of my applications showed it regularly when a new JFrame was presented in front of it, and another application would show it when selecting menu's in the menubar (but I think also only at certain frame sizes). I wouldn't be surprised if quite a few users have this issue without really noticing it, especially at higher scale factors the black line looks pretty similar to the native border.
Your implementation looks good to me, it's nice that the additional thickness is read from the OS, and applying it only on Windows 11 (or later) sounds good to me also.
Thanks again for the great work!
Many thanks for testing and your insights.
I've updated the C++ code in latest 3.5-SNAPSHOT
: https://github.com/JFormDesigner/FlatLaf#snapshots
I have been noticing this already for quite some time now but it has never really bothered me, but this weekend I decided to look into this. I had to take a picture because I am not able to capture the issue with a screenshot or other screen recording tools:
It gets more noticeable when setting a native border color on the window:
I used the following code to reproduce the issue:
It will probably not be easy to reproduce because I see different behavior in different situations, on my hidpi system the black line is visible immediately when running the code, but on a 100% scaled system the black line is visible after the repaint in the mouse-click listener. It also seems to be dependent of the frame sizes and their placement, moving frame2 around also shows the issue.
At first I thought I had found a workaround, one of my applications had the issue especially when selecting menus in the jmenubar, repainting the layeredpane of the frame instead of repainting just the menu made the issue go away. But later I noticed the issue is also present in the above situation where 2 frames overlap.
I have tested many different java runtimes (jbr, openjdk, 11, 19, 21, 22), maybe it's just my laptop, this is a Microsoft Surface Book 3 with Windows 11 pro.
The black line seems to be outside the area that is painted by swing (second picture shows it's painted over the native window border), I have been trying to build the native windows library myself, I wanted to play around with the WM_NCCALCSIZE code for example, but unfortunately I haven't yet been able to stop visual studio from giving build errors (lack of experience on my side).
If you have any idea's whats going on here I'm happy to hear them, I will also see if I can reproduce this on a few more windows 11 systems. Thanks!