From f11a2b2ff1787712dffc7bc1f49ee049a0c1dd63 Mon Sep 17 00:00:00 2001 From: hogliux Date: Mon, 23 May 2016 18:47:39 +0100 Subject: [PATCH] Fix modifier keys in AAX plug-ins on Windows 10 --- .../AAX/juce_AAX_Modifier_Injector.h | 41 +++++++++++++++++++ .../AAX/juce_AAX_Wrapper.cpp | 29 ++++++++++++- .../native/juce_win32_Windowing.cpp | 40 +++++++++++++++++- 3 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 modules/juce_audio_plugin_client/AAX/juce_AAX_Modifier_Injector.h diff --git a/modules/juce_audio_plugin_client/AAX/juce_AAX_Modifier_Injector.h b/modules/juce_audio_plugin_client/AAX/juce_AAX_Modifier_Injector.h new file mode 100644 index 0000000000..db3ae30f6d --- /dev/null +++ b/modules/juce_audio_plugin_client/AAX/juce_AAX_Modifier_Injector.h @@ -0,0 +1,41 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2016 - ROLI Ltd. + + Permission is granted to use this software under the terms of either: + a) the GPL v2 (or any later version) + b) the Affero GPL v3 + + Details of these licenses can be found at: www.gnu.org/licenses + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.juce.com for more information. + + ============================================================================== +*/ + +#ifndef JUCE_AAX_MODIFIER_INJECTOR_H_INCLUDED +#define JUCE_AAX_MODIFIER_INJECTOR_H_INCLUDED + +struct ModifierKeyProvider +{ + virtual ~ModifierKeyProvider() {} + virtual int getWin32Modifiers() const = 0; +}; + +struct ModifierKeyReceiver +{ + virtual ~ModifierKeyReceiver() {} + virtual void setModifierKeyProvider (ModifierKeyProvider* provider) = 0; + virtual void removeModifierKeyProvider () = 0; +}; + +#endif \ No newline at end of file diff --git a/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp b/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp index 0c8a43f63c..5391f63411 100644 --- a/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp @@ -93,6 +93,11 @@ #undef check +namespace juce +{ + #include "juce_AAX_Modifier_Injector.h" +} + const int32_t juceChunkType = 'juce'; const int maxAAXChannels = 8; @@ -328,7 +333,7 @@ struct AAXClasses #endif //============================================================================== - class JuceAAX_GUI : public AAX_CEffectGUI + class JuceAAX_GUI : public AAX_CEffectGUI, public ModifierKeyProvider { public: JuceAAX_GUI() {} @@ -361,6 +366,9 @@ struct AAXClasses { component->setVisible (true); component->addToDesktop (0, nativeViewToAttachTo); + + if (ModifierKeyReceiver* modReceiver = dynamic_cast (component->getPeer())) + modReceiver->setModifierKeyProvider (this); } } } @@ -371,6 +379,9 @@ struct AAXClasses { JUCE_AUTORELEASEPOOL { + if (ModifierKeyReceiver* modReceiver = dynamic_cast (component->getPeer())) + modReceiver->removeModifierKeyProvider(); + component->removeFromDesktop(); component = nullptr; } @@ -414,6 +425,22 @@ struct AAXClasses return AAX_ERROR_NULL_OBJECT; } + int getWin32Modifiers() const override + { + int modifierFlags = 0; + + if (const AAX_IViewContainer* viewContainer = GetViewContainer()) + { + uint32 aaxViewMods = 0; + const_cast(viewContainer)->GetModifiers (&aaxViewMods); + + if ((aaxViewMods & AAX_eModifiers_Shift) != 0) modifierFlags |= ModifierKeys::shiftModifier; + if ((aaxViewMods & AAX_eModifiers_Alt ) != 0) modifierFlags |= ModifierKeys::altModifier; + } + + return modifierFlags; + } + private: //============================================================================== inline int getParamIndexFromID (AAX_CParamID paramID) const noexcept diff --git a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp index e382c9ae81..4da441b855 100644 --- a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp @@ -39,6 +39,10 @@ #define WM_APPCOMMAND 0x0319 #endif +#if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client + #include +#endif + extern void juce_repeatLastProcessPriority(); extern void juce_checkCurrentlyFocusedTopLevelWindow(); // in juce_TopLevelWindow.cpp extern bool juce_isRunningInWine(); @@ -560,7 +564,7 @@ namespace IconConverters } //============================================================================== -class HWNDComponentPeer : public ComponentPeer +class HWNDComponentPeer : public ComponentPeer, public ModifierKeyReceiver { public: enum RenderingEngineType @@ -585,6 +589,9 @@ public: currentWindowIcon (0), dropTarget (nullptr), updateLayeredWindowAlpha (255) + #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client + , modProvider (nullptr) + #endif { callFunctionIfNotLocked (&createWindowCallback, this); @@ -1166,6 +1173,9 @@ private: JuceDropTarget* dropTarget; uint8 updateLayeredWindowAlpha; MultiTouchMapper currentTouches; + #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client + ModifierKeyProvider* modProvider; + #endif //============================================================================== class TemporaryImage : public Timer @@ -1752,6 +1762,11 @@ private: updateKeyModifiers(); + #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client + if (modProvider != nullptr) + currentModifiers = currentModifiers.withFlags (modProvider->getWin32Modifiers()); + #endif + TRACKMOUSEEVENT tme; tme.cbSize = sizeof (tme); tme.dwFlags = TME_LEAVE; @@ -1794,6 +1809,12 @@ private: if (isValidPeer (this)) { updateModifiersFromWParam (wParam); + + #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client + if (modProvider != nullptr) + currentModifiers = currentModifiers.withFlags (modProvider->getWin32Modifiers()); + #endif + isDragging = true; doMouseEvent (position, MouseInputSource::invalidPressure); @@ -1807,6 +1828,12 @@ private: return; updateModifiersFromWParam (wParam); + + #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client + if (modProvider != nullptr) + currentModifiers = currentModifiers.withFlags (modProvider->getWin32Modifiers()); + #endif + const bool wasDragging = isDragging; isDragging = false; @@ -2392,6 +2419,17 @@ private: { } + //============================================================================== + void setModifierKeyProvider (ModifierKeyProvider* provider) override + { + modProvider = provider; + } + + void removeModifierKeyProvider() override + { + modProvider = nullptr; + } + //============================================================================== public: static LRESULT CALLBACK windowProc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)