[Bug report] Component::mouseDrag() gets called on every click


#1

[Bug report] Component::mouseDrag() now gets called on every click, even if no dragging occurs.

This bug has been introduced in commit a3426aa (2015 11 02, by Jules).

 

The source of trouble:

In MouseInputSourceInternal::handleEvent ()

setScreenPos (screenPos, time, pressureChanged);

gets called. Before that commit it was

setScreenPos (screenPos, time, false);

pressureChanged is set by

const bool pressureChanged = (pressure != newPressure);

I haven't wrapped my head around the newly introduced pressure handling in the MouseInputSource yet, but it seems like a conventional mouse click emmits a pressure change from 0.0f to 1.0f. This should not trigger a mouseDrag().


#2

Why do you call that a "bug"?

Any component should expect to deal with an arbitrary number of drag events. If your code can't deal with one extra event then it must be pretty fragile (?)


#3

We use mouseDrag() to distinguish between normal clicks (where for example an editor is opened in mouseUp()) and drags (where a value might be changed by dragging).
Of course, one can check for the dragged distance instead of simply checking whether mouseDrag() was called but it at least breaks existing code in a way that’s rather error prone to fix.


#4

Did you see that there's a method MouseEvent::mouseWasClicked() which is designed with exactly that purpose? It detects whether the mouse was dragged a significant distance, or held down for a significant time, and it's what I use everywhere that I need to distinguish a drag from a click.


#5

Sorry Jules for calling this change of behaviour a bug, I didn't intend to be offensive at all.
Since the behaviour changed but the documentation didn't, I assumed this wasn't intended, i.e. a bug.

Like ckk I have been using mouseDrag() to distinguish between a drag and a click until now. I will start using MouseEvent::mouseWasClicked() instead. Thank you for the hint!

May I suggest to adapt the documentation of Component::mouseDrag()? At the moment it states

Called when the mouse is moved while a button is held down.

When a mouse button is pressed inside a component, that component receives mouseDrag callbacks each time the mouse moves, even if the mouse strays outside the component's bounds.

This does not reflect its behaviour anymore. It also gets called without any mouse movement.
Would be a good place to mention MouseEvent::mouseWasClicked() as well.


#6

I indeed missed this. On other occasions where I needed to detect dragging/clicking I probably didn’t look for something else as the implementation using mouseDrag() worked.

I just checked with the current code but from what I see and contrary to how I understood the first post, nothing changed in the behavior on Windows; i.e. mouseDrag is called when dragged but not by a single click.

Does this only affect OS X or did I misunderstand the first post?


#7

I didn't take it as offensive, don't worry! Would take a lot more than that to offend me! :)

It's a fair point about the behaviour change, but it's probably good that you hit this, because if you treat a 1-pixel movement (actually less than 1 pixel on high-res devices) as your test, then you're going to provide a terrible experience on devices like graphics tablets or some mice where they're continuously moving. People will struggle to keep them still enough to trigger a click. That's why I don't see it as a problem for this to have changed, as any robust software should be fine with an extra few drag events.


#8

I think it's just because of the new touch-force stuff, so a pressure change will be generating the event. So mainly OSX though it's also supported on Windows pen-input devices


#9

just got fried by this one :-)

I didn't spot it initially because I was testing on Windows where mouseDrag() is not called for a simple click. Then was puzzled for a while why the Mac version didn't work

Anyhow, not a big issue - thanks for the :mouseWasClicked() tip