Squeak SmalltalkJoker Squeak Smalltalk : Morphic : prevnext Active Hand instead of Sensor

The problem which has been described previously in this thread ](again)
raises the issue of referring directly to Sensor instead of the hand
while being in Morphic. I could track the problem (thanks for the
description btw) to a TransferMorph which kept stepping all the time
due to an error in the drop handling method (I presume this is what
Ned's fix addresses).
However, the stepping transfer morph is not the "real cause" of the
problem. What is more problematic is the code saying:
TransferMorph>>step
    self shouldCopy: Sensor shiftPressed.
    self updateCopyIcon
It's the use of "Sensor" that screws up as you can see if you simply
open a TransferMorph in the world via "TransferMorph new openInWorld"
(this will expose precisely the same behavior that was described
earlier). Why is this?
Historically, Sensor was (and is) being used to query for "current"
state of the input device (such as in the above #shiftPressed query)
but Morphic assumes that *it* will be able to query for all events
from the Sensor via #nextEvent. In order to reconcile the two regimes
I decided to make Sensor drain the event queue if you issue one of
these requests to Sensor. This decision came from wanting to be able
to write "simple code" such as in the examples where we may use, e.g.,
theWorldsSimplestDrawingProgram
    | canvas lastPt nextPt |
    canvas := Display getCanvas.
    Sensor waitButton.
    lastPt := Sensor cursorPoint.
    [Sensor anyButtonPressed] whileTrue:[
        nextPt := Sensor cursorPoint.
        canvas line: lastPt to: nextPt width: 1 color: Color black.
        lastPt := nextPt.
    ].
The trouble is that you simply cannot write such "simple code" via
Morphic (you would have to make a Morph, add a #mouseDown, #mouseMove,
#mouseUp method etc). If Sensor's behavior would have been made to
report back "the last state known to Morphic" the code wouldn't work
(Sensor would always report the same state since Morphic will not be
able to query new events). At the same time, relaying the events
recorded during this period to Morphic after the code is finished
would lead to lots and lots of weird things happening. That's why
*ANY* request for Sensor state will drain the event queue.
What that means for something like TransferMorph's #step method is that
*all* events which were received before that particular query are being
thrown away. And of course, there may very well be a #mouseUp event in
there which leads to the problems people have been reporting.
The bottom line of this is: If you are programming for Morphic, NEVER,
NEVER use Sensor. DO NOT EVER USE IT! Refer to the hand instead.
Changing TransferMorph>>step to say:
step
    self shouldCopy: ActiveHand shiftPressed.
entirely eliminates that problem (regardless of any error handler).
Again, if you write code for Morphic DO NOT REFER TO SENSOR! It will
just #^_at_! things up.
Cheers,
  - Andreas

Depending on what you want to teach people you may go about this in
either of two ways. If you are only interested in Morphic, you should
*always* refer to ActiveHand - this is the only reliable way by which
to query Morphic input state.
If you are interested in dual Morphic/MVC stuff "the right way" to
refer to "current I/O state" is by applying a pattern which says:
    (ActiveHand ifNil:[Sensor]) cursorPoint.
ActiveHand *will* be nil for MVC so this is the safe and recommended
way to deal with it. And yes, it looks ugly but that's what you get
from incomplete paradigm shifts...