From fc203d62d9dcc7379b4809889e7e34bf0eba8369 Mon Sep 17 00:00:00 2001 From: ed Date: Wed, 19 Sep 2018 12:35:48 +0100 Subject: [PATCH] Windows: Refactored some of the recent DPI-aware VST2 and VST3 plug-in changes --- .../VST/juce_VST_Wrapper.cpp | 124 +++++------- .../VST3/juce_VST3_Wrapper.cpp | 181 +++++++++--------- .../format_types/juce_VSTPluginFormat.cpp | 13 +- 3 files changed, 138 insertions(+), 180 deletions(-) diff --git a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp index ac1b7fc30e..dcb096eec6 100644 --- a/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp @@ -1100,15 +1100,7 @@ public: } if (editorComp != nullptr) - { editorComp->checkVisibility(); - - #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE - if (getHostType().isWavelab()) - if (auto* peer = editorComp->getTopLevelComponent()->getPeer()) - handleSetContentScaleFactor ((float) peer->getPlatformScaleFactor()); - #endif - } } void createEditorComp() @@ -1241,17 +1233,9 @@ public: // A component to hold the AudioProcessorEditor, and cope with some housekeeping // chores when it changes or repaints. struct EditorCompWrapper : public Component - #if ! JUCE_MAC - , public ComponentPeer::ScaleFactorListener, - public ComponentMovementWatcher - #endif { EditorCompWrapper (JuceVSTWrapper& w, AudioProcessorEditor& editor) - : - #if ! JUCE_MAC - ComponentMovementWatcher (this), - #endif - wrapper (w) + : wrapper (w) { editor.setOpaque (true); editor.setVisible (true); @@ -1276,11 +1260,6 @@ public: { deleteAllChildren(); // note that we can't use a std::unique_ptr because the editor may // have been transferred to another parent which takes over ownership. - #if ! JUCE_MAC - for (int i = 0; i < ComponentPeer::getNumPeers(); ++i) - if (auto* peer = ComponentPeer::getPeer (i)) - peer->removeScaleFactorListener (this); - #endif } void paint (Graphics&) override {} @@ -1293,6 +1272,11 @@ public: bounds.left = 0; bounds.bottom = (int16) b.getHeight(); bounds.right = (int16) b.getWidth(); + + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + bounds.bottom = (int16) roundToInt (bounds.bottom * wrapper.editorScaleFactor); + bounds.right = (int16) roundToInt (bounds.right * wrapper.editorScaleFactor); + #endif } void attachToHost (VstOpCodeArguments args) @@ -1303,10 +1287,14 @@ public: #if JUCE_WINDOWS addToDesktop (0, args.ptr); hostWindow = (HWND) args.ptr; - #if JUCE_WIN_PER_MONITOR_DPI_AWARE - // workaround for plug-ins opening on an auxiliary monitor - Timer::callAfterDelay (250, [this] { updateWindowSize (false); }); - #endif + + if (auto* ed = getEditorComp()) + #if JUCE_WIN_PER_MONITOR_DPI_AWARE + if (auto* peer = ed->getPeer()) + wrapper.editorScaleFactor = (float) peer->getPlatformScaleFactor(); + #else + ed->setScaleFactor (wrapper.editorScaleFactor); + #endif #elif JUCE_LINUX addToDesktop (0, args.ptr); hostWindow = (Window) args.ptr; @@ -1346,29 +1334,16 @@ public: return dynamic_cast (getChildComponent(0)); } - float getNativeEditorScaleFactor() const noexcept { return nativeScaleFactor; } - - #if ! JUCE_MAC - void componentMovedOrResized (bool, bool) override {} - - void componentPeerChanged() override + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + void checkScaleFactorIsCorrect() { - if (auto* peer = getTopLevelComponent()->getPeer()) - peer->addScaleFactorListener (this); - } + if (auto* peer = getEditorComp()->getPeer()) + { + auto peerScaleFactor = (float) peer->getPlatformScaleFactor(); - void componentVisibilityChanged() override - { - if (auto* peer = getTopLevelComponent()->getPeer()) - nativeScaleFactorChanged (peer->getPlatformScaleFactor()); - } - - void nativeScaleFactorChanged (double newScaleFactor) override - { - nativeScaleFactor = (float) newScaleFactor; - - if (getHostType().isBitwigStudio()) - updateWindowSize (true); + if (! approximatelyEqual (peerScaleFactor, wrapper.editorScaleFactor)) + wrapper.handleSetContentScaleFactor (peerScaleFactor); + } } #endif @@ -1376,13 +1351,16 @@ public: { if (auto* ed = getEditorComp()) { + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + checkScaleFactorIsCorrect(); + #endif + ed->setTopLeftPosition (0, 0); if (shouldResizeEditor) ed->setBounds (ed->getLocalArea (this, getLocalBounds())); - if (! getHostType().isBitwigStudio()) - updateWindowSize (false); + updateWindowSize (false); } #if JUCE_MAC && ! JUCE_64BIT @@ -1430,8 +1408,8 @@ public: #else ignoreUnused (resizeEditor); XResizeWindow (display.display, (Window) getWindowHandle(), - static_cast (roundToInt (pos.getWidth() * nativeScaleFactor)), - static_cast (roundToInt (pos.getHeight() * nativeScaleFactor))); + static_cast (roundToInt (pos.getWidth() * wrapper.editorScaleFactor)), + static_cast (roundToInt (pos.getHeight() * wrapper.editorScaleFactor))); #endif #if JUCE_MAC @@ -1451,11 +1429,15 @@ public: if (status == (pointer_sized_int) 1 || getHostType().isAbletonLive()) { - isInSizeWindow = true; + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + newWidth = roundToInt (newWidth * wrapper.editorScaleFactor); + newHeight = roundToInt (newHeight * wrapper.editorScaleFactor); + #endif + + const ScopedValueSetter inSizeWindowSetter (isInSizeWindow, true); + sizeWasSuccessful = (host (wrapper.getAEffect(), Vst2::audioMasterSizeWindow, - roundToInt (newWidth * nativeScaleFactor), - roundToInt (newHeight * nativeScaleFactor), 0, 0) != 0); - isInSizeWindow = false; + newWidth, newHeight, 0, 0) != 0); } } @@ -1552,8 +1534,6 @@ public: bool isInSizeWindow = false; bool shouldResizeEditor = true; - float nativeScaleFactor = 1.0f; - #if JUCE_MAC void* hostWindow = {}; #elif JUCE_LINUX @@ -2192,31 +2172,17 @@ private: pointer_sized_int handleSetContentScaleFactor (float scale) { #if ! JUCE_MAC - if (editorComp != nullptr) + if (! approximatelyEqual (scale, editorScaleFactor)) { - #if JUCE_WINDOWS && ! JUCE_WIN_PER_MONITOR_DPI_AWARE - if (auto* ed = editorComp->getEditorComp()) - { - ed->setScaleFactor (scale); - editorComp->updateWindowSize (true); - } - #else - if (! approximatelyEqual (scale, (float) editorComp->getNativeEditorScaleFactor())) - { - editorComp->nativeScaleFactorChanged ((double) scale); + editorScaleFactor = scale; - #if JUCE_LINUX - MessageManager::callAsync ([this] { if (editorComp != nullptr) editorComp->updateWindowSize (true); }); + if (editorComp != nullptr) + #if JUCE_WINDOWS && ! JUCE_WIN_PER_MONITOR_DPI_AWARE + if (auto* ed = editorComp->getEditorComp()) + ed->setScaleFactor (scale); #else editorComp->updateWindowSize (true); #endif - - #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE - if (getHostType().isStudioOne()) - Timer::callAfterDelay (100, [this] { if (editorComp != nullptr) editorComp->updateWindowSize (false); }); - #endif - } - #endif } #else ignoreUnused (scale); @@ -2277,6 +2243,10 @@ private: MidiBuffer midiEvents; VSTMidiEventList outgoingEvents; + #if ! JUCE_MAC + float editorScaleFactor = 1.0f; + #endif + LegacyAudioParametersWrapper juceParameters; bool isProcessing = false, isBypassed = false, hasShutdown = false; diff --git a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp index 968a458a57..dcd0959229 100644 --- a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp @@ -720,6 +720,7 @@ private: //============================================================================== Atomic vst3IsPlaying { 0 }; + float lastScaleFactorReceived = 1.0f; void setupParameters() { @@ -808,6 +809,8 @@ private: : Vst::EditorView (&ec, nullptr), owner (&ec), pluginInstance (p) { + editorScaleFactor = ec.lastScaleFactorReceived; + component.reset (new ContentWrapperComponent (*this, p)); } @@ -853,7 +856,7 @@ private: #endif #if ! JUCE_MAC - setContentScaleFactor ((Steinberg::IPlugViewContentScaleSupport::ScaleFactor) scaleFactor); + setContentScaleFactor ((Steinberg::IPlugViewContentScaleSupport::ScaleFactor) editorScaleFactor); #endif component->resizeHostWindow(); @@ -895,10 +898,15 @@ private: if (component != nullptr) { - auto scale = component->getNativeEditorScaleFactor(); + auto w = rect.getWidth(); + auto h = rect.getHeight(); - component->setSize (roundToInt (rect.getWidth() / scale), - roundToInt (rect.getHeight() / scale)); + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + w = roundToInt (w / editorScaleFactor); + h = roundToInt (h / editorScaleFactor); + #endif + + component->setSize (w, h); if (auto* peer = component->getPeer()) peer->updateBounds(); @@ -915,11 +923,15 @@ private: { if (size != nullptr && component != nullptr) { - auto scale = component->getNativeEditorScaleFactor(); + auto w = component->getWidth(); + auto h = component->getHeight(); - *size = ViewRect (0, 0, - roundToInt (component->getWidth() * scale), - roundToInt (component->getHeight() * scale)); + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + w = roundToInt (w * editorScaleFactor); + h = roundToInt (h * editorScaleFactor); + #endif + + *size = ViewRect (0, 0, w, h); return kResultTrue; } @@ -942,12 +954,14 @@ private: { if (auto* editor = component->pluginEditor.get()) { - // checkSizeConstraint - auto scale = component->getNativeEditorScaleFactor(); - auto scaledRect = (Rectangle::leftTopRightBottom (rectToCheck->left, rectToCheck->top, - rectToCheck->right, rectToCheck->bottom).toFloat() / scale).toNearestInt(); - - auto juceRect = editor->getLocalArea (component.get(), scaledRect); + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + auto juceRect = editor->getLocalArea (component.get(), + Rectangle::leftTopRightBottom (rectToCheck->left, rectToCheck->top, + rectToCheck->right, rectToCheck->bottom) / editorScaleFactor); + #else + auto juceRect = editor->getLocalArea (component.get(), + { rectToCheck->left, rectToCheck->top, rectToCheck->right, rectToCheck->bottom }); + #endif if (auto* constrainer = editor->getConstrainer()) { @@ -963,8 +977,13 @@ private: juceRect = component->getLocalArea (editor, juceRect); - rectToCheck->right = rectToCheck->left + roundToInt (juceRect.getWidth() * scale); - rectToCheck->bottom = rectToCheck->top + roundToInt (juceRect.getHeight() * scale); + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + rectToCheck->right = rectToCheck->left + roundToInt (juceRect.getWidth() * editorScaleFactor); + rectToCheck->bottom = rectToCheck->top + roundToInt (juceRect.getHeight() * editorScaleFactor); + #else + rectToCheck->right = rectToCheck->left + juceRect.getWidth(); + rectToCheck->bottom = rectToCheck->top + juceRect.getHeight(); + #endif } } @@ -978,20 +997,29 @@ private: tresult PLUGIN_API setContentScaleFactor (Steinberg::IPlugViewContentScaleSupport::ScaleFactor factor) override { #if ! JUCE_MAC - scaleFactor = static_cast (factor); + if (! approximatelyEqual ((float) factor, editorScaleFactor)) + { + editorScaleFactor = (float) factor; - if (component == nullptr) - return kResultFalse; + if (auto* o = owner.get()) + o->lastScaleFactorReceived = editorScaleFactor; - #if JUCE_WINDOWS && ! JUCE_WIN_PER_MONITOR_DPI_AWARE - if (auto* ed = component->pluginEditor.get()) - ed->setScaleFactor (scaleFactor); - #else - if (! approximatelyEqual (component->getNativeEditorScaleFactor(), scaleFactor)) - component->nativeScaleFactorChanged ((double) scaleFactor); - #endif + if (component == nullptr) + return kResultFalse; - component->resizeHostWindow(); + #if JUCE_WINDOWS && ! JUCE_WIN_PER_MONITOR_DPI_AWARE + if (auto* ed = component->pluginEditor.get()) + ed->setScaleFactor ((float) factor); + #endif + + component->resizeHostWindow(); + + if (getHostType().isBitwigStudio()) + { + component->setTopLeftPosition (0, 0); + component->repaint(); + } + } return kResultTrue; #else @@ -1012,18 +1040,10 @@ private: //============================================================================== struct ContentWrapperComponent : public Component - #if ! JUCE_MAC - , public ComponentPeer::ScaleFactorListener, - public ComponentMovementWatcher - #endif { ContentWrapperComponent (JuceVST3Editor& editor, AudioProcessor& plugin) - : - #if ! JUCE_MAC - ComponentMovementWatcher (this), - #endif - pluginEditor (plugin.createEditorIfNeeded()), - owner (editor) + : pluginEditor (plugin.createEditorIfNeeded()), + owner (editor) { setOpaque (true); setBroughtToFrontOnMouseClick (true); @@ -1054,12 +1074,6 @@ private: PopupMenu::dismissAllActiveMenus(); pluginEditor->processor.editorBeingDeleted (pluginEditor.get()); } - - #if ! JUCE_MAC - for (int i = 0; i < ComponentPeer::getNumPeers(); ++i) - if (auto* p = ComponentPeer::getPeer (i)) - p->removeScaleFactorListener (this); - #endif } void paint (Graphics& g) override @@ -1091,10 +1105,27 @@ private: } } + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + void checkScaleFactorIsCorrect() + { + if (auto* peer = pluginEditor->getPeer()) + { + auto peerScaleFactor = (float) peer->getPlatformScaleFactor(); + + if (! approximatelyEqual (peerScaleFactor, owner.editorScaleFactor)) + owner.setContentScaleFactor (peerScaleFactor); + } + } + #endif + void resized() override { if (pluginEditor != nullptr) { + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + checkScaleFactorIsCorrect(); + #endif + if (! isResizingParentToFitChild) { lastBounds = getLocalBounds(); @@ -1140,10 +1171,17 @@ private: if (owner.plugFrame != nullptr) { - ViewRect newSize (0, 0, roundToInt (w * nativeScaleFactor), roundToInt (h * nativeScaleFactor)); - isResizingParentToFitChild = true; - owner.plugFrame->resizeView (&owner, &newSize); - isResizingParentToFitChild = false; + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE + w = roundToInt (w * owner.editorScaleFactor); + h = roundToInt (h * owner.editorScaleFactor); + #endif + + ViewRect newSize (0, 0, w, h); + + { + const ScopedValueSetter resizingParentSetter (isResizingParentToFitChild, true); + owner.plugFrame->resizeView (&owner, &newSize); + } #if JUCE_MAC if (host.isWavelab() || host.isReaper()) @@ -1155,49 +1193,6 @@ private: } } - float getNativeEditorScaleFactor() const noexcept { return nativeScaleFactor; } - - #if ! JUCE_MAC - void componentMovedOrResized (bool, bool) override {} - - void componentPeerChanged() override - { - if (auto* peer = getTopLevelComponent()->getPeer()) - peer->addScaleFactorListener (this); - } - - void componentVisibilityChanged() override - { - if (auto* peer = getTopLevelComponent()->getPeer()) - nativeScaleFactor = (float) peer->getPlatformScaleFactor(); - } - - void nativeScaleFactorChanged (double newScaleFactor) override - { - nativeScaleFactor = (float) newScaleFactor; - - auto host = getHostType(); - - if (host.isWavelab()) - { - Timer::callAfterDelay (250, [this] { - if (auto* peer = getPeer()) - { - peer->updateBounds(); - repaint(); - } - - resizeHostWindow(); - }); - } - else if (host.isBitwigStudio()) - { - resizeHostWindow(); - setTopLeftPosition (0, 0); - } - } - #endif - std::unique_ptr pluginEditor; private: @@ -1207,8 +1202,6 @@ private: bool isResizingChildToFitParent = false; bool isResizingParentToFitChild = false; - float nativeScaleFactor = 1.0f; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ContentWrapperComponent) }; @@ -1222,10 +1215,10 @@ private: #if JUCE_MAC void* macHostWindow = nullptr; bool isNSView = false; - #else - float scaleFactor = 1.0f; #endif + float editorScaleFactor = 1.0f; + #if JUCE_WINDOWS WindowsHooks hooks; #endif diff --git a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp index 7bfea5233c..7259a3f03f 100644 --- a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp @@ -3079,6 +3079,10 @@ private: pluginRespondsToDPIChanges = plugin.pluginCanDo ("supportsViewDpiScaling") > 0; + if (pluginRespondsToDPIChanges) + if (auto* peer = getTopLevelComponent()->getPeer()) + setScaleFactorAndDispatchMessage (peer->getPlatformScaleFactor()); + #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE std::unique_ptr dpiDisabler; @@ -3108,9 +3112,6 @@ private: // Install keyboard hooks pluginWantsKeys = (dispatch (Vst2::effKeysRequired, 0, 0, 0, 0) == 0); - if (auto* peer = getTopLevelComponent()->getPeer()) - setScaleFactorAndDispatchMessage (peer->getPlatformScaleFactor()); - #if JUCE_WINDOWS originalWndProc = 0; pluginHWND = GetWindow ((HWND) getWindowHandle(), GW_CHILD); @@ -3147,12 +3148,6 @@ private: auto rw = rect->right - rect->left; auto rh = rect->bottom - rect->top; - if (pluginRespondsToDPIChanges) - { - rw = roundToInt (rw * nativeScaleFactor); - rh = roundToInt (rh * nativeScaleFactor); - } - if ((rw > 50 && rh > 50 && rw < 2000 && rh < 2000 && (! isWithin (w, rw, 2) || ! isWithin (h, rh, 2))) || ((w == 0 && rw > 0) || (h == 0 && rh > 0))) {