I use a singular juce::TooltipWindow as a member of my UI class, and the LookAndFeel functions only draw a grey (rounded) rectangle and the light-grey text inside. The shadow gets added by JUCE (no options to turn it off). I had to use nullptr for the parent, so the tooltip gets added to the desktop, as otherwise, the OpenGL component would cover the tooltip.
This black border only shows up in release builds. In debug builds it looks like this:
A nice, soft, shadow.
The same happens with the juce::PopupMenu. In release mode it’s a thick black border, in Debug mode it’s a nice soft shadow.
This is on Windows with the latest develop branch. I had this problem only for around 10 days now. Shortly after the new commits were added that changed the Windows behavior to use the newer APIs.
Do you see the same results in the DemoRunner or any of the other JUCE examples? I’m not seeing this in the OpenGLDemo or WidgetsDeo when building from current develop in release mode with MSVC 2022. Are you able to provide code or instructions so that we can reproduce the problem locally?
I use Clang (the one supplied by MS in MSVC 2022) and enabled some optimizations that could cause this (fast-math, sse4, etc.) to squeeze out the last ounce of performance.
I will experiment to narrow it down to a specific compiler flag.
I haven’t done any in-depth testing with the demorunner. A quick test with clang /O3 worked fine.
Interesting observation: a more recent commit (probably having to do with how windows are handled) has fixed this! No changes on my end. I just updated to the latest JUCE, and the shadows are suddenly fixed.
But now Tooltips have two shadows—one from JUCE and, around that, another from the OS.
To work around that, I had to subclass the juce::TooltipWindow and override the addToDesktop function
//
// Hacky workaround for JUCE adding window-shadows to tooltips that are on the desktop
//
class TooltipNoShadow : public juce::TooltipWindow
{
public:
void addToDesktop ( int styleWanted, void* nativeWindowToAttachTo ) override
{
juce::TooltipWindow::addToDesktop ( styleWanted & ~juce::ComponentPeer::windowHasDropShadow, nativeWindowToAttachTo );
}
};
Which JUCE commit are you using? At the moment, I’m not able to repro this behaviour on develop using the WidgetsDemo, which displays a Tooltip when hovering the two star buttons on the right side of the Buttons tab.
Here, when I put a breakpoint in LookAndFeel_V2::createDropShadowerForComponent, the breakpoint is hit when the tooltip window is first displayed. Also, a breakpoint in windowUsesNativeShadow() in juce_Windowing_windows.cpp shows that this function always returns false for the tooltip window and shadow windows, so none of these windows should get a native shadow.
Please could you try the WidgetsDemo and check how the tooltip shadows look there? If they look alright in the demo, then the issues in your app are likely due to some aspect of the tooltip window configuration in that app.
If I were to guess, I’d say it’s likely that the outer shadows are created by JUCE’s drop shadower rather than the OS. At least, the hard inner corners and general appearance of the outer shadow make it look like it’s drawn by JUCE.
This makes me wonder whether the inner shadow is also drawn by JUCE, perhaps using a custom TooltipWindow style. I know you said that your LnF only draws the window background and text, but it might be worth double-checking. If you put a breakpoint in DropShadow::drawForPath, drawForRectangle, and drawForImage, and in the constructor of DropShadower, do any of those breakpoints get hit?
Thinking a bit more, the very first images you posted might be consistent with rendering a transparent image into a window flagged as opaque. TooltipWindow sets itself as opaque in its constructor, so if you’re not changing this option and also not filling the bounds of the window, the background (i.e. the black fill) might be shown under the transparent areas of the window.
Sorry for the wild goose chase. I’ve found the problem. I have no idea how I could have overlooked it until now, but for Tooltips, I draw my own shadow (so I get rounded corners), and then JUCE added its own shadow around that.
This also explains why I thought createDropShadowerForComponent seemingly wasn’t called. Even if I returned a nullptr from that, the shadow was still there… because I drew it myself…
So for TooltipWindows, I now return a nullptr. Otherwise, I call the LAF_V4 createDropShadowerForComponent, creating the other shadows (for PopupMenu, etc.)
I wish the DropShadower had a corner-radius parameter so I wouldn’t have to turn shadows off, add lots of padding, and then draw the shadows myself, as I will now do for PopupMenus. Otherwise, they must be square or have missing shadows in the corners.
You don’t mention it in your reply, so just in case: given that you’re using transparency in your tooltip window, make sure you’re calling setOpaque(false) somewhere on the window before it is first displayed. I think this may solve/prevent the black backgrounds issue you were seeing.
Yes, I did already. That was also why I was confused: It worked in debug but not release. It also worked fine on other computers, just not my main dev machine. They all had the double shadow, but I only had the utterly black border on my machine.
It works fine everywhere now.
Is there any chance we can see a DropShadower with a corner radius for more modern-looking menus/tooltips, etc.?