[squeak-dev] #mouseHold: equivalent in newer images

tim Rowledge tim at rowledge.org
Thu Sep 18 22:10:15 UTC 2014

On 18-09-2014, at 6:51 AM, Bert Freudenberg <bert at freudenbergs.de> wrote:

> On 18.09.2014, at 04:12, tim Rowledge <tim at rowledge.org> wrote:
>> The old Scratch code uses the no longer supported #mouseHold: message to pop up menus if the left button is held down for a while; a bit like the doubleClickTimeout: we have now but not quite.
>> I tried using doubleClickTimeout: but it doesn’t get sent when the first click is held too long if there is a drag selector as well (which seems a bit odd) and it does odd things anyway. I’m looking at #mouseStillDown: now but that looks to be aimed at a different use pattern.
>> Is there an actually working equivalent of the old #mouseHold: ?
> I don't think so. Would be pretty useful to add though (thinking of right-click on touch devices).

I’m not at all sure the best way to add it though. Look at MouseClickEvent>>handleEvent:from: - talk about convoluted. It’s also very old code, so maybe it needs modernising?

So far as I can make out
- if the first click times out, the event is not mouseUp and there is a drag selector, just record the timeout state for the next time around.
- if the first click times out, the event is not mouseUp and there is no drag selector, do a double click timeout AND a click AND cancel the whole wait thing. I’m surprised that the click is sent when the mouse button is still down.
- if the first click ends as the mouse goes up and it’s either timed out or there is no double click selector, do a click and cancel the wait. This actually makes sense…
- if the first click ends as the mouse goes up and we do have a d-click selector or are within the time, advance the state, copy the event, do a click (that part makes sense) and then pass the whole thing back to the hand to reprocess (which makes no sense to me at all) and then return false so that even more stuff gets done as a mouse over event.
- if the first click is followed by enough motion to make a drag, do a double click timeout (why?), cancel the wait, and either do a click (why?) or a drag depending on whether there is a drag selector. I really don’t get that.
Then we get to the second state, where we know that we timed out before the first mouse up - it just gets more complex from there.

In trying to compare the modern process to the old code, it seems we now allow a very long press to still behave as a plain click/drag and as a result it looks pretty difficult to insert a #holdDownALongTime handler. I can see where to put the case - right at the end of the #firstClickTimedOut clause, something like -
	clickState == #firstClickTimedOut ifTrue:[
		localEvt isMouseUp ifTrue:["neither drag nor double click"
			aHand resetClickState.
			self doubleClickTimeout; click. "***"
		isDrag ifTrue:["drag start"
			aHand resetClickState.
			self doubleClickTimeout; drag: firstClickDown. "***"
		"tpr - testing "
		aHand resetClickState.
		clickClient catchTimeoutTest.
BUT that results in not being able to click, hold and then drag after a while, which is a change to current behaviour. Without the resetClickState we’d get continuous sends of the catchTimeoutTest, which isn’t desirable. I guess we could test for a holdDownSelector in the same way that other places in the code do.

We’d need to add an instvar - and handle the possible old versions. Any thoughts? This isn’t something I’m at all expert in.

tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim
Klingon Code Warrior:- 3) "Perhaps it IS a good day to Die!  I say we ship it!"

More information about the Squeak-dev mailing list