Multiple double clicks


I have a situation here where a double-click should open a window, and in about 20 % of the cases I get not one double-click event but about 17, causing 17 windows to be opened. It’s hard to debug because Visual Studio messes up all the line numbers in juce_amalgamated.cpp (still using JUCE 1.54.20), but the events are definitely being generated deep in the JUCE code… does this sound familiar to anyone? Sorry for not being able to be more specific atm…


Haven’t seen anything like that myself. The logic for the double-click detection is in MouseInputSource::getNumberOfMultipleClicks()

(I don’t recommend the amalgamated stuff any more - it’s much easier to debug if you get the introjucer to just include the non-amalgamated files)


This is the stack trace, which is being repeated over and over again…

> metaplugin.dll!PluginWindow::PluginWindow(juce::Component * const uiComp, juce::AudioProcessorGraph::Node * owner_, const bool isGeneric_) Line 52 C++ metaplugin.dll!PluginWindow::getWindowFor(juce::AudioProcessorGraph::Node * node, bool useGenericView) Line 106 + 0x3b bytes C++ metaplugin.dll!FilterComponent::mouseUp(const juce::MouseEvent & e) Line 331 + 0x10 bytes C++ metaplugin.dll!juce::Component::internalMouseUp(juce::MouseInputSource & source, const juce::Point<int> & relativePos, const juce::Time & time, const juce::ModifierKeys & oldModifiers) Line 43693 + 0x13 bytes C++ metaplugin.dll!juce::MouseInputSourceInternal::sendMouseUp(juce::Component * const comp, const juce::Point<int> & screenPos, const juce::Time & time) Line 8140 + 0x58 bytes C++ metaplugin.dll!juce::MouseInputSourceInternal::setButtons(const juce::Point<int> & screenPos, const juce::Time & time, const juce::ModifierKeys & newButtonState) Line 8172 + 0x46 bytes C++ metaplugin.dll!juce::MouseInputSourceInternal::handleEvent(juce::ComponentPeer * const newPeer, const juce::Point<int> & positionWithinPeer, const juce::Time & time, const juce::ModifierKeys & newMods) Line 8288 + 0x14 bytes C++ metaplugin.dll!juce::MouseInputSource::handleEvent(juce::ComponentPeer * peer, const juce::Point<int> & positionWithinPeer, const __int64 time, const juce::ModifierKeys & mods) Line 8530 + 0x5a bytes C++ metaplugin.dll!juce::ComponentPeer::handleMouseEvent(const int touchIndex, const juce::Point<int> & positionWithinPeer, const juce::ModifierKeys & newMods, const __int64 time) Line 14024 C++ metaplugin.dll!juce::Win32ComponentPeer::doMouseEvent(const juce::Point<int> & position) Line 53548 C++ metaplugin.dll!juce::Win32ComponentPeer::doMouseUp(const juce::Point<int> & position, const unsigned int wParam) Line 53654 C++ metaplugin.dll!juce::Win32ComponentPeer::peerWindowProc(HWND__ * h, unsigned int message, unsigned int wParam, long lParam) Line 54202 + 0x3f bytes C++ metaplugin.dll!juce::Win32ComponentPeer::windowProc(HWND__ * h, unsigned int message, unsigned int wParam, long lParam) Line 54120 + 0x18 bytes C++ user32.dll!76aac4e7() [Frames below may be incorrect and/or missing, no symbols loaded for user32.dll] user32.dll!76aac5e7() user32.dll!76aac590() user32.dll!76aacc19() user32.dll!76aa2e41() reaper.exe!007b7498() metaplugin.dll!AudioEffect::masterIdle() Line 231 + 0x1f bytes C++ metaplugin.dll!JuceVSTWrapper::tryMasterIdle() Line 990 + 0x12 bytes C++ metaplugin.dll!JuceVSTWrapper::timerCallback() Line 977 C++ metaplugin.dll!juce::InternalTimerThread::callTimers() Line 41065 + 0xf bytes C++ metaplugin.dll!juce::InternalTimerThread::handleMessage(const juce::Message & __formal) Line 41082 C++ metaplugin.dll!juce::MessageManager::deliverMessage(juce::Message * const message) Line 40645 + 0x13 bytes C++ metaplugin.dll!juce::WindowsMessageHelpers::messageWndProc(HWND__ * h, juce::Message * const message, const unsigned int wParam, const long lParam) Line 50716 C++ user32.dll!76aac4e7() user32.dll!76aac5e7() user32.dll!76aac590() user32.dll!76aacc19() user32.dll!76aa2e41() reaper.exe!005ce92d()

Seems like a window is created, and then immediately the old mouse event is applied to that new window, and so on…


I can’t really see how that could happen… If you can suggest some code that would make the same thing happen in e.g. the juce demo, I’ll have a go at debugging it, but can’t really see how I could figure it out without actually seeing it for myself.


Seems I got it figured out… in the constructor of the plugin window that is being opened, setVisible(true) was called before the new window was added to the list of already opened windows. However, the fake mouse move event that’s being generated in setVisible sometimes is received faster than that addition, so the whole cycle starts again. This is the same way it’s been done in the JUCE plugin host, but it seems that in a plugin context, the timing can change just enough to make things not work out all the time anymore. I’ve now placed setVisible(true) at the end of the plugin window constructor and haven’t seen this issue any more since…