1.46 1.51 DnD issue

Hi Jules,

I recently upgraded to Juce git tip, and I’m seeing some weird behavior regarding drag n drop.
When receiving a drag n drop, the component receive a mouseDown too.
This didn’t use to happen in 1.46 and do not happen on OSX 1.51 either.

Is this normal ?

It’s sent by the following code in MouseInputSourceInternal::setButtons around line 180

if (buttonState.isAnyMouseButtonDown())
{
  Desktop::getInstance().incrementMouseClickCounter();
  Component* const current = getComponentUnderMouse();
  if (current != 0)
  {
    registerMouseDown (screenPos, time, current);
    sendMouseDown (current, screenPos, time);
  }
}

Thanks,

Do you mean a drag and drop from an external app, or an internal drag?

External App, from the OS Desktop to the juce Window.

I can’t reproduce this in Win7… I’ve not tried Vista, but wouldn’t expect it to be any different (unless it’s some kind of actual bug in Vista that they’ve fixed).

Can you trace it back to an actual incoming win32 event in the platform-specific code?

Here is the stack trace

juce::Component::internalMouseDown(juce::MouseInputSource & source={...}, const juce::Point<int> & relativePos={...}, const juce::Time & time={...})  Line 2338	C++
juce::MouseInputSourceInternal::sendMouseDown(juce::Component * const comp=0x06f84fe0, const juce::Point<int> & screenPos={...}, const __int64 time=1282566200405)  Line 123	C++
juce::MouseInputSourceInternal::setButtons(const juce::Point<int> & screenPos={...}, const __int64 time=1282566200405, const juce::ModifierKeys & newButtonState={...})  Line 187	C++
juce::MouseInputSourceInternal::handleEvent(juce::ComponentPeer * const newPeer=0x0548e370, const juce::Point<int> & positionWithinPeer={...}, const __int64 time=1282566200405, const juce::ModifierKeys & newMods={...})  Line 280	C++
juce::MouseInputSource::handleEvent(juce::ComponentPeer * peer=0x0548e370, const juce::Point<int> & positionWithinPeer={...}, const __int64 time=1282566200405, const juce::ModifierKeys & mods={...})  Line 522	C++
juce::ComponentPeer::handleMouseEvent(const int touchIndex=0, const juce::Point<int> & positionWithinPeer={...}, const juce::ModifierKeys & newMods={...}, const __int64 time=1282566200405)  Line 108	C++
juce::Win32ComponentPeer::doMouseEvent(const juce::Point<int> & position={...})  Line 1222	C++
juce::Win32ComponentPeer::doMouseMove(const juce::Point<int> & position={...})  Line 1258	C++
juce::Win32ComponentPeer::peerWindowProc(HWND__ * h=0x000d03c2, unsigned int message=512, unsigned int wParam=0, long lParam=22413850)  Line 1700	C++
juce::Win32ComponentPeer::windowProc(HWND__ * h=0x000d03c2, unsigned int message=512, unsigned int wParam=0, long lParam=22413850)  Line 1640	C++

WM_MOUSEMOVE is called in the windowProc

imho the problem lies in juce::MouseInputSource::handleEvent
regarding the code
if (isDragging() && newMods.isAnyMouseButtonDown())
isDragging returns false
while newMods.isAnyMouseButtonDown() returns true

so the code is generating the missing mouse down button.

By the way I’m on Windows XP.

Don’t hesitate if you need more info regarding this

Thanks,

I don’t think there’s anything wrong with the MouseInputSource class - if XP sends a mousemove event while the button is held down, then it’s totally reasonable to assume that a click is taking place.

And kind of fix/workaround would have to be in the win32 code, perhaps ignoring mouse moves if there’s a drag operation in progress. Does it happen before or after the handleFileDragDrop callback?

It happens after the drop.
So technically the mouse is no more down otherwise the drop wouldn’t have took place.

I think the problem is that the current modifier containing which button is pressed is not updated after the drop. At least on Windows XP.
Maybe something related to getCurrentModifiersRealtime after the drop might be a solution.

Maybe just something like this?

HRESULT __stdcall Drop (IDataObject* pDataObject, DWORD /*grfKeyState*/, POINTL mousePos, DWORD* pdwEffect) { updateCurrentModifiers(); updateFileList (pDataObject); owner->handleFileDragDrop (files, owner->globalPositionToRelative (Point<int> (mousePos.x, mousePos.y))); *pdwEffect = DROPEFFECT_COPY; return S_OK; }

Ok I’ve found the issue.

I use to call getCurrentModifiersRealtime in my code as I wasn’t able to get the modifers on mac when DnD (like in order to detect a alt + DnD) (in 1.46)
and it looks like getCurrentModifiersRealtime is no more stateless anymore but update the global status.
If I put back getCurrentModifiers is now works fine and it looks like it now works fine on mac too.

So problem solved.

Thanks,

Ah, I see. Thanks for figuring it out. I should probably add a note about it that method not being stateless…