diff --git a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp index 7a76c48367..647ec848c3 100644 --- a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp @@ -2015,28 +2015,23 @@ public: { if (isOpen) { - if (ComponentPeer* const peer = getPeer()) + #if JUCE_LINUX + if (pluginWindow != 0) { - peer->addMaskedRegion (peer->globalToLocal (getScreenBounds())); + const Rectangle clip (g.getClipBounds()); - #if JUCE_LINUX - if (pluginWindow != 0) - { - const Rectangle clip (g.getClipBounds()); + XEvent ev = { 0 }; + ev.xexpose.type = Expose; + ev.xexpose.display = display; + ev.xexpose.window = pluginWindow; + ev.xexpose.x = clip.getX(); + ev.xexpose.y = clip.getY(); + ev.xexpose.width = clip.getWidth(); + ev.xexpose.height = clip.getHeight(); - XEvent ev = { 0 }; - ev.xexpose.type = Expose; - ev.xexpose.display = display; - ev.xexpose.window = pluginWindow; - ev.xexpose.x = clip.getX(); - ev.xexpose.y = clip.getY(); - ev.xexpose.width = clip.getWidth(); - ev.xexpose.height = clip.getHeight(); - - sendEventToChild (ev); - } - #endif + sendEventToChild (ev); } + #endif } else { diff --git a/modules/juce_gui_basics/components/juce_Component.cpp b/modules/juce_gui_basics/components/juce_Component.cpp index 50cd4a8add..85213c8134 100644 --- a/modules/juce_gui_basics/components/juce_Component.cpp +++ b/modules/juce_gui_basics/components/juce_Component.cpp @@ -1839,9 +1839,9 @@ void Component::internalRepaintUnchecked (const Rectangle& area, const bool //============================================================================== void Component::paint (Graphics&) { - // all painting is done in the subclasses - - jassert (! isOpaque()); // if your component's opaque, you've gotta paint it! + // if your component is marked as opaque, you must implement a paint + // method and ensure that its entire area is completely painted. + jassert (getBounds().isEmpty() || ! isOpaque()); } void Component::paintOverChildren (Graphics&) diff --git a/modules/juce_gui_basics/native/juce_linux_Windowing.cpp b/modules/juce_gui_basics/native/juce_linux_Windowing.cpp index 7aa71761c6..fd74f22f6c 100644 --- a/modules/juce_gui_basics/native/juce_linux_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_linux_Windowing.cpp @@ -1840,8 +1840,6 @@ private: } #endif - peer.clearMaskedRegion(); - RectangleList originalRepaintRegion (regionsNeedingRepaint); regionsNeedingRepaint.clear(); const Rectangle totalArea (originalRepaintRegion.getBounds()); @@ -1877,9 +1875,6 @@ private: peer.handlePaint (*context); } - if (! peer.maskedRegion.isEmpty()) - originalRepaintRegion.subtract (peer.maskedRegion); - for (const Rectangle* i = originalRepaintRegion.begin(), * const e = originalRepaintRegion.end(); i != e; ++i) { #if JUCE_USE_XSHM diff --git a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp index 865319aa17..ddea196e7d 100644 --- a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp @@ -333,19 +333,12 @@ public: void blitToWindow (HWND hwnd, HDC dc, const bool transparent, const int x, const int y, - const RectangleList& maskedRegion, const uint8 updateLayeredWindowAlpha) noexcept { SetMapMode (dc, MM_TEXT); if (transparent) { - if (! maskedRegion.isEmpty()) - { - for (const Rectangle* i = maskedRegion.begin(), * const e = maskedRegion.end(); i != e; ++i) - ExcludeClipRect (hdc, i->getX(), i->getY(), i->getRight(), i->getBottom()); - } - RECT windowBounds; GetWindowRect (hwnd, &windowBounds); @@ -364,24 +357,11 @@ public: } else { - int savedDC = 0; - - if (! maskedRegion.isEmpty()) - { - savedDC = SaveDC (dc); - - for (const Rectangle* i = maskedRegion.begin(), * const e = maskedRegion.end(); i != e; ++i) - ExcludeClipRect (dc, i->getX(), i->getY(), i->getRight(), i->getBottom()); - } - StretchDIBits (dc, x, y, width, height, 0, 0, width, height, bitmapData, (const BITMAPINFO*) &bitmapInfo, DIB_RGB_COLORS, SRCCOPY); - - if (! maskedRegion.isEmpty()) - RestoreDC (dc, savedDC); } } @@ -1422,6 +1402,19 @@ private: } } + static BOOL CALLBACK clipChildWindowCallback (HWND hwnd, LPARAM context) + { + RECT childPos, parentPos; + GetWindowRect (hwnd, &childPos); + GetWindowRect (GetParent (hwnd), &parentPos); + + ((RectangleList*) context)->subtract (Rectangle (childPos.left - parentPos.left, + childPos.top - parentPos.top, + childPos.right - childPos.left, + childPos.bottom - childPos.top)); + return TRUE; + } + //============================================================================== void handlePaintMessage() { @@ -1483,8 +1476,6 @@ private: if (w > 0 && h > 0) { - clearMaskedRegion(); - Image& offscreenImage = offscreenImageGenerator.getImage (transparent, w, h); RectangleList contextClip; @@ -1539,24 +1530,27 @@ private: contextClip.addWithoutMerging (Rectangle (w, h)); } - if (transparent) + EnumChildWindows (hwnd, clipChildWindowCallback, (LPARAM) &contextClip); + + if (! contextClip.isEmpty()) { - for (const Rectangle* i = contextClip.begin(), * const e = contextClip.end(); i != e; ++i) - offscreenImage.clear (*i); + if (transparent) + for (const Rectangle* i = contextClip.begin(), * const e = contextClip.end(); i != e; ++i) + offscreenImage.clear (*i); + + // if the component's not opaque, this won't draw properly unless the platform can support this + jassert (Desktop::canUseSemiTransparentWindows() || component.isOpaque()); + + { + ScopedPointer context (component.getLookAndFeel() + .createGraphicsContext (offscreenImage, Point (-x, -y), contextClip)); + handlePaint (*context); + } + + if (! dontRepaint) + static_cast (offscreenImage.getPixelData()) + ->blitToWindow (hwnd, dc, transparent, x, y, updateLayeredWindowAlpha); } - - // if the component's not opaque, this won't draw properly unless the platform can support this - jassert (Desktop::canUseSemiTransparentWindows() || component.isOpaque()); - - { - ScopedPointer context (component.getLookAndFeel() - .createGraphicsContext (offscreenImage, Point (-x, -y), contextClip)); - handlePaint (*context); - } - - if (! dontRepaint) - static_cast (offscreenImage.getPixelData()) - ->blitToWindow (hwnd, dc, transparent, x, y, maskedRegion, updateLayeredWindowAlpha); } DeleteObject (rgn); diff --git a/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp b/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp index 3e9e53c851..082a8e2b54 100644 --- a/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp +++ b/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp @@ -573,17 +573,6 @@ void ComponentPeer::setRepresentedFile (const File&) { } -//============================================================================== -void ComponentPeer::clearMaskedRegion() -{ - maskedRegion.clear(); -} - -void ComponentPeer::addMaskedRegion (const Rectangle& area) -{ - maskedRegion.add (area); -} - //============================================================================== StringArray ComponentPeer::getAvailableRenderingEngines() { return StringArray ("Software Renderer"); } int ComponentPeer::getCurrentRenderingEngine() const { return 0; } diff --git a/modules/juce_gui_basics/windows/juce_ComponentPeer.h b/modules/juce_gui_basics/windows/juce_ComponentPeer.h index 6375b8db51..118892cd06 100644 --- a/modules/juce_gui_basics/windows/juce_ComponentPeer.h +++ b/modules/juce_gui_basics/windows/juce_ComponentPeer.h @@ -323,24 +323,6 @@ public: bool handleDragExit (const DragInfo&); bool handleDragDrop (const DragInfo&); - //============================================================================== - /** Resets the masking region. - The subclass should call this every time it's about to call the handlePaint method. - @see addMaskedRegion - */ - void clearMaskedRegion(); - - /** Adds a rectangle to the set of areas not to paint over. - - A component can call this on its peer during its paint() method, to signal - that the painting code should ignore a given region. The reason - for this is to stop embedded windows (such as OpenGL) getting painted over. - - The masked region is cleared each time before a paint happens, so a component - will have to make sure it calls this every time it's painted. - */ - void addMaskedRegion (const Rectangle& area); - //============================================================================== /** Returns the number of currently-active peers. @see getPeer @@ -369,7 +351,6 @@ protected: //============================================================================== Component& component; const int styleFlags; - RectangleList maskedRegion; Rectangle lastNonFullscreenBounds; ComponentBoundsConstrainer* constrainer; diff --git a/modules/juce_opengl/opengl/juce_OpenGLContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLContext.cpp index 0e1d5a52c3..88800fe3b5 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLContext.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLContext.cpp @@ -69,11 +69,7 @@ public: } //============================================================================== - void paint (Graphics&) override - { - if (ComponentPeer* const peer = component.getPeer()) - peer->addMaskedRegion (peer->getComponent().getLocalArea (&component, component.getLocalBounds())); - } + void paint (Graphics&) override {} void invalidateAll() override { diff --git a/modules/juce_video/native/juce_win32_DirectShowComponent.cpp b/modules/juce_video/native/juce_win32_DirectShowComponent.cpp index 8fef860778..8ec01dd048 100644 --- a/modules/juce_video/native/juce_win32_DirectShowComponent.cpp +++ b/modules/juce_video/native/juce_win32_DirectShowComponent.cpp @@ -254,7 +254,7 @@ public: void handleAsyncUpdate() override { - if (hwnd != 0) + if (hwnd != 0) { if (needToRecreateNativeWindow) { @@ -791,12 +791,8 @@ void DirectShowComponent::updateContextPosition() context->updateContextPosition(); if (getWidth() > 0 && getHeight() > 0) - { - Component* const topComp = getTopLevelComponent(); - - if (topComp->getPeer() != nullptr) - context->updateWindowPosition (topComp->getLocalArea (this, getLocalBounds())); - } + if (ComponentPeer* peer = getTopLevelComponent()->getPeer()) + context->updateWindowPosition (peer->getAreaCoveredBy (*this)); } void DirectShowComponent::showContext (const bool shouldBeVisible) @@ -807,16 +803,9 @@ void DirectShowComponent::showContext (const bool shouldBeVisible) void DirectShowComponent::paint (Graphics& g) { if (videoLoaded) - { context->handleUpdateNowIfNeeded(); - - if (ComponentPeer* const peer = getPeer()) - peer->addMaskedRegion (peer->globalToLocal (getScreenBounds())); - } else - { g.fillAll (Colours::grey); - } } //======================================================================