1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Direct2D: Temporarily disable window transparency for D2D windows

This commit is contained in:
reuk 2024-08-12 20:56:35 +01:00
parent 2a108ca582
commit 348d638581
No known key found for this signature in database
GPG key ID: FCB43929F012EE5C
5 changed files with 12 additions and 74 deletions

View file

@ -573,11 +573,9 @@ protected:
}
public:
Pimpl (Direct2DGraphicsContext& ownerIn, bool opaqueIn)
: owner (ownerIn), opaque (opaqueIn)
explicit Pimpl (Direct2DGraphicsContext& ownerIn)
: owner (ownerIn)
{
setTargetAlpha (1.0f);
directX->adapters.addListener (*this);
}
@ -588,12 +586,6 @@ public:
popAllSavedStates();
}
void setTargetAlpha (float alpha)
{
backgroundColor = D2DUtilities::toCOLOR_F (Colours::black.withAlpha (opaque ? targetAlpha : 0.0f));
targetAlpha = alpha;
}
virtual SavedState* startFrame (float dpiScale)
{
prepare();
@ -832,9 +824,6 @@ public:
}
DirectWriteGlyphRun glyphRun;
bool opaque = true;
float targetAlpha = 1.0f;
D2D1_COLOR_F backgroundColor{};
private:
static void resetTransform (ID2D1DeviceContext1* context)

View file

@ -373,11 +373,6 @@ private:
if (swap.state == SwapChain::State::bufferAllocated || resizing)
return swap.getSize();
// If the window alpha is less than 1.0, clip to the union of the
// deferred repaints so the device context Clear() works correctly
if (targetAlpha < 1.0f || ! opaque)
return deferredRepaints.getBounds();
return deferredRepaints;
}
@ -405,8 +400,8 @@ private:
JUCE_DECLARE_WEAK_REFERENCEABLE (HwndPimpl)
public:
HwndPimpl (Direct2DHwndContext& ownerIn, HWND hwndIn, bool opaqueIn)
: Pimpl (ownerIn, opaqueIn),
HwndPimpl (Direct2DHwndContext& ownerIn, HWND hwndIn)
: Pimpl (ownerIn),
hwnd (hwndIn)
{
}
@ -645,7 +640,7 @@ public:
};
//==============================================================================
Direct2DHwndContext::Direct2DHwndContext (void* windowHandle, bool opaque)
Direct2DHwndContext::Direct2DHwndContext (HWND windowHandle)
{
#if JUCE_DIRECT2D_METRICS
metrics = new Direct2DMetrics { Direct2DMetricsHub::getInstance()->lock,
@ -654,7 +649,7 @@ Direct2DHwndContext::Direct2DHwndContext (void* windowHandle, bool opaque)
Direct2DMetricsHub::getInstance()->add (metrics);
#endif
pimpl = std::make_unique<HwndPimpl> (*this, reinterpret_cast<HWND> (windowHandle), opaque);
pimpl = std::make_unique<HwndPimpl> (*this, windowHandle);
updateSize();
}
@ -675,11 +670,6 @@ void Direct2DHwndContext::handleShowWindow()
pimpl->handleShowWindow();
}
void Direct2DHwndContext::setWindowAlpha (float alpha)
{
pimpl->setTargetAlpha (alpha);
}
void Direct2DHwndContext::setResizing (bool x)
{
pimpl->setResizing (x);
@ -712,13 +702,7 @@ Image Direct2DHwndContext::createSnapshot() const
void Direct2DHwndContext::clearTargetBuffer()
{
// For opaque windows, clear the background to black with the window alpha
// For non-opaque windows, clear the background to transparent black
// In either case, add a transparency layer if the window alpha is less than 1.0
pimpl->getDeviceContext()->Clear (pimpl->backgroundColor);
if (pimpl->targetAlpha < 1.0f)
beginTransparencyLayer (pimpl->targetAlpha);
pimpl->getDeviceContext()->Clear();
}
} // namespace juce

View file

@ -38,11 +38,10 @@ namespace juce
class Direct2DHwndContext : public Direct2DGraphicsContext
{
public:
Direct2DHwndContext (void* windowHandle, bool opaque);
explicit Direct2DHwndContext (HWND windowHandle);
~Direct2DHwndContext() override;
void handleShowWindow();
void setWindowAlpha (float alpha);
void setResizing (bool);
bool getResizing() const;
@ -53,11 +52,6 @@ public:
Image createSnapshot() const override;
static Colour getBackgroundTransparencyKeyColour() noexcept
{
return Colour { 0xff000001 };
}
private:
struct HwndPimpl;
std::unique_ptr<HwndPimpl> pimpl;

View file

@ -38,13 +38,11 @@ namespace juce
struct Direct2DImageContext::ImagePimpl : public Direct2DGraphicsContext::Pimpl
{
public:
static constexpr auto opaque = false;
ImagePimpl (Direct2DImageContext& ownerIn,
ComSmartPtr<ID2D1DeviceContext1> contextIn,
ComSmartPtr<ID2D1Bitmap1> bitmapIn,
const RectangleList<int>& paintAreasIn)
: Pimpl (ownerIn, opaque),
: Pimpl (ownerIn),
context (std::move (contextIn)),
bitmap (std::move (bitmapIn)),
paintAreas (paintAreasIn)

View file

@ -4996,42 +4996,15 @@ public:
explicit D2DRenderContext (HWNDComponentPeer& peerIn)
: peer (peerIn),
direct2DContext (std::make_unique<Direct2DHwndContext> (peer.getHWND(), peer.getComponent().isOpaque()))
direct2DContext (std::make_unique<Direct2DHwndContext> (peer.getHWND()))
{
// Layered windows use the contents of the window back buffer to automatically determine mouse hit testing
// But - Direct2D doesn't fill the window back buffer so the hit tests pass through for transparent windows
//
// Layered windows can use a single RGB colour as a transparency key (like a green screen). So - choose an
// RGB color as the key and call SetLayeredWindowAttributes with LWA_COLORKEY and the key colour.
//
// Then, use an ID2D1HwndRenderTarget when resizing the window to flush the redirection bitmap to that same
// RGB color.
//
// Setting the window class background brush and handling WM_ERASEBKGND didn't work; Windows keeps filling
// the redirection bitmap in with solid black when the window resizes.
//
// Also - only certain colour values seem to work for the transparency key; RGB(0, 0, 1) seems OK
if (peer.getComponent().isOpaque())
return;
peer.setLayeredWindowStyle (true);
auto backgroundKeyColour = Direct2DHwndContext::getBackgroundTransparencyKeyColour();
[[maybe_unused]] auto ok = SetLayeredWindowAttributes (peer.getHWND(),
RGB (backgroundKeyColour.getRed(),
backgroundKeyColour.getGreen(),
backgroundKeyColour.getBlue()),
255,
LWA_COLORKEY);
jassert (ok);
}
const char* getName() const override { return name; }
void setAlpha (float newAlpha) override
void setAlpha (float) override
{
direct2DContext->setWindowAlpha (newAlpha);
peer.getComponent().repaint();
// setAlpha is not supported for swapchain-backed D2D rendering
}
void handlePaintMessage() override