From 72f3a15616b4a03b22b951e77d7dc88f5db62b7d Mon Sep 17 00:00:00 2001 From: reuk Date: Tue, 28 Sep 2021 18:09:24 +0100 Subject: [PATCH] HWNDComponentPeer: Avoid auto-scaling child hwnds The scaling machinery in the component peer was causing problems for hosted plugin views. Scaling the plugin view size requires close collaboration between the plugin and the host, and it's important for the host to have exact control over the size of the plugin's view. The removed code in the HWNDComponentPeer was modifying the sizes of embedded plugin windows, which would often leave them at an incorrect size. The faulty behaviour was especially noticable with plugins that do not support DPI-aware behaviour. I tested with the following plugins (VST2 + VST3), which should all now display correctly in the AudioPluginHost, and assume the correct size when opened on hi-res displays, or dragged between displays with different scale factors: - Plogue AlterEgo - U-He Hive 2 - FabFilter Pro-C - Native Instruments Supercharger - Surge --- .../native/juce_win32_Windowing.cpp | 55 +------------------ 1 file changed, 1 insertion(+), 54 deletions(-) diff --git a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp index 94ffa0f54e..bd686ff409 100644 --- a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp @@ -3447,12 +3447,6 @@ private: } //============================================================================== - struct ChildWindowCallbackData - { - std::map windowRectsMap; - float scaleRatio; - }; - LRESULT handleDPIChanging (int newDPI, RECT newRect) { // Sometimes, windows that should not be automatically scaled (secondary windows in plugins) @@ -3466,7 +3460,7 @@ private: if (approximatelyEqual (scaleFactor, newScale)) return 0; - const auto oldScale = std::exchange (scaleFactor, newScale); + scaleFactor = newScale; { const ScopedValueSetter setter (numInDpiChange, numInDpiChange + 1); @@ -3482,58 +3476,11 @@ private: updateShadower(); InvalidateRect (hwnd, nullptr, FALSE); - ChildWindowCallbackData callbackData; - callbackData.scaleRatio = (float) (scaleFactor / oldScale); - - EnumChildWindows (hwnd, getChildWindowRectCallback, (LPARAM) &callbackData); scaleFactorListeners.call ([this] (ScaleFactorListener& l) { l.nativeScaleFactorChanged (scaleFactor); }); - EnumChildWindows (hwnd, scaleChildWindowCallback, (LPARAM) &callbackData); return 0; } - static BOOL CALLBACK getChildWindowRectCallback (HWND hwnd, LPARAM data) - { - auto& callbackData = *(reinterpret_cast (data)); - - callbackData.windowRectsMap[hwnd] = getWindowClientRect (hwnd); - return TRUE; - } - - static BOOL CALLBACK scaleChildWindowCallback (HWND hwnd, LPARAM data) - { - auto& callbackData = *(reinterpret_cast (data)); - - auto originalBounds = rectangleFromRECT (callbackData.windowRectsMap[hwnd]); - auto scaledBounds = (originalBounds.toFloat() * callbackData.scaleRatio).toNearestInt(); - auto currentBounds = rectangleFromRECT (getWindowClientRect (hwnd)); - - if (scaledBounds != currentBounds) - { - SetWindowPos (hwnd, - nullptr, - scaledBounds.getX(), - scaledBounds.getY(), - scaledBounds.getWidth(), - scaledBounds.getHeight(), - SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER); - } - - if (auto* peer = getOwnerOfWindow (hwnd)) - peer->handleChildDPIChanging(); - - return TRUE; - } - - void handleChildDPIChanging() - { - scaleFactor = getScaleFactorForWindow (parentToAddTo); - scaleFactorListeners.call ([&] (ScaleFactorListener& l) { l.nativeScaleFactorChanged (scaleFactor); }); - - updateShadower(); - InvalidateRect (hwnd, nullptr, FALSE); - } - //============================================================================== void handleAppActivation (const WPARAM wParam) {