Open Eroica opened 2 years ago
I don't think I can help. Looking at your comment, you seem more versed in Win32 API than me :)
I can add a few more points to your findings though. On my notebook, which has an NVidia card:
root.setStyle("-fx-background-color: transparent");
with root.getStylesheets().add(".root { -fx-background-color: transparent; }");
and removing scene.setFill(Color.TRANSPARENT);
works, until I move the window to an external display.At this point, I don't think it is possible to create a mica window without doing it properly on stage creation. Probably a custom stage implementation is required here, but this is too big a task for what I use JavaFX for.
Sorry :(
No problem, thanks for your hint about the background color! Unfortunately, it doesn't seem to do the same on my NVIDIA desktop, so there might be even more uncertainties.
I also heard conflicting opinions on whether one has to use WS_EX_NOREDIRECTIONBITMAP
at creation time or whether one can set it later with SetWindowLong
. There are also some differences when using StageStyle.UNIFIED
or not, but so far I wasn't able to find out what exactly JavaFX does different in these 2 cases when creating windows (https://github.com/openjdk/jfx/blob/86b854dc367fb32743810716da5583f7d59208f8/modules/javafx.graphics/src/main/native-glass/win/BaseWnd.cpp#L112).
I'll keep investigating this issue, if you have the time feel free to let me know about any changes that you noticed!
An additional thing that I found out: If I use StageStyle.TRANSPARENT
then Mica seems to work as expected! But of course, the window decorations are now missing. JavaFX skips some steps when the window is set to be transparent, or there is something going on with blending the effect onto the window: https://github.com/openjdk/jfx/blob/303bcdb9ba40b7d82e555d675dad8d028e018c86/modules/javafx.graphics/src/main/native-glass/win/GlassWindow.cpp#L807
The most annoying part is that it just works on my desktop, which has an AMD card:
:(
Hi,
using an undocumented -Dprism.forceUploadingPainter=true
/System.setProperty("prism.forceUploadingPainter", "true")
, I was able to make Mica work on my NVIDIA machine! Can you try it on your system? I will also check whether it works on my Intel graphics system later.
StageStyle.UNIFIED
scene.fill = Color.TRANSPARENT
By the way,
The most annoying part is that it just works on my desktop, which has an AMD card:
I had a similar experience. My main machine also uses AMD so in the beginning I thought that Mica works without problems. However, I had another user running AMD where for some reason, the same code didn't work! I needed to investigate that too. But if that forceUploadingPainter
works on NVIDIA and Intel, I hope that it might also remove any inconsistencies on AMD hardware as well.
It doesn't work on mine :( But maybe I'm doing it wrong? I'm more of a sbt person than maven person. How did you pass that option? I tried setting $env:MAVEN_OPTS/$env:JAVA_OPTS, and calling setProperty in main
before launch()
.
I'm actually mainly using Gradle, with Gradle it depends a little bit on whether it runs a main()
function or directly instantiates the JavaFX application.
In general, you could look for the way how to pass "JVM arguments" to Java. For example, in Gradle one can use applicationDefaultJvmArgs
, and then you also need to prepend the option with a D like this: -Dprism.forceUploadingPainter=true
But it actually should work if you use System.setProperty
before launch
... can you check whether other setProperty
works, e.g. System.setProperty("prism.verbose", "true")
? It should then print some information about your graphics configuration.
Turns out you can list JVM options under JavaFX plugin configuration. And it works! Well, the title text background is still opaque but it works :)
Great to hear! I actually do not have this opaque title problem anymore, at least on my current 22H2 machine. I remember having it in the past (before 22H2), but I also put it off until later. Luckily, it seems to be gone for me, but I will look for a fix and tell you if it happens to me again.
For the sake of completeness, I'll collect my data points on Mica issues here:
Graphics | Works out-of-the-box | Works with forceUploadingPainter |
---|---|---|
AMD (Polaris, Navi) | YES | YES(1) |
NVIDIA (30XX series) | NO | YES(2) |
Intel (Xe) | NO | YES(2) |
(1) With performance loss on monitors >60Hz. (2) Possibly with performance loss on monitors >60Hz.
If I notice that it is driver-dependend, I'll lookup the versions and add them later.
You can put 'yes' to both column for RX 570X. And yes, opaque background isn't an issue in 22H2, my notebook is not yet updated.
It turns out the Mica issue that the RX 580 user had was actually me additionally using DwmExtendFrameIntoClientArea
(and me only applying Mica's light theme on a dark-themed desktop). So it seems AMD isn't affected by this in general.
One could now simply enable forceUploadingPainter
on all systems, but I noticed a great performance loss if enabling that and also having a monitor with >60Hz. This might affect only AMD or could depend on the higher refresh rate in general.
In that case, also setting javafx.animation.fullspeed=true
gets rid of what seems to be a frame limit.
Here is also some additional information on what forceUploadingPainter
does:
... Note that it's only required for UploadingPainer. The PresentingPainter does not call uploadPixels(), and thus doesn't depend on RT-24168.
https://bugs.openjdk.org/browse/JDK-8091385
* UploadingPainter is used when we need to render into an offscreen buffer.
* The PresentingPainter is used when we are rendering to the main screen.
*/
* The PresentingPainter is used when we are rendering to the main screen.
* UploadingPainter is used when we need to render into an offscreen buffer.
*/
For now I'll update the table to be more general because in the end it only seems to depend on using AMD or not. I will probably build a check for a user's GPU and enable forceUploadingPainter
if necessary, but if I find out another fix I will let you know!
π
You're awesome.
I will re-open this issue if you don't mind, just to make it a bit more visible. Who knows, maybe there is a third person on the internet that cares about JavaFX on Windows 11 π.
π
You're awesome.
I will re-open this issue if you don't mind, just to make it a bit more visible. Who knows, maybe there is a third person on the internet that cares about JavaFX on Windows 11 π.
me! π
Hi there,
I was hoping that you might help investigating an issue with the Mica effect that I noticed on certain hardware. Similar to you, I was applying Windows 11's Mica style to a JavaFX window by setting the necessary "magic" values (20 and 1029 before 22H2, now 38 on 22H2). While this works great on my main development machine, there seems to be a graphical glitch on certain hardware that make the effect look wrong. For example, with your test code:
Left is how it should look, and right is how it actually looks on another computer that uses an NVIDIA GPU. My main computer where everything works as intended uses an AMD graphics card. The scene is set to
Color.TRANSPARENT
, so it seems the "real" color of the window shines through and is black.At first I noticed this problem on a notebook that uses Intel integrated graphics. I put this on hold because I thought the 22H2 update might fix this issue. However, I now have 22H2 on both an AMD and an NVIDIA system, and the NVIDIA computer still has the same issue no matter if I use my original code or your library.
Now the interesting thing is that if I turn off hardware acceleration (
System.setProperty("prism.order, "sw")
), then both the NVIDIA and the Intel machine show the Mica effect correctly. The fact that other Windows applications (e.g. Explorer) also correctly show the Mica effect makes me think it might something internal to JavaFX---however, it seems, only on certain hardware. Would you happen to know what might be the cause of this?I investigated a little bit more and I was able to achieve something by using Windows'
SetLayeredWindowAttributes(hWnd, RGB(255, 0, 255), 0, LWA_COLORKEY);
and setting the scene background to Magenta (here showcased with my program):Again, left is how it should look, and right is how it looks on an NVIDIA system. What happens is that while the window correctly shows the Mica effect, it is completely mouse transparent, and only the magenta color is actually clickable (and of course there is this strange color fringe).
What I also found out is that other GUI toolkits are able to correctly "Mica-ify" a window on my NVIDIA system, e.g.:
https://github.com/martinet101/win32mica/ https://github.com/dongle-the-gadget/SystemBackdropTypes
However, they seem to do a little bit more than only setting
DwmSetWindowAttribute
. For example, the WPF example works with aCompositionTarget
and a transparent color here: https://github.com/dongle-the-gadget/SystemBackdropTypes/blob/ab18f1aa70f0575e5df42ebad5ae2699b2ee4c9a/SystemBackdropTypes/MainWindow.xaml.cs#L34Sadly, my knowledge about the Windows API is limited, so I wonder if you have any more insights on why this seems to be a JavaFX problem, and what exactly the drivers do different so that it only occurs on certain hardware.