Last updated at 7:44 pm UTC on 20 September 2020
An explanation by Andreas Raab of the role of several global variables used in Morphic. The original change set from which which this is quoted may be found on the files.squeak.org server at http://files.squeak.org/updates/3854ActiveGlobals.cs
Preamble to 3854ActiveGlobals.cs:
'From Squeak3.1alpha of 4 February 2001 [latest update: #3862] on 18 March 2001 at 1:57:53 am'!
Change Set: ActiveGlobals
Date: 22 January 2001
Author: Andreas Raab
This change set introduces three dynamic globals for use in Morphic:
ActiveWorld - the world currently in control of handling some event. Usually ActiveWorld is identical with World but for embedded worlds the world will change when event handling reaches the new (inner world) and will be restored when event handling leaves it.
ActiveHand - the hand that issued the event responsible for the current action. In a multi-user setup, this hand identifies which user-incarnation invoked the action. Inbetween event handling cycles the ActiveHand is equivalent to the Worlds primary hand .
ActiveEvent - the event responsible for the current action. Inbetween event handling cycles the ActiveEvent is nil. It is therefore safer to use ActiveHand for code which cannot be sure if it is run outside of event handling cycles (e.g., during stepping) .
The change set establishes the following notions:
- World - is always the outermost world. Never nil when in Morphic.
- ActiveWorld - is always the 'innermost' world control of the current event/step cycle. Never nil when in Morphic.
- ActiveHand - is always the hand controlling the current action. Never nil when in Morphic.
- ActiveEvent - is the event triggering the current action. nil if action was not triggered (neither directly nor indirectly) by a user input event.
Also, the change set introduces HandMorph>>cursorPoint as a dynamic equivalent of Sensor>>cursorPoint when used in embedded worlds. HandMorph>>cursorPoint will transform its position into the currently active world so that a client sees no difference if running in an embedded world. This greatly simplifies matters when we're trying to put up something next to the current mouse (hand) position and allows for a convenient MVC/Morphic compatibility pattern by using:
(ActiveHand ifNil:[Sensor]) cursorPoint.
which can be used in places where MVC compatibility matters and will work correctly even when used in embedded worlds, unless the position of the active hand in its (outer) world is needed (in which case ActiveHand>>position should be used).
 The reason for making the world's primary hand the ActiveHand inbetween cycles is that most simple-minded code will not really care about what hand is returned inbetween event handling cycles. Code that does care can check ActiveEvent to see if it was invoked in a regular event cycle or not.
As an example, the change set fixes various issues due to incorrectly computed z-orders when modal loops were used (such as for FITBM) as a direct response to some event. Since HandMorph can now check if it was invoked inside or outside the event cycle it can re-establish the z-order when a modal loop is detected.