From 7685a84c81a9b2a33872e479740220cf1dcbee97 Mon Sep 17 00:00:00 2001 From: reuk Date: Wed, 7 Jan 2026 15:35:07 +0000 Subject: [PATCH] HWNDComponentPeer: Avoid glitches and sluggishness during live resize 258203706cdfc1357effe8cc752672b793cea37d introduced a problem where live-resize of a window would cause the window content to flash and slow down. The cause of the errant behaviour seems to be that, during resize, many WM_PAINT messages might be dispatched over the course of a single vblank interval. Then, each of these paint calls was waiting for the next vblank interval to display. This additional waiting resulted in sluggishness, since many frames would have to be presented before the presentation 'caught up' with the current window size. This also meant that many consecutive frames were presented with stale window size information. The solution added here simply checks whether we're live resizing, and uses the vblank instead of WM_PAINT to synchronise repaints during the resize operation. --- .../native/juce_Windowing_windows.cpp | 37 ++++++++++++++----- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/modules/juce_gui_basics/native/juce_Windowing_windows.cpp b/modules/juce_gui_basics/native/juce_Windowing_windows.cpp index fb8134f45a..366c2e77d6 100644 --- a/modules/juce_gui_basics/native/juce_Windowing_windows.cpp +++ b/modules/juce_gui_basics/native/juce_Windowing_windows.cpp @@ -2096,6 +2096,7 @@ public: } bool hasTitleBar() const { return (styleFlags & windowHasTitleBar) != 0; } + bool isSizing() const { return sizing; } private: HWND hwnd, parentToAddTo; @@ -5077,14 +5078,22 @@ public: updateRegion.findRECTAndValidate (peer.getHWND()); - for (const auto& rect : updateRegion.getRects()) - direct2DContext->addDeferredRepaint (D2DUtilities::toRectangle (rect)); + if (peer.isSizing()) + { + for (const auto& rect : updateRegion.getRects()) + deferredRepaints.add (D2DUtilities::toRectangle (rect)); + } + else + { + for (const auto& rect : updateRegion.getRects()) + direct2DContext->addDeferredRepaint (D2DUtilities::toRectangle (rect)); - #if JUCE_DIRECT2D_METRICS - lastPaintStartTicks = paintStartTicks; - #endif + #if JUCE_DIRECT2D_METRICS + lastPaintStartTicks = paintStartTicks; + #endif - handleDirect2DPaint(); + handleDirect2DPaint(); + } } void repaint (const Rectangle& area) override @@ -5101,10 +5110,20 @@ public: void onVBlank() override { - for (auto deferredRect : deferredRepaints) + if (peer.isSizing()) { - auto r = D2DUtilities::toRECT (deferredRect); - InvalidateRect (peer.getHWND(), &r, FALSE); + for (const auto& rect : deferredRepaints) + direct2DContext->addDeferredRepaint (rect); + + handleDirect2DPaint(); + } + else + { + for (auto deferredRect : deferredRepaints) + { + auto r = D2DUtilities::toRECT (deferredRect); + InvalidateRect (peer.getHWND(), &r, FALSE); + } } deferredRepaints.clear();