Browse Source

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
v6.1.6
reuk 3 years ago
parent
commit
72f3a15616
No known key found for this signature in database GPG Key ID: 9ADCD339CFC98A11
1 changed files with 1 additions and 54 deletions
  1. +1
    -54
      modules/juce_gui_basics/native/juce_win32_Windowing.cpp

+ 1
- 54
modules/juce_gui_basics/native/juce_win32_Windowing.cpp View File

@@ -3447,12 +3447,6 @@ private:
}
//==============================================================================
struct ChildWindowCallbackData
{
std::map<HWND, RECT> 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<int> 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<ChildWindowCallbackData*> (data));
callbackData.windowRectsMap[hwnd] = getWindowClientRect (hwnd);
return TRUE;
}
static BOOL CALLBACK scaleChildWindowCallback (HWND hwnd, LPARAM data)
{
auto& callbackData = *(reinterpret_cast<ChildWindowCallbackData*> (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)
{


Loading…
Cancel
Save