moved event dispatching code to view (where it belongs)
authorClaus Gittinger <cg@exept.de>
Thu, 21 May 1998 01:58:25 +0200
changeset 2126 1f108c76dfdb
parent 2125 664f8101c8d2
child 2127 c6d63c47bf07
moved event dispatching code to view (where it belongs)
DSurface.st
DevWorkst.st
DeviceWorkstation.st
DisplaySurface.st
KeybdFwd.st
KeyboardForwarder.st
SWSensor.st
SynchronousWindowSensor.st
WEvent.st
WGroup.st
WSensor.st
WindowEvent.st
WindowGroup.st
WindowSensor.st
--- a/DSurface.st	Wed May 20 21:56:14 1998 +0200
+++ b/DSurface.st	Thu May 21 01:58:25 1998 +0200
@@ -884,6 +884,228 @@
     self enableEvent:#pointerMotion
 ! !
 
+!DisplaySurface methodsFor:'event dispatching'!
+
+dispatchEvent:event
+    "dispatch the event"
+
+    self 
+        dispatchEvent:event type
+        arguments:(event arguments)
+        withFocusOn:nil
+        delegate:true
+
+    "Modified: / 20.5.1998 / 23:01:15 / cg"
+!
+
+dispatchEvent:type arguments:arguments
+    ^ self 
+        dispatchEvent:type 
+        arguments:arguments 
+        withFocusOn:nil 
+        delegate:true
+
+    "Modified: / 20.5.1998 / 22:50:31 / cg"
+!
+
+dispatchEvent:type arguments:argArray withFocusOn:focusView delegate:doDelegate
+    "dispatch the event represented by type and arguments either to my delegate,
+     or to my controller (which may be myself, if I implement the controller functionality myself). 
+     If focusView is nonNil, and it is a keyboard event, it is forwarded to this
+     view (but not if there was a delegate in the first place).
+
+     If doDelegate is true, keyboard and button events are forwarded to a
+     delegate object (if non-nil). DoDelegate may be passed as true, to
+     handle events which are already delegated.
+     If there is a delegate, only messages which are understood by it are 
+     forwarded. Also, the delegate is asked if it is willing to handle the event
+     before.
+     Delegated messages get the original view as an extra argument.
+     Delegation has higher priority than both controller or focusView 
+     forwarding."
+
+    |delegate selector delegateMessage delegateQuery 
+     eventReceiver controller deviceMessage
+     isKeyEvent isButtonEvent isPointerEvent trans
+     rect x y w h|
+
+    isKeyEvent := isButtonEvent := isPointerEvent := false.
+
+    type == #damage ifTrue:[
+        self shown ifTrue:[
+            rect := argArray.
+            x := rect left.
+            y := rect top.
+            w := rect width.
+            h := rect height.
+            transformation notNil ifTrue:[
+                self deviceExposeX:x y:y width:w height:h
+            ] ifFalse:[
+                self exposeX:x y:y width:w height:h
+            ]
+        ].
+        ^ self
+    ].
+
+    (type == #'keyPress:x:y:') ifTrue:[
+        isKeyEvent := true.
+        deviceMessage := #'deviceKeyPress:x:y:'.
+        delegateMessage := #'keyPress:x:y:view:'.
+        delegateQuery := #'handlesKeyPress:inView:'.
+    ] ifFalse:[ (type == #'keyRelease:x:y:') ifTrue:[
+        isKeyEvent := true.
+        deviceMessage := #'deviceKeyRelease:x:y:'.
+        delegateMessage := #'keyRelease:x:y:view:'.
+        delegateQuery := #'handlesKeyRelease:inView:'.
+    ] ifFalse:[ (type == #'buttonMotion:x:y:') ifTrue:[
+        isButtonEvent := true.
+        deviceMessage := #'deviceButtonMotion:x:y:'.
+        delegateMessage := #'buttonMotion:x:y:view:'.
+        delegateQuery := #'handlesButtonMotion:inView:'.
+    ] ifFalse:[ (type == #'buttonPress:x:y:') ifTrue:[
+        isButtonEvent := true.
+        deviceMessage := #'deviceButtonPress:x:y:'.
+        delegateMessage := #'buttonPress:x:y:view:'.
+        delegateQuery := #'handlesButtonPress:inView:'.
+    ] ifFalse:[ (type == #'buttonRelease:x:y:') ifTrue:[
+        isButtonEvent := true.
+        deviceMessage := #'deviceButtonRelease:x:y:'.
+        delegateMessage := #'buttonRelease:x:y:view:'.
+        delegateQuery := #'handlesButtonRelease:inView:'.
+    ] ifFalse:[ (type == #'buttonShiftPress:x:y:') ifTrue:[
+        isButtonEvent := true.
+        deviceMessage := #'deviceButtonShiftPress:x:y:'.
+        delegateMessage := #'buttonShiftPress:x:y:view:'.
+        delegateQuery := #'handlesButtonShiftPress:inView:'.
+    ] ifFalse:[ (type == #'buttonMultiPress:x:y:') ifTrue:[
+        isButtonEvent := true.
+        deviceMessage := #'deviceButtonMultiPress:x:y:'.
+        delegateMessage := #'buttonMultiPress:x:y:view:'.
+        delegateQuery := #'handlesButtonMultiPress:inView:'.
+    ] ifFalse:[ (type == #'pointerEnter:x:y:') ifTrue:[
+        isPointerEvent := true.
+        deviceMessage := #'devicePointerEnter:x:y:'.
+        delegateMessage := #'pointerEnter:x:y:view:'.
+        delegateQuery := #'handlesPointerEnter:inView:'.
+    ] ifFalse:[ (type == #'pointerLeave:') ifTrue:[
+        isPointerEvent := true.
+        deviceMessage := type.
+        delegateMessage := #'pointerLeave:view:'.
+        delegateQuery := #'handlesPointerLeave:inView:'.
+    ] ifFalse:[ (type == #'exposeX:y:width:height:') ifTrue:[
+        deviceMessage := #'deviceExposeX:y:width:height:'.
+    ] ifFalse:[ (type == #'graphicsExposeX:y:width:height:final:') ifTrue:[
+        deviceMessage := #'deviceGraphicsExposeX:y:width:height:final:'.
+    ]]]]]]]]]]].
+
+    "
+     if there is a focusView, and its a keyboard event, pass it
+     to that view (or its controller, or its delegate). 
+     In this case, a coordinate which is outside of
+     the focusView (0 @ 0) is passed as x/y coordinates.
+    "
+    (focusView notNil 
+    and:[isKeyEvent]) ifTrue:[
+        focusView 
+            dispatchEvent:type 
+            arguments:(Array with:(argArray at:1) with:0 with:0)
+            withFocusOn:nil
+            delegate:doDelegate.
+        ^ self
+    ].
+
+    doDelegate ifTrue:[
+        "
+         handle delegated messages
+        "
+        (isKeyEvent 
+         or:[isButtonEvent 
+         or:[isPointerEvent]]) ifTrue:[
+            delegate := self delegate.
+
+            "
+             what a kludge - sending to delegate requires
+             another selector and an additional argument ...
+            "
+            (delegate notNil
+            and:[delegate respondsTo:delegateMessage]) ifTrue:[
+                "
+                 is the delegate interested in that event ?
+                 (if it does not respond to the handlesXXX message,
+                  we assume: NO)
+                "
+                ((delegate respondsTo:delegateQuery) 
+                and:[delegate perform:delegateQuery with:(argArray at:1) with:self]) ifTrue:[
+                    "
+                     mhmh ... have to convert to logical coordinates
+                    "        
+                    transformation notNil ifTrue:[
+                        argArray size > 2 ifTrue:[
+                            argArray at:2 put:(trans applyInverseToX:(argArray at:2)).
+                            argArray at:3 put:(trans applyInverseToY:(argArray at:3)).
+                        ].
+                    ].
+                    argArray isNil ifTrue:[
+                        delegate perform:delegateMessage with:self
+                    ] ifFalse:[
+                        delegate perform:delegateMessage withArguments:(argArray copyWith:self)
+                    ].
+                    ^ self
+                ]
+            ].
+        ].
+    ].
+
+    (isKeyEvent 
+     or:[isButtonEvent 
+     or:[isPointerEvent]]) ifTrue:[
+        realized ifFalse:[
+            ^ self
+        ]
+    ].
+
+    "
+     if there is a controller, that one gets all user events
+    "
+    eventReceiver := self.
+    (controller := self controller) notNil ifTrue:[  
+        (isKeyEvent 
+         or:[isButtonEvent 
+         or:[isPointerEvent
+         or:[(type == #focusIn)
+         or:[(type == #focusOut)]]]]) ifTrue:[
+            eventReceiver := controller.
+        ]
+    ].
+
+    "
+     finally, another one:
+     if I have a transformation, edit the selector from #foo to #deviceFoo...
+     This allows for the event to be handled either in device or
+     logical coordinates. (since the deviceFoo-messages default implementation
+     in DisplaySurface translates and resends).
+     Actually, I could always send deviceXXX without speed penalty
+     (event sending is no high frequency operation), but that just adds 
+     another context to any debuggers walkback, making things less clear.
+    "
+    selector := type.
+
+    transformation notNil ifTrue:[
+        (isKeyEvent
+         or:[isButtonEvent
+         or:[isPointerEvent
+         or:[(type == #'exposeX:y:width:height:')
+         or:[(type == #'graphicsExposeX:y:width:height:final:')]]]]) ifTrue:[
+            selector := deviceMessage
+        ]        
+    ].
+
+    eventReceiver perform:selector withArguments:argArray
+
+    "Modified: / 31.10.1997 / 19:54:28 / cg"
+    "Created: / 20.5.1998 / 22:46:25 / cg"
+! !
+
 !DisplaySurface methodsFor:'event handling'!
 
 activateMenu
@@ -1232,199 +1454,6 @@
     "Modified: 14.10.1996 / 22:26:35 / stefan"
 !
 
-dispatchEvent:event
-    "dispatch an event the views controller or the receiver itself.
-     This is the main event handling entry; 
-     however, for backward compatibility (and your convenience), 
-     this dispatches to specialized event handlers 
-     (such as keyPress/buttonPress etc.)"
-
-    |type argArray
-     delegate selector delegateMessage delegateQuery 
-     eventReceiver controller deviceMessage
-     isKeyEvent isButtonEvent isPointerEvent trans
-     rect x y w h|
-
-    type := event type.
-    argArray := event arguments.
-
-    isKeyEvent := isButtonEvent := isPointerEvent := false.
-
-    type == #damage ifTrue:[
-        self shown ifTrue:[
-            rect := argArray.
-            x := rect left.
-            y := rect top.
-            w := rect width.
-            h := rect height.
-            transformation notNil ifTrue:[
-                self deviceExposeX:x y:y width:w height:h
-            ] ifFalse:[
-                self exposeX:x y:y width:w height:h
-            ]
-        ].
-        ^ self
-    ].
-
-    (type == #'keyPress:x:y:') ifTrue:[
-        isKeyEvent := true.
-        deviceMessage := #'deviceKeyPress:x:y:'.
-        delegateMessage := #'keyPress:x:y:view:'.
-        delegateQuery := #'handlesKeyPress:inView:'.
-    ] ifFalse:[ (type == #'keyRelease:x:y:') ifTrue:[
-        isKeyEvent := true.
-        deviceMessage := #'deviceKeyRelease:x:y:'.
-        delegateMessage := #'keyRelease:x:y:view:'.
-        delegateQuery := #'handlesKeyRelease:inView:'.
-    ] ifFalse:[ (type == #'buttonMotion:x:y:') ifTrue:[
-        isButtonEvent := true.
-        deviceMessage := #'deviceButtonMotion:x:y:'.
-        delegateMessage := #'buttonMotion:x:y:view:'.
-        delegateQuery := #'handlesButtonMotion:inView:'.
-    ] ifFalse:[ (type == #'buttonPress:x:y:') ifTrue:[
-        isButtonEvent := true.
-        deviceMessage := #'deviceButtonPress:x:y:'.
-        delegateMessage := #'buttonPress:x:y:view:'.
-        delegateQuery := #'handlesButtonPress:inView:'.
-    ] ifFalse:[ (type == #'buttonRelease:x:y:') ifTrue:[
-        isButtonEvent := true.
-        deviceMessage := #'deviceButtonRelease:x:y:'.
-        delegateMessage := #'buttonRelease:x:y:view:'.
-        delegateQuery := #'handlesButtonRelease:inView:'.
-    ] ifFalse:[ (type == #'buttonShiftPress:x:y:') ifTrue:[
-        isButtonEvent := true.
-        deviceMessage := #'deviceButtonShiftPress:x:y:'.
-        delegateMessage := #'buttonShiftPress:x:y:view:'.
-        delegateQuery := #'handlesButtonShiftPress:inView:'.
-    ] ifFalse:[ (type == #'buttonMultiPress:x:y:') ifTrue:[
-        isButtonEvent := true.
-        deviceMessage := #'deviceButtonMultiPress:x:y:'.
-        delegateMessage := #'buttonMultiPress:x:y:view:'.
-        delegateQuery := #'handlesButtonMultiPress:inView:'.
-    ] ifFalse:[ (type == #'pointerEnter:x:y:') ifTrue:[
-        isPointerEvent := true.
-        deviceMessage := #'devicePointerEnter:x:y:'.
-        delegateMessage := #'pointerEnter:x:y:view:'.
-        delegateQuery := #'handlesPointerEnter:inView:'.
-    ] ifFalse:[ (type == #'pointerLeave:') ifTrue:[
-        isPointerEvent := true.
-        deviceMessage := type.
-        delegateMessage := #'pointerLeave:view:'.
-        delegateQuery := #'handlesPointerLeave:inView:'.
-    ] ifFalse:[ (type == #'exposeX:y:width:height:') ifTrue:[
-        deviceMessage := #'deviceExposeX:y:width:height:'.
-    ] ifFalse:[ (type == #'graphicsExposeX:y:width:height:final:') ifTrue:[
-        deviceMessage := #'deviceGraphicsExposeX:y:width:height:final:'.
-    ]]]]]]]]]]].
-
-"/    "
-"/     if there is a focusView, and its a keyboard event, pass it
-"/     to that view (or its controller, or its delegate). 
-"/     In this case, a coordinate which is outside of
-"/     the focusView (0 @ 0) is passed as x/y coordinates.
-"/    "
-"/    (focusView notNil 
-"/    and:[isKeyEvent]) ifTrue:[
-"/        self sendEvent:type 
-"/             arguments:(Array with:(argArray at:1) with:0 with:0)
-"/             view:focusView 
-"/             withFocusOn:nil
-"/             delegate:doDelegate.
-"/        ^ self
-"/    ].
-
-"/    doDelegate ifTrue:[
-"/        "
-"/         handle delegated messages
-"/        "
-"/        (isKeyEvent 
-"/         or:[isButtonEvent 
-"/         or:[isPointerEvent]]) ifTrue:[
-"/            delegate := view delegate.
-"/
-"/            "
-"/             what a kludge - sending to delegate requires
-"/             another selector and an additional argument ...
-"/            "
-"/            (delegate notNil
-"/            and:[delegate respondsTo:delegateMessage]) ifTrue:[
-"/                "
-"/                 is the delegate interested in that event ?
-"/                 (if it does not respond to the handlesXXX message,
-"/                  we assume: NO)
-"/                "
-"/                ((delegate respondsTo:delegateQuery) 
-"/                and:[delegate perform:delegateQuery with:(argArray at:1) with:view]) ifTrue:[
-"/                    "
-"/                     mhmh ... have to convert to logical coordinates
-"/                    "        
-"/                    (trans := view transformation) notNil ifTrue:[
-"/                        argArray size > 2 ifTrue:[
-"/                            argArray at:2 put:(trans applyInverseToX:(argArray at:2)).
-"/                            argArray at:3 put:(trans applyInverseToY:(argArray at:3)).
-"/                        ].
-"/                    ].
-"/                    argArray isNil ifTrue:[
-"/                        delegate perform:delegateMessage with:view
-"/                    ] ifFalse:[
-"/                        delegate perform:delegateMessage withArguments:(argArray copyWith:view)
-"/                    ].
-"/                    ^ self
-"/                ]
-"/            ].
-"/        ].
-"/    ].
-
-    (isKeyEvent 
-     or:[isButtonEvent 
-     or:[isPointerEvent]]) ifTrue:[
-        self realized ifFalse:[
-            ^ self
-        ]
-    ].
-
-    "
-     if there is a controller, that one gets all user events
-    "
-    eventReceiver := self.
-    controller notNil ifTrue:[  
-        (isKeyEvent 
-         or:[isButtonEvent 
-         or:[isPointerEvent
-         or:[(type == #focusIn)
-         or:[(type == #focusOut)]]]]) ifTrue:[
-            eventReceiver := controller.
-        ]
-    ].
-
-    "
-     finally, another one:
-     if the view has a transformation, edit the selector
-     from #foo to #deviceFoo...
-     This allows the view to handle the event either in device or
-     logical coordinates. (since the deviceFoo-messages default implementation
-     in DisplaySurface translates and resends).
-     Actually, I could always send deviceXXX without speed penalty
-     (event sending is no high frequency operation), but that just adds 
-     another context to any debuggers walkback, making things less clear.
-    "
-    selector := type.
-
-    transformation notNil ifTrue:[
-        (isKeyEvent
-         or:[isButtonEvent
-         or:[isPointerEvent
-         or:[(type == #'exposeX:y:width:height:')
-         or:[(type == #'graphicsExposeX:y:width:height:final:')]]]]) ifTrue:[
-            selector := deviceMessage
-        ]        
-    ].
-
-    eventReceiver perform:selector withArguments:argArray
-
-    "Modified: 21.8.1997 / 19:49:42 / cg"
-!
-
 exposeX:x y:y width:w height:h
     "an expose event - nothing done here"
 
@@ -1958,5 +1987,5 @@
 !DisplaySurface class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/Attic/DSurface.st,v 1.37 1998-04-22 10:57:25 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/Attic/DSurface.st,v 1.38 1998-05-20 23:54:17 cg Exp $'
 ! !
--- a/DevWorkst.st	Wed May 20 21:56:14 1998 +0200
+++ b/DevWorkst.st	Thu May 21 01:58:25 1998 +0200
@@ -2963,20 +2963,24 @@
     |sensor|
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor buttonMotion:button x:x y:y view:aView
+        sensor buttonMotion:button x:x y:y view:aView
     ] ifFalse:[
-	aView shown ifTrue:[ "/ could be a late event arrival
-	    "
-	     if there is no sensor ...
-	    "
-	    WindowEvent
-		sendEvent:#buttonMotion:x:y:
-		arguments:(Array with:button with:x with:y)
-		view:aView
-	]
+        aView shown ifTrue:[ "/ could be a late event arrival
+            "
+             if there is no sensor ...
+            "
+            aView
+                dispatchEvent:#buttonMotion:x:y:
+                arguments:(Array with:button with:x with:y)
+
+"/            WindowEvent
+"/                sendEvent:#buttonMotion:x:y:
+"/                arguments:(Array with:button with:x with:y)
+"/                view:aView
+        ]
     ]
 
-    "Modified: 26.2.1997 / 15:02:18 / cg"
+    "Modified: / 20.5.1998 / 22:50:32 / cg"
 !
 
 buttonMultiPress:button x:x y:y view:aView
@@ -2985,20 +2989,24 @@
     |sensor|
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor buttonMultiPress:button x:x y:y view:aView
+        sensor buttonMultiPress:button x:x y:y view:aView
     ] ifFalse:[
-	aView shown ifTrue:[ "/ could be a late event arrival
-	    "
-	     if there is no sensor ...
-	    "
-	    WindowEvent
-		sendEvent:#buttonMultiPress:x:y:
-		arguments:(Array with:button with:x with:y)
-		view:aView
-	]
+        aView shown ifTrue:[ "/ could be a late event arrival
+            "
+             if there is no sensor ...
+            "
+            aView
+                dispatchEvent:#buttonMultiPress:x:y:
+                arguments:(Array with:button with:x with:y)
+
+"/            WindowEvent
+"/                sendEvent:#buttonMultiPress:x:y:
+"/                arguments:(Array with:button with:x with:y)
+"/                view:aView
+        ]
     ]
 
-    "Modified: 26.2.1997 / 15:02:29 / cg"
+    "Modified: / 20.5.1998 / 22:50:49 / cg"
 !
 
 buttonPress:button x:x y:y view:aView
@@ -3007,20 +3015,24 @@
     |sensor|
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor buttonPress:button x:x y:y view:aView
+        sensor buttonPress:button x:x y:y view:aView
     ] ifFalse:[
-	aView shown ifTrue:[ "/ could be a late event arrival
-	    "
-	     if there is no sensor ...
-	    "
-	    WindowEvent
-		sendEvent:#buttonPress:x:y:
-		arguments:(Array with:button with:x with:y)
-		view:aView
-	]
+        aView shown ifTrue:[ "/ could be a late event arrival
+            "
+             if there is no sensor ...
+            "
+            aView
+                dispatchEvent:#buttonPress:x:y:
+                arguments:(Array with:button with:x with:y)
+
+"/            WindowEvent
+"/                sendEvent:#buttonPress:x:y:
+"/                arguments:(Array with:button with:x with:y)
+"/                view:aView
+        ]
     ]
 
-    "Modified: 26.2.1997 / 15:02:42 / cg"
+    "Modified: / 20.5.1998 / 22:51:02 / cg"
 !
 
 buttonRelease:button x:x y:y view:aView
@@ -3029,20 +3041,24 @@
     |sensor|
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor buttonRelease:button x:x y:y view:aView
+        sensor buttonRelease:button x:x y:y view:aView
     ] ifFalse:[
-	aView shown ifTrue:[ "/ could be a late event arrival
-	    "
-	     if there is no sensor ...
-	    "
-	    WindowEvent
-		sendEvent:#buttonRelease:x:y:
-		arguments:(Array with:button with:x with:y)
-		view:aView
-	]
+        aView shown ifTrue:[ "/ could be a late event arrival
+            "
+             if there is no sensor ...
+            "
+            aView
+                dispatchEvent:#buttonRelease:x:y:
+                arguments:(Array with:button with:x with:y)
+
+"/            WindowEvent
+"/                sendEvent:#buttonRelease:x:y:
+"/                arguments:(Array with:button with:x with:y)
+"/                view:aView
+        ]
     ]
 
-    "Modified: 26.2.1997 / 15:02:52 / cg"
+    "Modified: / 20.5.1998 / 22:51:13 / cg"
 !
 
 configureX:x y:y width:w height:h view:aView
@@ -3096,16 +3112,22 @@
     |sensor|
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor exposeX:x y:y width:w height:h view:aView
+        sensor exposeX:x y:y width:w height:h view:aView
     ] ifFalse:[
-	"
-	 if there is no sensor ...
-	"
-	WindowEvent
-	    sendEvent:#exposeX:y:width:height:
-	    arguments:(Array with:x with:y with:w with:h)
-	    view:aView
+        "
+         if there is no sensor ...
+        "
+        aView
+            dispatchEvent:#exposeX:y:width:height:
+            arguments:(Array with:x with:y with:w with:h)
+
+"/        WindowEvent
+"/            sendEvent:#exposeX:y:width:height:
+"/            arguments:(Array with:x with:y with:w with:h)
+"/            view:aView
     ]
+
+    "Modified: / 20.5.1998 / 22:51:31 / cg"
 !
 
 focusInView:aView
@@ -3114,16 +3136,22 @@
     |sensor|
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor focusInView:aView
+        sensor focusInView:aView
     ] ifFalse:[
-	"
-	 if there is no sensor ...
-	"
-	WindowEvent
-	    sendEvent:#focusIn
-	    arguments:nil
-	    view:aView
+        "
+         if there is no sensor ...
+        "
+        aView
+            dispatchEvent:#focusIn
+            arguments:nil
+
+"/        WindowEvent
+"/            sendEvent:#focusIn
+"/            arguments:nil
+"/            view:aView
     ]
+
+    "Modified: / 20.5.1998 / 22:51:48 / cg"
 !
 
 focusOutView:aView 
@@ -3132,16 +3160,22 @@
     |sensor|
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor focusOutView:aView
+        sensor focusOutView:aView
     ] ifFalse:[
-	"
-	 if there is no sensor ...
-	"
-	WindowEvent
-	    sendEvent:#focusOut
-	    arguments:nil
-	    view:aView
+        "
+         if there is no sensor ...
+        "
+        aView
+            dispatchEvent:#focusOut
+            arguments:nil
+
+"/        WindowEvent
+"/            sendEvent:#focusOut
+"/            arguments:nil
+"/            view:aView
     ]
+
+    "Modified: / 20.5.1998 / 22:51:58 / cg"
 !
 
 graphicsExposeX:x y:y width:w height:h final:final view:aView
@@ -3150,16 +3184,22 @@
     |sensor|
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor graphicsExposeX:x y:y width:w height:h final:final view:aView
+        sensor graphicsExposeX:x y:y width:w height:h final:final view:aView
     ] ifFalse:[
-	"
-	 if there is no sensor ...
-	"
-	WindowEvent
-	    sendEvent:#graphicsExposeX:y:width:height:final:
-	    arguments:(Array with:x with:y with:w with:h with:final)
-	    view:aView
+        "
+         if there is no sensor ...
+        "
+        aView
+            dispatchEvent:#graphicsExposeX:y:width:height:final:
+            arguments:(Array with:x with:y with:w with:h with:final)
+
+"/        WindowEvent
+"/            sendEvent:#graphicsExposeX:y:width:height:final:
+"/            arguments:(Array with:x with:y with:w with:h with:final)
+"/            view:aView
     ]
+
+    "Modified: / 20.5.1998 / 22:52:16 / cg"
 !
 
 keyPress:untranslatedKey x:x y:y view:aView
@@ -3173,32 +3213,36 @@
     "/ ctrl-Esc gives up focus
     "/
     untranslatedKey == #Escape ifTrue:[
-	ctrlDown ifTrue:[
-	    self ungrabPointer.
-	    self setInputFocusTo:nil 
-	]
+        ctrlDown ifTrue:[
+            self ungrabPointer.
+            self setInputFocusTo:nil 
+        ]
     ].
 
     self modifierKeyProcessing:untranslatedKey down:true.
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor keyPress:untranslatedKey x:x y:y view:aView
+        sensor keyPress:untranslatedKey x:x y:y view:aView
     ] ifFalse:[
-	aView shown ifTrue:[ "/ could be a late event arrival
-	    "
-	     if there is no sensor ...
-	    "
-	    xlatedKey := self translateKey:untranslatedKey.
-	    xlatedKey notNil ifTrue:[
-		WindowEvent
-		  sendEvent:#keyPress:x:y:
-		  arguments:(Array with:xlatedKey with:x with:y)
-		  view:aView
-	    ]
-	]
+        aView shown ifTrue:[ "/ could be a late event arrival
+            "
+             if there is no sensor ...
+            "
+            xlatedKey := self translateKey:untranslatedKey.
+            xlatedKey notNil ifTrue:[
+                aView
+                    dispatchEvent:#keyPress:x:y:
+                    arguments:(Array with:xlatedKey with:x with:y)
+
+"/                WindowEvent
+"/                  sendEvent:#keyPress:x:y:
+"/                  arguments:(Array with:xlatedKey with:x with:y)
+"/                  view:aView
+            ]
+        ]
     ]
 
-    "Modified: 26.2.1997 / 15:03:28 / cg"
+    "Modified: / 20.5.1998 / 22:52:36 / cg"
 !
 
 keyRelease:untranslatedKey x:x y:y view:aView
@@ -3209,23 +3253,27 @@
     self modifierKeyProcessing:untranslatedKey down:false.
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor keyRelease:untranslatedKey x:x y:y view:aView
+        sensor keyRelease:untranslatedKey x:x y:y view:aView
     ] ifFalse:[
-	aView shown ifTrue:[ "/ could be a late event arrival
-	    "
-	     if there is no sensor ...
-	    "
-	    xlatedKey := self translateKey:untranslatedKey.
-	    xlatedKey notNil ifTrue:[
-		WindowEvent
-		    sendEvent:#keyRelease:x:y:
-		    arguments:(Array with:xlatedKey with:x with:y)
-		    view:aView
-	    ]
-	]
+        aView shown ifTrue:[ "/ could be a late event arrival
+            "
+             if there is no sensor ...
+            "
+            xlatedKey := self translateKey:untranslatedKey.
+            xlatedKey notNil ifTrue:[
+                aView
+                    dispatchEvent:#keyRelease:x:y:
+                    arguments:(Array with:xlatedKey with:x with:y)
+
+"/                WindowEvent
+"/                    sendEvent:#keyRelease:x:y:
+"/                    arguments:(Array with:xlatedKey with:x with:y)
+"/                    view:aView
+            ]
+        ]
     ]
 
-    "Modified: 26.2.1997 / 15:03:40 / cg"
+    "Modified: / 20.5.1998 / 22:52:52 / cg"
 !
 
 mappedView:aView
@@ -3264,16 +3312,22 @@
     |sensor|
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor pointerEnter:buttonState x:x y:y view:aView
+        sensor pointerEnter:buttonState x:x y:y view:aView
     ] ifFalse:[
-	"
-	 if there is no sensor ...
-	"
-	WindowEvent
-	    sendEvent:#pointerEnter:x:y:
-	    arguments:(Array with:buttonState with:x with:y)
-	    view:aView
+        "
+         if there is no sensor ...
+        "
+        aView
+            dispatchEvent:#pointerEnter:x:y:
+            arguments:(Array with:buttonState with:x with:y)
+
+"/        WindowEvent
+"/            sendEvent:#pointerEnter:x:y:
+"/            arguments:(Array with:buttonState with:x with:y)
+"/            view:aView
     ]
+
+    "Modified: / 20.5.1998 / 22:53:13 / cg"
 !
 
 pointerLeave:buttonState view:aView
@@ -3282,16 +3336,22 @@
     |sensor|
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor pointerLeave:buttonState view:aView
+        sensor pointerLeave:buttonState view:aView
     ] ifFalse:[
-	"
-	 if there is no sensor ...
-	"
-	WindowEvent
-	    sendEvent:#pointerLeave:
-	    arguments:(Array with:buttonState)
-	    view:aView
+        "
+         if there is no sensor ...
+        "
+        aView
+            dispatchEvent:#pointerLeave:
+            arguments:(Array with:buttonState)
+
+"/        WindowEvent
+"/            sendEvent:#pointerLeave:
+"/            arguments:(Array with:buttonState)
+"/            view:aView
     ]
+
+    "Modified: / 20.5.1998 / 22:53:29 / cg"
 !
 
 saveAndTerminateView:aView
@@ -5719,15 +5779,6 @@
     "Modified: 24.4.1996 / 19:40:04 / cg"
 !
 
-mapView:aView id:aWindowId iconified:aBoolean atX:xPos y:yPos
-        width:w height:h minExtent:minExt maxExtent:maxExt
-    "make a window visible - either as icon or as a real view - needed for restart"
-
-    ^ self subclassResponsibility
-
-    "Modified: 24.4.1996 / 19:43:17 / cg"
-!
-
 mapView:aView id:aWindowId iconified:aBoolean atX:xPos y:yPos width:w height:h
     "map a window - either as icon or as a real view - needed for restart"
 
@@ -5739,6 +5790,15 @@
         width:w height:h minExtent:nil maxExtent:nil
 !
 
+mapView:aView id:aWindowId iconified:aBoolean atX:xPos y:yPos
+        width:w height:h minExtent:minExt maxExtent:maxExt
+    "make a window visible - either as icon or as a real view - needed for restart"
+
+    ^ self subclassResponsibility
+
+    "Modified: 24.4.1996 / 19:43:17 / cg"
+!
+
 mapWindow:aWindowId
     "map a window"
 
@@ -5994,6 +6054,6 @@
 !DeviceWorkstation class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/Attic/DevWorkst.st,v 1.256 1998-05-07 22:25:16 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/Attic/DevWorkst.st,v 1.257 1998-05-20 23:55:15 cg Exp $'
 ! !
 DeviceWorkstation initialize!
--- a/DeviceWorkstation.st	Wed May 20 21:56:14 1998 +0200
+++ b/DeviceWorkstation.st	Thu May 21 01:58:25 1998 +0200
@@ -2963,20 +2963,24 @@
     |sensor|
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor buttonMotion:button x:x y:y view:aView
+        sensor buttonMotion:button x:x y:y view:aView
     ] ifFalse:[
-	aView shown ifTrue:[ "/ could be a late event arrival
-	    "
-	     if there is no sensor ...
-	    "
-	    WindowEvent
-		sendEvent:#buttonMotion:x:y:
-		arguments:(Array with:button with:x with:y)
-		view:aView
-	]
+        aView shown ifTrue:[ "/ could be a late event arrival
+            "
+             if there is no sensor ...
+            "
+            aView
+                dispatchEvent:#buttonMotion:x:y:
+                arguments:(Array with:button with:x with:y)
+
+"/            WindowEvent
+"/                sendEvent:#buttonMotion:x:y:
+"/                arguments:(Array with:button with:x with:y)
+"/                view:aView
+        ]
     ]
 
-    "Modified: 26.2.1997 / 15:02:18 / cg"
+    "Modified: / 20.5.1998 / 22:50:32 / cg"
 !
 
 buttonMultiPress:button x:x y:y view:aView
@@ -2985,20 +2989,24 @@
     |sensor|
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor buttonMultiPress:button x:x y:y view:aView
+        sensor buttonMultiPress:button x:x y:y view:aView
     ] ifFalse:[
-	aView shown ifTrue:[ "/ could be a late event arrival
-	    "
-	     if there is no sensor ...
-	    "
-	    WindowEvent
-		sendEvent:#buttonMultiPress:x:y:
-		arguments:(Array with:button with:x with:y)
-		view:aView
-	]
+        aView shown ifTrue:[ "/ could be a late event arrival
+            "
+             if there is no sensor ...
+            "
+            aView
+                dispatchEvent:#buttonMultiPress:x:y:
+                arguments:(Array with:button with:x with:y)
+
+"/            WindowEvent
+"/                sendEvent:#buttonMultiPress:x:y:
+"/                arguments:(Array with:button with:x with:y)
+"/                view:aView
+        ]
     ]
 
-    "Modified: 26.2.1997 / 15:02:29 / cg"
+    "Modified: / 20.5.1998 / 22:50:49 / cg"
 !
 
 buttonPress:button x:x y:y view:aView
@@ -3007,20 +3015,24 @@
     |sensor|
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor buttonPress:button x:x y:y view:aView
+        sensor buttonPress:button x:x y:y view:aView
     ] ifFalse:[
-	aView shown ifTrue:[ "/ could be a late event arrival
-	    "
-	     if there is no sensor ...
-	    "
-	    WindowEvent
-		sendEvent:#buttonPress:x:y:
-		arguments:(Array with:button with:x with:y)
-		view:aView
-	]
+        aView shown ifTrue:[ "/ could be a late event arrival
+            "
+             if there is no sensor ...
+            "
+            aView
+                dispatchEvent:#buttonPress:x:y:
+                arguments:(Array with:button with:x with:y)
+
+"/            WindowEvent
+"/                sendEvent:#buttonPress:x:y:
+"/                arguments:(Array with:button with:x with:y)
+"/                view:aView
+        ]
     ]
 
-    "Modified: 26.2.1997 / 15:02:42 / cg"
+    "Modified: / 20.5.1998 / 22:51:02 / cg"
 !
 
 buttonRelease:button x:x y:y view:aView
@@ -3029,20 +3041,24 @@
     |sensor|
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor buttonRelease:button x:x y:y view:aView
+        sensor buttonRelease:button x:x y:y view:aView
     ] ifFalse:[
-	aView shown ifTrue:[ "/ could be a late event arrival
-	    "
-	     if there is no sensor ...
-	    "
-	    WindowEvent
-		sendEvent:#buttonRelease:x:y:
-		arguments:(Array with:button with:x with:y)
-		view:aView
-	]
+        aView shown ifTrue:[ "/ could be a late event arrival
+            "
+             if there is no sensor ...
+            "
+            aView
+                dispatchEvent:#buttonRelease:x:y:
+                arguments:(Array with:button with:x with:y)
+
+"/            WindowEvent
+"/                sendEvent:#buttonRelease:x:y:
+"/                arguments:(Array with:button with:x with:y)
+"/                view:aView
+        ]
     ]
 
-    "Modified: 26.2.1997 / 15:02:52 / cg"
+    "Modified: / 20.5.1998 / 22:51:13 / cg"
 !
 
 configureX:x y:y width:w height:h view:aView
@@ -3096,16 +3112,22 @@
     |sensor|
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor exposeX:x y:y width:w height:h view:aView
+        sensor exposeX:x y:y width:w height:h view:aView
     ] ifFalse:[
-	"
-	 if there is no sensor ...
-	"
-	WindowEvent
-	    sendEvent:#exposeX:y:width:height:
-	    arguments:(Array with:x with:y with:w with:h)
-	    view:aView
+        "
+         if there is no sensor ...
+        "
+        aView
+            dispatchEvent:#exposeX:y:width:height:
+            arguments:(Array with:x with:y with:w with:h)
+
+"/        WindowEvent
+"/            sendEvent:#exposeX:y:width:height:
+"/            arguments:(Array with:x with:y with:w with:h)
+"/            view:aView
     ]
+
+    "Modified: / 20.5.1998 / 22:51:31 / cg"
 !
 
 focusInView:aView
@@ -3114,16 +3136,22 @@
     |sensor|
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor focusInView:aView
+        sensor focusInView:aView
     ] ifFalse:[
-	"
-	 if there is no sensor ...
-	"
-	WindowEvent
-	    sendEvent:#focusIn
-	    arguments:nil
-	    view:aView
+        "
+         if there is no sensor ...
+        "
+        aView
+            dispatchEvent:#focusIn
+            arguments:nil
+
+"/        WindowEvent
+"/            sendEvent:#focusIn
+"/            arguments:nil
+"/            view:aView
     ]
+
+    "Modified: / 20.5.1998 / 22:51:48 / cg"
 !
 
 focusOutView:aView 
@@ -3132,16 +3160,22 @@
     |sensor|
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor focusOutView:aView
+        sensor focusOutView:aView
     ] ifFalse:[
-	"
-	 if there is no sensor ...
-	"
-	WindowEvent
-	    sendEvent:#focusOut
-	    arguments:nil
-	    view:aView
+        "
+         if there is no sensor ...
+        "
+        aView
+            dispatchEvent:#focusOut
+            arguments:nil
+
+"/        WindowEvent
+"/            sendEvent:#focusOut
+"/            arguments:nil
+"/            view:aView
     ]
+
+    "Modified: / 20.5.1998 / 22:51:58 / cg"
 !
 
 graphicsExposeX:x y:y width:w height:h final:final view:aView
@@ -3150,16 +3184,22 @@
     |sensor|
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor graphicsExposeX:x y:y width:w height:h final:final view:aView
+        sensor graphicsExposeX:x y:y width:w height:h final:final view:aView
     ] ifFalse:[
-	"
-	 if there is no sensor ...
-	"
-	WindowEvent
-	    sendEvent:#graphicsExposeX:y:width:height:final:
-	    arguments:(Array with:x with:y with:w with:h with:final)
-	    view:aView
+        "
+         if there is no sensor ...
+        "
+        aView
+            dispatchEvent:#graphicsExposeX:y:width:height:final:
+            arguments:(Array with:x with:y with:w with:h with:final)
+
+"/        WindowEvent
+"/            sendEvent:#graphicsExposeX:y:width:height:final:
+"/            arguments:(Array with:x with:y with:w with:h with:final)
+"/            view:aView
     ]
+
+    "Modified: / 20.5.1998 / 22:52:16 / cg"
 !
 
 keyPress:untranslatedKey x:x y:y view:aView
@@ -3173,32 +3213,36 @@
     "/ ctrl-Esc gives up focus
     "/
     untranslatedKey == #Escape ifTrue:[
-	ctrlDown ifTrue:[
-	    self ungrabPointer.
-	    self setInputFocusTo:nil 
-	]
+        ctrlDown ifTrue:[
+            self ungrabPointer.
+            self setInputFocusTo:nil 
+        ]
     ].
 
     self modifierKeyProcessing:untranslatedKey down:true.
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor keyPress:untranslatedKey x:x y:y view:aView
+        sensor keyPress:untranslatedKey x:x y:y view:aView
     ] ifFalse:[
-	aView shown ifTrue:[ "/ could be a late event arrival
-	    "
-	     if there is no sensor ...
-	    "
-	    xlatedKey := self translateKey:untranslatedKey.
-	    xlatedKey notNil ifTrue:[
-		WindowEvent
-		  sendEvent:#keyPress:x:y:
-		  arguments:(Array with:xlatedKey with:x with:y)
-		  view:aView
-	    ]
-	]
+        aView shown ifTrue:[ "/ could be a late event arrival
+            "
+             if there is no sensor ...
+            "
+            xlatedKey := self translateKey:untranslatedKey.
+            xlatedKey notNil ifTrue:[
+                aView
+                    dispatchEvent:#keyPress:x:y:
+                    arguments:(Array with:xlatedKey with:x with:y)
+
+"/                WindowEvent
+"/                  sendEvent:#keyPress:x:y:
+"/                  arguments:(Array with:xlatedKey with:x with:y)
+"/                  view:aView
+            ]
+        ]
     ]
 
-    "Modified: 26.2.1997 / 15:03:28 / cg"
+    "Modified: / 20.5.1998 / 22:52:36 / cg"
 !
 
 keyRelease:untranslatedKey x:x y:y view:aView
@@ -3209,23 +3253,27 @@
     self modifierKeyProcessing:untranslatedKey down:false.
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor keyRelease:untranslatedKey x:x y:y view:aView
+        sensor keyRelease:untranslatedKey x:x y:y view:aView
     ] ifFalse:[
-	aView shown ifTrue:[ "/ could be a late event arrival
-	    "
-	     if there is no sensor ...
-	    "
-	    xlatedKey := self translateKey:untranslatedKey.
-	    xlatedKey notNil ifTrue:[
-		WindowEvent
-		    sendEvent:#keyRelease:x:y:
-		    arguments:(Array with:xlatedKey with:x with:y)
-		    view:aView
-	    ]
-	]
+        aView shown ifTrue:[ "/ could be a late event arrival
+            "
+             if there is no sensor ...
+            "
+            xlatedKey := self translateKey:untranslatedKey.
+            xlatedKey notNil ifTrue:[
+                aView
+                    dispatchEvent:#keyRelease:x:y:
+                    arguments:(Array with:xlatedKey with:x with:y)
+
+"/                WindowEvent
+"/                    sendEvent:#keyRelease:x:y:
+"/                    arguments:(Array with:xlatedKey with:x with:y)
+"/                    view:aView
+            ]
+        ]
     ]
 
-    "Modified: 26.2.1997 / 15:03:40 / cg"
+    "Modified: / 20.5.1998 / 22:52:52 / cg"
 !
 
 mappedView:aView
@@ -3264,16 +3312,22 @@
     |sensor|
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor pointerEnter:buttonState x:x y:y view:aView
+        sensor pointerEnter:buttonState x:x y:y view:aView
     ] ifFalse:[
-	"
-	 if there is no sensor ...
-	"
-	WindowEvent
-	    sendEvent:#pointerEnter:x:y:
-	    arguments:(Array with:buttonState with:x with:y)
-	    view:aView
+        "
+         if there is no sensor ...
+        "
+        aView
+            dispatchEvent:#pointerEnter:x:y:
+            arguments:(Array with:buttonState with:x with:y)
+
+"/        WindowEvent
+"/            sendEvent:#pointerEnter:x:y:
+"/            arguments:(Array with:buttonState with:x with:y)
+"/            view:aView
     ]
+
+    "Modified: / 20.5.1998 / 22:53:13 / cg"
 !
 
 pointerLeave:buttonState view:aView
@@ -3282,16 +3336,22 @@
     |sensor|
 
     (sensor := aView sensor) notNil ifTrue:[
-	sensor pointerLeave:buttonState view:aView
+        sensor pointerLeave:buttonState view:aView
     ] ifFalse:[
-	"
-	 if there is no sensor ...
-	"
-	WindowEvent
-	    sendEvent:#pointerLeave:
-	    arguments:(Array with:buttonState)
-	    view:aView
+        "
+         if there is no sensor ...
+        "
+        aView
+            dispatchEvent:#pointerLeave:
+            arguments:(Array with:buttonState)
+
+"/        WindowEvent
+"/            sendEvent:#pointerLeave:
+"/            arguments:(Array with:buttonState)
+"/            view:aView
     ]
+
+    "Modified: / 20.5.1998 / 22:53:29 / cg"
 !
 
 saveAndTerminateView:aView
@@ -5719,15 +5779,6 @@
     "Modified: 24.4.1996 / 19:40:04 / cg"
 !
 
-mapView:aView id:aWindowId iconified:aBoolean atX:xPos y:yPos
-        width:w height:h minExtent:minExt maxExtent:maxExt
-    "make a window visible - either as icon or as a real view - needed for restart"
-
-    ^ self subclassResponsibility
-
-    "Modified: 24.4.1996 / 19:43:17 / cg"
-!
-
 mapView:aView id:aWindowId iconified:aBoolean atX:xPos y:yPos width:w height:h
     "map a window - either as icon or as a real view - needed for restart"
 
@@ -5739,6 +5790,15 @@
         width:w height:h minExtent:nil maxExtent:nil
 !
 
+mapView:aView id:aWindowId iconified:aBoolean atX:xPos y:yPos
+        width:w height:h minExtent:minExt maxExtent:maxExt
+    "make a window visible - either as icon or as a real view - needed for restart"
+
+    ^ self subclassResponsibility
+
+    "Modified: 24.4.1996 / 19:43:17 / cg"
+!
+
 mapWindow:aWindowId
     "map a window"
 
@@ -5994,6 +6054,6 @@
 !DeviceWorkstation class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/DeviceWorkstation.st,v 1.256 1998-05-07 22:25:16 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/DeviceWorkstation.st,v 1.257 1998-05-20 23:55:15 cg Exp $'
 ! !
 DeviceWorkstation initialize!
--- a/DisplaySurface.st	Wed May 20 21:56:14 1998 +0200
+++ b/DisplaySurface.st	Thu May 21 01:58:25 1998 +0200
@@ -884,6 +884,228 @@
     self enableEvent:#pointerMotion
 ! !
 
+!DisplaySurface methodsFor:'event dispatching'!
+
+dispatchEvent:event
+    "dispatch the event"
+
+    self 
+        dispatchEvent:event type
+        arguments:(event arguments)
+        withFocusOn:nil
+        delegate:true
+
+    "Modified: / 20.5.1998 / 23:01:15 / cg"
+!
+
+dispatchEvent:type arguments:arguments
+    ^ self 
+        dispatchEvent:type 
+        arguments:arguments 
+        withFocusOn:nil 
+        delegate:true
+
+    "Modified: / 20.5.1998 / 22:50:31 / cg"
+!
+
+dispatchEvent:type arguments:argArray withFocusOn:focusView delegate:doDelegate
+    "dispatch the event represented by type and arguments either to my delegate,
+     or to my controller (which may be myself, if I implement the controller functionality myself). 
+     If focusView is nonNil, and it is a keyboard event, it is forwarded to this
+     view (but not if there was a delegate in the first place).
+
+     If doDelegate is true, keyboard and button events are forwarded to a
+     delegate object (if non-nil). DoDelegate may be passed as true, to
+     handle events which are already delegated.
+     If there is a delegate, only messages which are understood by it are 
+     forwarded. Also, the delegate is asked if it is willing to handle the event
+     before.
+     Delegated messages get the original view as an extra argument.
+     Delegation has higher priority than both controller or focusView 
+     forwarding."
+
+    |delegate selector delegateMessage delegateQuery 
+     eventReceiver controller deviceMessage
+     isKeyEvent isButtonEvent isPointerEvent trans
+     rect x y w h|
+
+    isKeyEvent := isButtonEvent := isPointerEvent := false.
+
+    type == #damage ifTrue:[
+        self shown ifTrue:[
+            rect := argArray.
+            x := rect left.
+            y := rect top.
+            w := rect width.
+            h := rect height.
+            transformation notNil ifTrue:[
+                self deviceExposeX:x y:y width:w height:h
+            ] ifFalse:[
+                self exposeX:x y:y width:w height:h
+            ]
+        ].
+        ^ self
+    ].
+
+    (type == #'keyPress:x:y:') ifTrue:[
+        isKeyEvent := true.
+        deviceMessage := #'deviceKeyPress:x:y:'.
+        delegateMessage := #'keyPress:x:y:view:'.
+        delegateQuery := #'handlesKeyPress:inView:'.
+    ] ifFalse:[ (type == #'keyRelease:x:y:') ifTrue:[
+        isKeyEvent := true.
+        deviceMessage := #'deviceKeyRelease:x:y:'.
+        delegateMessage := #'keyRelease:x:y:view:'.
+        delegateQuery := #'handlesKeyRelease:inView:'.
+    ] ifFalse:[ (type == #'buttonMotion:x:y:') ifTrue:[
+        isButtonEvent := true.
+        deviceMessage := #'deviceButtonMotion:x:y:'.
+        delegateMessage := #'buttonMotion:x:y:view:'.
+        delegateQuery := #'handlesButtonMotion:inView:'.
+    ] ifFalse:[ (type == #'buttonPress:x:y:') ifTrue:[
+        isButtonEvent := true.
+        deviceMessage := #'deviceButtonPress:x:y:'.
+        delegateMessage := #'buttonPress:x:y:view:'.
+        delegateQuery := #'handlesButtonPress:inView:'.
+    ] ifFalse:[ (type == #'buttonRelease:x:y:') ifTrue:[
+        isButtonEvent := true.
+        deviceMessage := #'deviceButtonRelease:x:y:'.
+        delegateMessage := #'buttonRelease:x:y:view:'.
+        delegateQuery := #'handlesButtonRelease:inView:'.
+    ] ifFalse:[ (type == #'buttonShiftPress:x:y:') ifTrue:[
+        isButtonEvent := true.
+        deviceMessage := #'deviceButtonShiftPress:x:y:'.
+        delegateMessage := #'buttonShiftPress:x:y:view:'.
+        delegateQuery := #'handlesButtonShiftPress:inView:'.
+    ] ifFalse:[ (type == #'buttonMultiPress:x:y:') ifTrue:[
+        isButtonEvent := true.
+        deviceMessage := #'deviceButtonMultiPress:x:y:'.
+        delegateMessage := #'buttonMultiPress:x:y:view:'.
+        delegateQuery := #'handlesButtonMultiPress:inView:'.
+    ] ifFalse:[ (type == #'pointerEnter:x:y:') ifTrue:[
+        isPointerEvent := true.
+        deviceMessage := #'devicePointerEnter:x:y:'.
+        delegateMessage := #'pointerEnter:x:y:view:'.
+        delegateQuery := #'handlesPointerEnter:inView:'.
+    ] ifFalse:[ (type == #'pointerLeave:') ifTrue:[
+        isPointerEvent := true.
+        deviceMessage := type.
+        delegateMessage := #'pointerLeave:view:'.
+        delegateQuery := #'handlesPointerLeave:inView:'.
+    ] ifFalse:[ (type == #'exposeX:y:width:height:') ifTrue:[
+        deviceMessage := #'deviceExposeX:y:width:height:'.
+    ] ifFalse:[ (type == #'graphicsExposeX:y:width:height:final:') ifTrue:[
+        deviceMessage := #'deviceGraphicsExposeX:y:width:height:final:'.
+    ]]]]]]]]]]].
+
+    "
+     if there is a focusView, and its a keyboard event, pass it
+     to that view (or its controller, or its delegate). 
+     In this case, a coordinate which is outside of
+     the focusView (0 @ 0) is passed as x/y coordinates.
+    "
+    (focusView notNil 
+    and:[isKeyEvent]) ifTrue:[
+        focusView 
+            dispatchEvent:type 
+            arguments:(Array with:(argArray at:1) with:0 with:0)
+            withFocusOn:nil
+            delegate:doDelegate.
+        ^ self
+    ].
+
+    doDelegate ifTrue:[
+        "
+         handle delegated messages
+        "
+        (isKeyEvent 
+         or:[isButtonEvent 
+         or:[isPointerEvent]]) ifTrue:[
+            delegate := self delegate.
+
+            "
+             what a kludge - sending to delegate requires
+             another selector and an additional argument ...
+            "
+            (delegate notNil
+            and:[delegate respondsTo:delegateMessage]) ifTrue:[
+                "
+                 is the delegate interested in that event ?
+                 (if it does not respond to the handlesXXX message,
+                  we assume: NO)
+                "
+                ((delegate respondsTo:delegateQuery) 
+                and:[delegate perform:delegateQuery with:(argArray at:1) with:self]) ifTrue:[
+                    "
+                     mhmh ... have to convert to logical coordinates
+                    "        
+                    transformation notNil ifTrue:[
+                        argArray size > 2 ifTrue:[
+                            argArray at:2 put:(trans applyInverseToX:(argArray at:2)).
+                            argArray at:3 put:(trans applyInverseToY:(argArray at:3)).
+                        ].
+                    ].
+                    argArray isNil ifTrue:[
+                        delegate perform:delegateMessage with:self
+                    ] ifFalse:[
+                        delegate perform:delegateMessage withArguments:(argArray copyWith:self)
+                    ].
+                    ^ self
+                ]
+            ].
+        ].
+    ].
+
+    (isKeyEvent 
+     or:[isButtonEvent 
+     or:[isPointerEvent]]) ifTrue:[
+        realized ifFalse:[
+            ^ self
+        ]
+    ].
+
+    "
+     if there is a controller, that one gets all user events
+    "
+    eventReceiver := self.
+    (controller := self controller) notNil ifTrue:[  
+        (isKeyEvent 
+         or:[isButtonEvent 
+         or:[isPointerEvent
+         or:[(type == #focusIn)
+         or:[(type == #focusOut)]]]]) ifTrue:[
+            eventReceiver := controller.
+        ]
+    ].
+
+    "
+     finally, another one:
+     if I have a transformation, edit the selector from #foo to #deviceFoo...
+     This allows for the event to be handled either in device or
+     logical coordinates. (since the deviceFoo-messages default implementation
+     in DisplaySurface translates and resends).
+     Actually, I could always send deviceXXX without speed penalty
+     (event sending is no high frequency operation), but that just adds 
+     another context to any debuggers walkback, making things less clear.
+    "
+    selector := type.
+
+    transformation notNil ifTrue:[
+        (isKeyEvent
+         or:[isButtonEvent
+         or:[isPointerEvent
+         or:[(type == #'exposeX:y:width:height:')
+         or:[(type == #'graphicsExposeX:y:width:height:final:')]]]]) ifTrue:[
+            selector := deviceMessage
+        ]        
+    ].
+
+    eventReceiver perform:selector withArguments:argArray
+
+    "Modified: / 31.10.1997 / 19:54:28 / cg"
+    "Created: / 20.5.1998 / 22:46:25 / cg"
+! !
+
 !DisplaySurface methodsFor:'event handling'!
 
 activateMenu
@@ -1232,199 +1454,6 @@
     "Modified: 14.10.1996 / 22:26:35 / stefan"
 !
 
-dispatchEvent:event
-    "dispatch an event the views controller or the receiver itself.
-     This is the main event handling entry; 
-     however, for backward compatibility (and your convenience), 
-     this dispatches to specialized event handlers 
-     (such as keyPress/buttonPress etc.)"
-
-    |type argArray
-     delegate selector delegateMessage delegateQuery 
-     eventReceiver controller deviceMessage
-     isKeyEvent isButtonEvent isPointerEvent trans
-     rect x y w h|
-
-    type := event type.
-    argArray := event arguments.
-
-    isKeyEvent := isButtonEvent := isPointerEvent := false.
-
-    type == #damage ifTrue:[
-        self shown ifTrue:[
-            rect := argArray.
-            x := rect left.
-            y := rect top.
-            w := rect width.
-            h := rect height.
-            transformation notNil ifTrue:[
-                self deviceExposeX:x y:y width:w height:h
-            ] ifFalse:[
-                self exposeX:x y:y width:w height:h
-            ]
-        ].
-        ^ self
-    ].
-
-    (type == #'keyPress:x:y:') ifTrue:[
-        isKeyEvent := true.
-        deviceMessage := #'deviceKeyPress:x:y:'.
-        delegateMessage := #'keyPress:x:y:view:'.
-        delegateQuery := #'handlesKeyPress:inView:'.
-    ] ifFalse:[ (type == #'keyRelease:x:y:') ifTrue:[
-        isKeyEvent := true.
-        deviceMessage := #'deviceKeyRelease:x:y:'.
-        delegateMessage := #'keyRelease:x:y:view:'.
-        delegateQuery := #'handlesKeyRelease:inView:'.
-    ] ifFalse:[ (type == #'buttonMotion:x:y:') ifTrue:[
-        isButtonEvent := true.
-        deviceMessage := #'deviceButtonMotion:x:y:'.
-        delegateMessage := #'buttonMotion:x:y:view:'.
-        delegateQuery := #'handlesButtonMotion:inView:'.
-    ] ifFalse:[ (type == #'buttonPress:x:y:') ifTrue:[
-        isButtonEvent := true.
-        deviceMessage := #'deviceButtonPress:x:y:'.
-        delegateMessage := #'buttonPress:x:y:view:'.
-        delegateQuery := #'handlesButtonPress:inView:'.
-    ] ifFalse:[ (type == #'buttonRelease:x:y:') ifTrue:[
-        isButtonEvent := true.
-        deviceMessage := #'deviceButtonRelease:x:y:'.
-        delegateMessage := #'buttonRelease:x:y:view:'.
-        delegateQuery := #'handlesButtonRelease:inView:'.
-    ] ifFalse:[ (type == #'buttonShiftPress:x:y:') ifTrue:[
-        isButtonEvent := true.
-        deviceMessage := #'deviceButtonShiftPress:x:y:'.
-        delegateMessage := #'buttonShiftPress:x:y:view:'.
-        delegateQuery := #'handlesButtonShiftPress:inView:'.
-    ] ifFalse:[ (type == #'buttonMultiPress:x:y:') ifTrue:[
-        isButtonEvent := true.
-        deviceMessage := #'deviceButtonMultiPress:x:y:'.
-        delegateMessage := #'buttonMultiPress:x:y:view:'.
-        delegateQuery := #'handlesButtonMultiPress:inView:'.
-    ] ifFalse:[ (type == #'pointerEnter:x:y:') ifTrue:[
-        isPointerEvent := true.
-        deviceMessage := #'devicePointerEnter:x:y:'.
-        delegateMessage := #'pointerEnter:x:y:view:'.
-        delegateQuery := #'handlesPointerEnter:inView:'.
-    ] ifFalse:[ (type == #'pointerLeave:') ifTrue:[
-        isPointerEvent := true.
-        deviceMessage := type.
-        delegateMessage := #'pointerLeave:view:'.
-        delegateQuery := #'handlesPointerLeave:inView:'.
-    ] ifFalse:[ (type == #'exposeX:y:width:height:') ifTrue:[
-        deviceMessage := #'deviceExposeX:y:width:height:'.
-    ] ifFalse:[ (type == #'graphicsExposeX:y:width:height:final:') ifTrue:[
-        deviceMessage := #'deviceGraphicsExposeX:y:width:height:final:'.
-    ]]]]]]]]]]].
-
-"/    "
-"/     if there is a focusView, and its a keyboard event, pass it
-"/     to that view (or its controller, or its delegate). 
-"/     In this case, a coordinate which is outside of
-"/     the focusView (0 @ 0) is passed as x/y coordinates.
-"/    "
-"/    (focusView notNil 
-"/    and:[isKeyEvent]) ifTrue:[
-"/        self sendEvent:type 
-"/             arguments:(Array with:(argArray at:1) with:0 with:0)
-"/             view:focusView 
-"/             withFocusOn:nil
-"/             delegate:doDelegate.
-"/        ^ self
-"/    ].
-
-"/    doDelegate ifTrue:[
-"/        "
-"/         handle delegated messages
-"/        "
-"/        (isKeyEvent 
-"/         or:[isButtonEvent 
-"/         or:[isPointerEvent]]) ifTrue:[
-"/            delegate := view delegate.
-"/
-"/            "
-"/             what a kludge - sending to delegate requires
-"/             another selector and an additional argument ...
-"/            "
-"/            (delegate notNil
-"/            and:[delegate respondsTo:delegateMessage]) ifTrue:[
-"/                "
-"/                 is the delegate interested in that event ?
-"/                 (if it does not respond to the handlesXXX message,
-"/                  we assume: NO)
-"/                "
-"/                ((delegate respondsTo:delegateQuery) 
-"/                and:[delegate perform:delegateQuery with:(argArray at:1) with:view]) ifTrue:[
-"/                    "
-"/                     mhmh ... have to convert to logical coordinates
-"/                    "        
-"/                    (trans := view transformation) notNil ifTrue:[
-"/                        argArray size > 2 ifTrue:[
-"/                            argArray at:2 put:(trans applyInverseToX:(argArray at:2)).
-"/                            argArray at:3 put:(trans applyInverseToY:(argArray at:3)).
-"/                        ].
-"/                    ].
-"/                    argArray isNil ifTrue:[
-"/                        delegate perform:delegateMessage with:view
-"/                    ] ifFalse:[
-"/                        delegate perform:delegateMessage withArguments:(argArray copyWith:view)
-"/                    ].
-"/                    ^ self
-"/                ]
-"/            ].
-"/        ].
-"/    ].
-
-    (isKeyEvent 
-     or:[isButtonEvent 
-     or:[isPointerEvent]]) ifTrue:[
-        self realized ifFalse:[
-            ^ self
-        ]
-    ].
-
-    "
-     if there is a controller, that one gets all user events
-    "
-    eventReceiver := self.
-    controller notNil ifTrue:[  
-        (isKeyEvent 
-         or:[isButtonEvent 
-         or:[isPointerEvent
-         or:[(type == #focusIn)
-         or:[(type == #focusOut)]]]]) ifTrue:[
-            eventReceiver := controller.
-        ]
-    ].
-
-    "
-     finally, another one:
-     if the view has a transformation, edit the selector
-     from #foo to #deviceFoo...
-     This allows the view to handle the event either in device or
-     logical coordinates. (since the deviceFoo-messages default implementation
-     in DisplaySurface translates and resends).
-     Actually, I could always send deviceXXX without speed penalty
-     (event sending is no high frequency operation), but that just adds 
-     another context to any debuggers walkback, making things less clear.
-    "
-    selector := type.
-
-    transformation notNil ifTrue:[
-        (isKeyEvent
-         or:[isButtonEvent
-         or:[isPointerEvent
-         or:[(type == #'exposeX:y:width:height:')
-         or:[(type == #'graphicsExposeX:y:width:height:final:')]]]]) ifTrue:[
-            selector := deviceMessage
-        ]        
-    ].
-
-    eventReceiver perform:selector withArguments:argArray
-
-    "Modified: 21.8.1997 / 19:49:42 / cg"
-!
-
 exposeX:x y:y width:w height:h
     "an expose event - nothing done here"
 
@@ -1958,5 +1987,5 @@
 !DisplaySurface class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/DisplaySurface.st,v 1.37 1998-04-22 10:57:25 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/DisplaySurface.st,v 1.38 1998-05-20 23:54:17 cg Exp $'
 ! !
--- a/KeybdFwd.st	Wed May 20 21:56:14 1998 +0200
+++ b/KeybdFwd.st	Thu May 21 01:58:25 1998 +0200
@@ -342,16 +342,22 @@
         destination keyPress:key x:nil y:nil view:aView.
     ] ifFalse:[
         destinationView notNil ifTrue:[
-            WindowEvent
-                sendEvent:#keyPress:x:y: 
+            destinationView
+                dispatchEvent:#keyPress:x:y:
                 arguments:(Array with:key with:xDel with:yDel) 
-                view:destinationView 
                 withFocusOn:nil 
                 delegate:false
+
+"/            WindowEvent
+"/                sendEvent:#keyPress:x:y: 
+"/                arguments:(Array with:key with:xDel with:yDel) 
+"/                view:destinationView 
+"/                withFocusOn:nil 
+"/                delegate:false
         ]
     ]
 
-    "Modified: / 6.12.1997 / 01:50:57 / cg"
+    "Modified: / 20.5.1998 / 22:54:05 / cg"
 !
 
 keyRelease:key x:x y:y view:aView
@@ -374,14 +380,20 @@
         destination keyRelease:key x:-1 y:-1 view:aView
     ] ifFalse:[
         destinationView notNil ifTrue:[
-            WindowEvent
-                sendEvent:#keyRelease:x:y:
-                arguments:(Array with:key with:-1 with:-1)
-                view:destinationView
+            destinationView
+                dispatchEvent:#keyRelease:x:y:
+                arguments:(Array with:key with:-1 with:-1) 
+                withFocusOn:nil 
+                delegate:false
+
+"/            WindowEvent
+"/                sendEvent:#keyRelease:x:y:
+"/                arguments:(Array with:key with:-1 with:-1)
+"/                view:destinationView
         ]
     ]
 
-    "Modified: / 6.12.1997 / 01:44:12 / cg"
+    "Modified: / 20.5.1998 / 22:54:32 / cg"
 ! !
 
 !KeyboardForwarder methodsFor:'focus forwarding'!
@@ -474,5 +486,5 @@
 !KeyboardForwarder class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/Attic/KeybdFwd.st,v 1.22 1997-12-08 17:31:20 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/Attic/KeybdFwd.st,v 1.23 1998-05-20 23:56:12 cg Exp $'
 ! !
--- a/KeyboardForwarder.st	Wed May 20 21:56:14 1998 +0200
+++ b/KeyboardForwarder.st	Thu May 21 01:58:25 1998 +0200
@@ -342,16 +342,22 @@
         destination keyPress:key x:nil y:nil view:aView.
     ] ifFalse:[
         destinationView notNil ifTrue:[
-            WindowEvent
-                sendEvent:#keyPress:x:y: 
+            destinationView
+                dispatchEvent:#keyPress:x:y:
                 arguments:(Array with:key with:xDel with:yDel) 
-                view:destinationView 
                 withFocusOn:nil 
                 delegate:false
+
+"/            WindowEvent
+"/                sendEvent:#keyPress:x:y: 
+"/                arguments:(Array with:key with:xDel with:yDel) 
+"/                view:destinationView 
+"/                withFocusOn:nil 
+"/                delegate:false
         ]
     ]
 
-    "Modified: / 6.12.1997 / 01:50:57 / cg"
+    "Modified: / 20.5.1998 / 22:54:05 / cg"
 !
 
 keyRelease:key x:x y:y view:aView
@@ -374,14 +380,20 @@
         destination keyRelease:key x:-1 y:-1 view:aView
     ] ifFalse:[
         destinationView notNil ifTrue:[
-            WindowEvent
-                sendEvent:#keyRelease:x:y:
-                arguments:(Array with:key with:-1 with:-1)
-                view:destinationView
+            destinationView
+                dispatchEvent:#keyRelease:x:y:
+                arguments:(Array with:key with:-1 with:-1) 
+                withFocusOn:nil 
+                delegate:false
+
+"/            WindowEvent
+"/                sendEvent:#keyRelease:x:y:
+"/                arguments:(Array with:key with:-1 with:-1)
+"/                view:destinationView
         ]
     ]
 
-    "Modified: / 6.12.1997 / 01:44:12 / cg"
+    "Modified: / 20.5.1998 / 22:54:32 / cg"
 ! !
 
 !KeyboardForwarder methodsFor:'focus forwarding'!
@@ -474,5 +486,5 @@
 !KeyboardForwarder class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/KeyboardForwarder.st,v 1.22 1997-12-08 17:31:20 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/KeyboardForwarder.st,v 1.23 1998-05-20 23:56:12 cg Exp $'
 ! !
--- a/SWSensor.st	Wed May 20 21:56:14 1998 +0200
+++ b/SWSensor.st	Thu May 21 01:58:25 1998 +0200
@@ -62,59 +62,86 @@
 addDamage:aRectangle view:aView wakeup:doWakeup
     "forward as an expose for some view"
 
-    WindowEvent
-        sendEvent:#exposeX:y:width:height:
+    aView
+        dispatchEvent:#exposeX:y:width:height:
         arguments:(Array with:aRectangle left 
                          with:aRectangle top 
                          with:aRectangle width
                          with:aRectangle height)
-        view:aView
 
-    "Modified: 29.1.1997 / 20:40:52 / cg"
+"/    WindowEvent
+"/        sendEvent:#exposeX:y:width:height:
+"/        arguments:(Array with:aRectangle left 
+"/                         with:aRectangle top 
+"/                         with:aRectangle width
+"/                         with:aRectangle height)
+"/        view:aView
+
+    "Modified: / 20.5.1998 / 22:55:37 / cg"
 !
 
 buttonMotion:button x:x y:y view:aView
     "forward a button-motion for some view"
 
-    WindowEvent
-        sendEvent:#buttonMotion:x:y:
+    aView
+        dispatchEvent:#buttonMotion:x:y:
         arguments:(Array with:button with:x with:y)
-        view:aView
 
-    "Created: 24.11.1995 / 19:14:02 / cg"
+"/    WindowEvent
+"/        sendEvent:#buttonMotion:x:y:
+"/        arguments:(Array with:button with:x with:y)
+"/        view:aView
+
+    "Created: / 24.11.1995 / 19:14:02 / cg"
+    "Modified: / 20.5.1998 / 22:55:54 / cg"
 !
 
 buttonMultiPress:button x:x y:y view:aView
     "forward a button-multi-press event for some view"
 
-    WindowEvent
-        sendEvent:#buttonMultiPress:x:y:
+    aView
+        dispatchEvent:#buttonMultiPress:x:y:
         arguments:(Array with:button with:x with:y)
-        view:aView
 
-    "Created: 24.11.1995 / 19:14:14 / cg"
+"/    WindowEvent
+"/        sendEvent:#buttonMultiPress:x:y:
+"/        arguments:(Array with:button with:x with:y)
+"/        view:aView
+
+    "Created: / 24.11.1995 / 19:14:14 / cg"
+    "Modified: / 20.5.1998 / 22:56:07 / cg"
 !
 
 buttonPress:button x:x y:y view:aView
     "forward a button-press event for some view"
 
-    WindowEvent
-        sendEvent:#buttonPress:x:y:
+    aView
+        dispatchEvent:#buttonPress:x:y:
         arguments:(Array with:button with:x with:y)
-        view:aView
 
-    "Created: 24.11.1995 / 19:14:25 / cg"
+"/    WindowEvent
+"/        sendEvent:#buttonPress:x:y:
+"/        arguments:(Array with:button with:x with:y)
+"/        view:aView
+
+    "Created: / 24.11.1995 / 19:14:25 / cg"
+    "Modified: / 20.5.1998 / 22:56:23 / cg"
 !
 
 buttonRelease:button x:x y:y view:aView
     "forward a button-release event for some view"
 
-    WindowEvent
-        sendEvent:#buttonRelease:x:y:
+    aView
+        dispatchEvent:#buttonRelease:x:y:
         arguments:(Array with:button with:x with:y)
-        view:aView
 
-    "Created: 24.11.1995 / 19:14:36 / cg"
+"/    WindowEvent
+"/        sendEvent:#buttonRelease:x:y:
+"/        arguments:(Array with:button with:x with:y)
+"/        view:aView
+
+    "Created: / 24.11.1995 / 19:14:36 / cg"
+    "Modified: / 20.5.1998 / 22:56:34 / cg"
 !
 
 configureX:x y:y width:w height:h view:aView
@@ -144,35 +171,49 @@
 exposeX:x y:y width:w height:h view:aView
     "forward an expose for some view"
 
-    WindowEvent
-        sendEvent:#exposeX:y:width:height:
+    aView
+        dispatchEvent:#exposeX:y:width:height:
         arguments:(Array with:x with:y with:w with:h)
-        view:aView
 
-    "Created: 24.11.1995 / 19:15:54 / cg"
-    "Modified: 29.1.1997 / 20:40:58 / cg"
+"/    WindowEvent
+"/        sendEvent:#exposeX:y:width:height:
+"/        arguments:(Array with:x with:y with:w with:h)
+"/        view:aView
+
+    "Created: / 24.11.1995 / 19:15:54 / cg"
+    "Modified: / 20.5.1998 / 22:56:49 / cg"
 !
 
 focusInView:aView
     "forward a focusIn event for some view"
 
-    WindowEvent
-        sendEvent:#focusIn
+    aView
+        dispatchEvent:#focusIn
         arguments:nil
-        view:aView
 
-    "Created: 24.11.1995 / 19:16:11 / cg"
+"/   WindowEvent
+"/        sendEvent:#focusIn
+"/        arguments:nil
+"/        view:aView
+
+    "Created: / 24.11.1995 / 19:16:11 / cg"
+    "Modified: / 20.5.1998 / 22:57:04 / cg"
 !
 
 focusOutView:aView 
     "forward a focusOut event for some view"
 
-    WindowEvent
-        sendEvent:#focusOut
+    aView
+        dispatchEvent:#focusOut
         arguments:nil
-        view:aView
 
-    "Created: 24.11.1995 / 19:16:24 / cg"
+"/    WindowEvent
+"/        sendEvent:#focusOut
+"/        arguments:nil
+"/        view:aView
+
+    "Created: / 24.11.1995 / 19:16:24 / cg"
+    "Modified: / 20.5.1998 / 22:57:16 / cg"
 !
 
 graphicsExposeX:x y:y width:w height:h final:final view:aView
@@ -187,13 +228,17 @@
         ]
     ].
 
-    WindowEvent
-        sendEvent:#graphicsExposeX:y:width:height:final:
+    aView
+        dispatchEvent:#graphicsExposeX:y:width:height:final:
         arguments:(Array with:x with:y with:w with:h with:final)
-        view:aView
 
-    "Created: 24.11.1995 / 19:16:38 / cg"
-    "Modified: 29.1.1997 / 20:46:15 / cg"
+"/    WindowEvent
+"/        sendEvent:#graphicsExposeX:y:width:height:final:
+"/        arguments:(Array with:x with:y with:w with:h with:final)
+"/        view:aView
+
+    "Created: / 24.11.1995 / 19:16:38 / cg"
+    "Modified: / 20.5.1998 / 22:57:32 / cg"
 !
 
 keyPress:untranslatedKey x:x y:y view:aView
@@ -205,14 +250,18 @@
 
     xlatedKey := aView graphicsDevice translateKey:untranslatedKey.
     xlatedKey notNil ifTrue:[
-        WindowEvent
-          sendEvent:#keyPress:x:y:
-          arguments:(Array with:xlatedKey with:x with:y)
-          view:aView
+        aView
+            dispatchEvent:#keyPress:x:y:
+            arguments:(Array with:xlatedKey with:x with:y)
+
+"/        WindowEvent
+"/          sendEvent:#keyPress:x:y:
+"/          arguments:(Array with:xlatedKey with:x with:y)
+"/          view:aView
     ]
 
-    "Created: 24.11.1995 / 19:17:23 / cg"
-    "Modified: 28.5.1996 / 20:25:23 / cg"
+    "Created: / 24.11.1995 / 19:17:23 / cg"
+    "Modified: / 20.5.1998 / 22:57:52 / cg"
 !
 
 keyRelease:untranslatedKey x:x y:y view:aView
@@ -224,14 +273,18 @@
 
     xlatedKey := aView graphicsDevice translateKey:untranslatedKey.
     xlatedKey notNil ifTrue:[
-        WindowEvent
-            sendEvent:#keyRelease:x:y:
+        aView
+            dispatchEvent:#keyRelease:x:y:
             arguments:(Array with:xlatedKey with:x with:y)
-            view:aView
+
+"/        WindowEvent
+"/            sendEvent:#keyRelease:x:y:
+"/            arguments:(Array with:xlatedKey with:x with:y)
+"/            view:aView
     ]
 
-    "Created: 24.11.1995 / 19:17:50 / cg"
-    "Modified: 28.5.1996 / 20:25:25 / cg"
+    "Created: / 24.11.1995 / 19:17:50 / cg"
+    "Modified: / 20.5.1998 / 22:58:05 / cg"
 !
 
 mappedView:aView
@@ -262,23 +315,33 @@
 pointerEnter:buttonState x:x y:y view:aView
     "forward a pointer enter for some view"
 
-    WindowEvent
-        sendEvent:#pointerEnter:x:y:
+    aView
+        dispatchEvent:#pointerEnter:x:y:
         arguments:(Array with:buttonState with:x with:y)
-        view:aView
 
-    "Created: 24.11.1995 / 19:18:20 / cg"
+"/    WindowEvent
+"/        sendEvent:#pointerEnter:x:y:
+"/        arguments:(Array with:buttonState with:x with:y)
+"/        view:aView
+
+    "Created: / 24.11.1995 / 19:18:20 / cg"
+    "Modified: / 20.5.1998 / 22:58:20 / cg"
 !
 
 pointerLeave:buttonState view:aView
     "forward a pointer leave for some view"
 
-    WindowEvent
-        sendEvent:#pointerLeave:
+    aView
+        dispatchEvent:#pointerLeave:
         arguments:(Array with:buttonState)
-        view:aView
 
-    "Created: 24.11.1995 / 19:18:30 / cg"
+"/    WindowEvent
+"/        sendEvent:#pointerLeave:
+"/        arguments:(Array with:buttonState)
+"/        view:aView
+
+    "Created: / 24.11.1995 / 19:18:30 / cg"
+    "Modified: / 20.5.1998 / 22:58:35 / cg"
 !
 
 saveAndTerminateView:aView
@@ -361,5 +424,5 @@
 !SynchronousWindowSensor class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/Attic/SWSensor.st,v 1.15 1997-08-19 15:28:51 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/Attic/SWSensor.st,v 1.16 1998-05-20 23:56:59 cg Exp $'
 ! !
--- a/SynchronousWindowSensor.st	Wed May 20 21:56:14 1998 +0200
+++ b/SynchronousWindowSensor.st	Thu May 21 01:58:25 1998 +0200
@@ -62,59 +62,86 @@
 addDamage:aRectangle view:aView wakeup:doWakeup
     "forward as an expose for some view"
 
-    WindowEvent
-        sendEvent:#exposeX:y:width:height:
+    aView
+        dispatchEvent:#exposeX:y:width:height:
         arguments:(Array with:aRectangle left 
                          with:aRectangle top 
                          with:aRectangle width
                          with:aRectangle height)
-        view:aView
 
-    "Modified: 29.1.1997 / 20:40:52 / cg"
+"/    WindowEvent
+"/        sendEvent:#exposeX:y:width:height:
+"/        arguments:(Array with:aRectangle left 
+"/                         with:aRectangle top 
+"/                         with:aRectangle width
+"/                         with:aRectangle height)
+"/        view:aView
+
+    "Modified: / 20.5.1998 / 22:55:37 / cg"
 !
 
 buttonMotion:button x:x y:y view:aView
     "forward a button-motion for some view"
 
-    WindowEvent
-        sendEvent:#buttonMotion:x:y:
+    aView
+        dispatchEvent:#buttonMotion:x:y:
         arguments:(Array with:button with:x with:y)
-        view:aView
 
-    "Created: 24.11.1995 / 19:14:02 / cg"
+"/    WindowEvent
+"/        sendEvent:#buttonMotion:x:y:
+"/        arguments:(Array with:button with:x with:y)
+"/        view:aView
+
+    "Created: / 24.11.1995 / 19:14:02 / cg"
+    "Modified: / 20.5.1998 / 22:55:54 / cg"
 !
 
 buttonMultiPress:button x:x y:y view:aView
     "forward a button-multi-press event for some view"
 
-    WindowEvent
-        sendEvent:#buttonMultiPress:x:y:
+    aView
+        dispatchEvent:#buttonMultiPress:x:y:
         arguments:(Array with:button with:x with:y)
-        view:aView
 
-    "Created: 24.11.1995 / 19:14:14 / cg"
+"/    WindowEvent
+"/        sendEvent:#buttonMultiPress:x:y:
+"/        arguments:(Array with:button with:x with:y)
+"/        view:aView
+
+    "Created: / 24.11.1995 / 19:14:14 / cg"
+    "Modified: / 20.5.1998 / 22:56:07 / cg"
 !
 
 buttonPress:button x:x y:y view:aView
     "forward a button-press event for some view"
 
-    WindowEvent
-        sendEvent:#buttonPress:x:y:
+    aView
+        dispatchEvent:#buttonPress:x:y:
         arguments:(Array with:button with:x with:y)
-        view:aView
 
-    "Created: 24.11.1995 / 19:14:25 / cg"
+"/    WindowEvent
+"/        sendEvent:#buttonPress:x:y:
+"/        arguments:(Array with:button with:x with:y)
+"/        view:aView
+
+    "Created: / 24.11.1995 / 19:14:25 / cg"
+    "Modified: / 20.5.1998 / 22:56:23 / cg"
 !
 
 buttonRelease:button x:x y:y view:aView
     "forward a button-release event for some view"
 
-    WindowEvent
-        sendEvent:#buttonRelease:x:y:
+    aView
+        dispatchEvent:#buttonRelease:x:y:
         arguments:(Array with:button with:x with:y)
-        view:aView
 
-    "Created: 24.11.1995 / 19:14:36 / cg"
+"/    WindowEvent
+"/        sendEvent:#buttonRelease:x:y:
+"/        arguments:(Array with:button with:x with:y)
+"/        view:aView
+
+    "Created: / 24.11.1995 / 19:14:36 / cg"
+    "Modified: / 20.5.1998 / 22:56:34 / cg"
 !
 
 configureX:x y:y width:w height:h view:aView
@@ -144,35 +171,49 @@
 exposeX:x y:y width:w height:h view:aView
     "forward an expose for some view"
 
-    WindowEvent
-        sendEvent:#exposeX:y:width:height:
+    aView
+        dispatchEvent:#exposeX:y:width:height:
         arguments:(Array with:x with:y with:w with:h)
-        view:aView
 
-    "Created: 24.11.1995 / 19:15:54 / cg"
-    "Modified: 29.1.1997 / 20:40:58 / cg"
+"/    WindowEvent
+"/        sendEvent:#exposeX:y:width:height:
+"/        arguments:(Array with:x with:y with:w with:h)
+"/        view:aView
+
+    "Created: / 24.11.1995 / 19:15:54 / cg"
+    "Modified: / 20.5.1998 / 22:56:49 / cg"
 !
 
 focusInView:aView
     "forward a focusIn event for some view"
 
-    WindowEvent
-        sendEvent:#focusIn
+    aView
+        dispatchEvent:#focusIn
         arguments:nil
-        view:aView
 
-    "Created: 24.11.1995 / 19:16:11 / cg"
+"/   WindowEvent
+"/        sendEvent:#focusIn
+"/        arguments:nil
+"/        view:aView
+
+    "Created: / 24.11.1995 / 19:16:11 / cg"
+    "Modified: / 20.5.1998 / 22:57:04 / cg"
 !
 
 focusOutView:aView 
     "forward a focusOut event for some view"
 
-    WindowEvent
-        sendEvent:#focusOut
+    aView
+        dispatchEvent:#focusOut
         arguments:nil
-        view:aView
 
-    "Created: 24.11.1995 / 19:16:24 / cg"
+"/    WindowEvent
+"/        sendEvent:#focusOut
+"/        arguments:nil
+"/        view:aView
+
+    "Created: / 24.11.1995 / 19:16:24 / cg"
+    "Modified: / 20.5.1998 / 22:57:16 / cg"
 !
 
 graphicsExposeX:x y:y width:w height:h final:final view:aView
@@ -187,13 +228,17 @@
         ]
     ].
 
-    WindowEvent
-        sendEvent:#graphicsExposeX:y:width:height:final:
+    aView
+        dispatchEvent:#graphicsExposeX:y:width:height:final:
         arguments:(Array with:x with:y with:w with:h with:final)
-        view:aView
 
-    "Created: 24.11.1995 / 19:16:38 / cg"
-    "Modified: 29.1.1997 / 20:46:15 / cg"
+"/    WindowEvent
+"/        sendEvent:#graphicsExposeX:y:width:height:final:
+"/        arguments:(Array with:x with:y with:w with:h with:final)
+"/        view:aView
+
+    "Created: / 24.11.1995 / 19:16:38 / cg"
+    "Modified: / 20.5.1998 / 22:57:32 / cg"
 !
 
 keyPress:untranslatedKey x:x y:y view:aView
@@ -205,14 +250,18 @@
 
     xlatedKey := aView graphicsDevice translateKey:untranslatedKey.
     xlatedKey notNil ifTrue:[
-        WindowEvent
-          sendEvent:#keyPress:x:y:
-          arguments:(Array with:xlatedKey with:x with:y)
-          view:aView
+        aView
+            dispatchEvent:#keyPress:x:y:
+            arguments:(Array with:xlatedKey with:x with:y)
+
+"/        WindowEvent
+"/          sendEvent:#keyPress:x:y:
+"/          arguments:(Array with:xlatedKey with:x with:y)
+"/          view:aView
     ]
 
-    "Created: 24.11.1995 / 19:17:23 / cg"
-    "Modified: 28.5.1996 / 20:25:23 / cg"
+    "Created: / 24.11.1995 / 19:17:23 / cg"
+    "Modified: / 20.5.1998 / 22:57:52 / cg"
 !
 
 keyRelease:untranslatedKey x:x y:y view:aView
@@ -224,14 +273,18 @@
 
     xlatedKey := aView graphicsDevice translateKey:untranslatedKey.
     xlatedKey notNil ifTrue:[
-        WindowEvent
-            sendEvent:#keyRelease:x:y:
+        aView
+            dispatchEvent:#keyRelease:x:y:
             arguments:(Array with:xlatedKey with:x with:y)
-            view:aView
+
+"/        WindowEvent
+"/            sendEvent:#keyRelease:x:y:
+"/            arguments:(Array with:xlatedKey with:x with:y)
+"/            view:aView
     ]
 
-    "Created: 24.11.1995 / 19:17:50 / cg"
-    "Modified: 28.5.1996 / 20:25:25 / cg"
+    "Created: / 24.11.1995 / 19:17:50 / cg"
+    "Modified: / 20.5.1998 / 22:58:05 / cg"
 !
 
 mappedView:aView
@@ -262,23 +315,33 @@
 pointerEnter:buttonState x:x y:y view:aView
     "forward a pointer enter for some view"
 
-    WindowEvent
-        sendEvent:#pointerEnter:x:y:
+    aView
+        dispatchEvent:#pointerEnter:x:y:
         arguments:(Array with:buttonState with:x with:y)
-        view:aView
 
-    "Created: 24.11.1995 / 19:18:20 / cg"
+"/    WindowEvent
+"/        sendEvent:#pointerEnter:x:y:
+"/        arguments:(Array with:buttonState with:x with:y)
+"/        view:aView
+
+    "Created: / 24.11.1995 / 19:18:20 / cg"
+    "Modified: / 20.5.1998 / 22:58:20 / cg"
 !
 
 pointerLeave:buttonState view:aView
     "forward a pointer leave for some view"
 
-    WindowEvent
-        sendEvent:#pointerLeave:
+    aView
+        dispatchEvent:#pointerLeave:
         arguments:(Array with:buttonState)
-        view:aView
 
-    "Created: 24.11.1995 / 19:18:30 / cg"
+"/    WindowEvent
+"/        sendEvent:#pointerLeave:
+"/        arguments:(Array with:buttonState)
+"/        view:aView
+
+    "Created: / 24.11.1995 / 19:18:30 / cg"
+    "Modified: / 20.5.1998 / 22:58:35 / cg"
 !
 
 saveAndTerminateView:aView
@@ -361,5 +424,5 @@
 !SynchronousWindowSensor class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/SynchronousWindowSensor.st,v 1.15 1997-08-19 15:28:51 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/SynchronousWindowSensor.st,v 1.16 1998-05-20 23:56:59 cg Exp $'
 ! !
--- a/WEvent.st	Wed May 20 21:56:14 1998 +0200
+++ b/WEvent.st	Thu May 21 01:58:25 1998 +0200
@@ -198,246 +198,6 @@
     "Created: 4.4.1997 / 13:41:44 / cg"
 ! !
 
-!WindowEvent class methodsFor:'forwarding events'!
-
-sendEvent:type arguments:arguments view:view
-    "forward the event represented by type and arguments to the views delegate,
-     the views controller or the view. 
-
-     If there is a delegate, only messages which are understood by it are 
-     forwarded. Also, the delegate is asked if it is willing to handle the event
-     before.
-     Delegated messages get the original view as an extra argument.
-     Delegation has higher priority than controller forwarding."
-
-    ^ self 
-	sendEvent:type 
-	arguments:arguments 
-	view:view 
-	withFocusOn:nil 
-	delegate:true
-!
-
-sendEvent:type arguments:argArray view:view withFocusOn:focusView
-    "forward the event represented by type and arguments to the views delegate,
-     the views controller or the view. 
-     If focusView is nonNil, and it is a keyboard event, it is forwarded to this
-     view (even if there is a delegate).
-
-     If there is a delegate, only messages which are understood by it are 
-     forwarded. Also, the delegate is asked if it is willing to handle the event
-     before.
-     Delegated messages get the original view as an extra argument.
-     Delegation has higher priority than both controller or focusView 
-     forwarding."
-
-    ^ self 
-	sendEvent:type 
-	arguments:argArray 
-	view:view 
-	withFocusOn:focusView 
-	delegate:true 
-!
-
-sendEvent:type arguments:argArray view:view withFocusOn:focusView delegate:doDelegate
-    "forward the event represented by type and arguments to the views delegate,
-     the views controller 
-     (which may be the view itself, if it implements the controller functionality itself). 
-     If focusView is nonNil, and it is a keyboard event, it is forwarded to this
-     view (but not if there was a delegate in the first place).
-
-     If doDelegate is true, keyboard and button events are forwarded to a
-     delegate object (if non-nil). DoDelegate may be passed as true, to
-     handle events which are already delegated.
-     If there is a delegate, only messages which are understood by it are 
-     forwarded. Also, the delegate is asked if it is willing to handle the event
-     before.
-     Delegated messages get the original view as an extra argument.
-     Delegation has higher priority than both controller or focusView 
-     forwarding."
-
-    |delegate selector delegateMessage delegateQuery 
-     eventReceiver controller deviceMessage
-     isKeyEvent isButtonEvent isPointerEvent trans
-     rect x y w h|
-
-    isKeyEvent := isButtonEvent := isPointerEvent := false.
-
-    type == #damage ifTrue:[
-	view shown ifTrue:[
-	    rect := argArray.
-	    x := rect left.
-	    y := rect top.
-	    w := rect width.
-	    h := rect height.
-	    view transformation notNil ifTrue:[
-		view deviceExposeX:x y:y width:w height:h
-	    ] ifFalse:[
-		view exposeX:x y:y width:w height:h
-	    ]
-	].
-	^ self
-    ].
-
-    (type == #'keyPress:x:y:') ifTrue:[
-	isKeyEvent := true.
-	deviceMessage := #'deviceKeyPress:x:y:'.
-	delegateMessage := #'keyPress:x:y:view:'.
-	delegateQuery := #'handlesKeyPress:inView:'.
-    ] ifFalse:[ (type == #'keyRelease:x:y:') ifTrue:[
-	isKeyEvent := true.
-	deviceMessage := #'deviceKeyRelease:x:y:'.
-	delegateMessage := #'keyRelease:x:y:view:'.
-	delegateQuery := #'handlesKeyRelease:inView:'.
-    ] ifFalse:[ (type == #'buttonMotion:x:y:') ifTrue:[
-	isButtonEvent := true.
-	deviceMessage := #'deviceButtonMotion:x:y:'.
-	delegateMessage := #'buttonMotion:x:y:view:'.
-	delegateQuery := #'handlesButtonMotion:inView:'.
-    ] ifFalse:[ (type == #'buttonPress:x:y:') ifTrue:[
-	isButtonEvent := true.
-	deviceMessage := #'deviceButtonPress:x:y:'.
-	delegateMessage := #'buttonPress:x:y:view:'.
-	delegateQuery := #'handlesButtonPress:inView:'.
-    ] ifFalse:[ (type == #'buttonRelease:x:y:') ifTrue:[
-	isButtonEvent := true.
-	deviceMessage := #'deviceButtonRelease:x:y:'.
-	delegateMessage := #'buttonRelease:x:y:view:'.
-	delegateQuery := #'handlesButtonRelease:inView:'.
-    ] ifFalse:[ (type == #'buttonShiftPress:x:y:') ifTrue:[
-	isButtonEvent := true.
-	deviceMessage := #'deviceButtonShiftPress:x:y:'.
-	delegateMessage := #'buttonShiftPress:x:y:view:'.
-	delegateQuery := #'handlesButtonShiftPress:inView:'.
-    ] ifFalse:[ (type == #'buttonMultiPress:x:y:') ifTrue:[
-	isButtonEvent := true.
-	deviceMessage := #'deviceButtonMultiPress:x:y:'.
-	delegateMessage := #'buttonMultiPress:x:y:view:'.
-	delegateQuery := #'handlesButtonMultiPress:inView:'.
-    ] ifFalse:[ (type == #'pointerEnter:x:y:') ifTrue:[
-	isPointerEvent := true.
-	deviceMessage := #'devicePointerEnter:x:y:'.
-	delegateMessage := #'pointerEnter:x:y:view:'.
-	delegateQuery := #'handlesPointerEnter:inView:'.
-    ] ifFalse:[ (type == #'pointerLeave:') ifTrue:[
-	isPointerEvent := true.
-	deviceMessage := type.
-	delegateMessage := #'pointerLeave:view:'.
-	delegateQuery := #'handlesPointerLeave:inView:'.
-    ] ifFalse:[ (type == #'exposeX:y:width:height:') ifTrue:[
-	deviceMessage := #'deviceExposeX:y:width:height:'.
-    ] ifFalse:[ (type == #'graphicsExposeX:y:width:height:final:') ifTrue:[
-	deviceMessage := #'deviceGraphicsExposeX:y:width:height:final:'.
-    ]]]]]]]]]]].
-
-    "
-     if there is a focusView, and its a keyboard event, pass it
-     to that view (or its controller, or its delegate). 
-     In this case, a coordinate which is outside of
-     the focusView (0 @ 0) is passed as x/y coordinates.
-    "
-    (focusView notNil 
-    and:[isKeyEvent]) ifTrue:[
-	self sendEvent:type 
-	     arguments:(Array with:(argArray at:1) with:0 with:0)
-	     view:focusView 
-	     withFocusOn:nil
-	     delegate:doDelegate.
-	^ self
-    ].
-
-    doDelegate ifTrue:[
-	"
-	 handle delegated messages
-	"
-	(isKeyEvent 
-	 or:[isButtonEvent 
-	 or:[isPointerEvent]]) ifTrue:[
-	    delegate := view delegate.
-
-	    "
-	     what a kludge - sending to delegate requires
-	     another selector and an additional argument ...
-	    "
-	    (delegate notNil
-	    and:[delegate respondsTo:delegateMessage]) ifTrue:[
-		"
-		 is the delegate interested in that event ?
-		 (if it does not respond to the handlesXXX message,
-		  we assume: NO)
-		"
-		((delegate respondsTo:delegateQuery) 
-		and:[delegate perform:delegateQuery with:(argArray at:1) with:view]) ifTrue:[
-		    "
-		     mhmh ... have to convert to logical coordinates
-		    "        
-		    (trans := view transformation) notNil ifTrue:[
-			argArray size > 2 ifTrue:[
-			    argArray at:2 put:(trans applyInverseToX:(argArray at:2)).
-			    argArray at:3 put:(trans applyInverseToY:(argArray at:3)).
-			].
-		    ].
-		    argArray isNil ifTrue:[
-			delegate perform:delegateMessage with:view
-		    ] ifFalse:[
-			delegate perform:delegateMessage withArguments:(argArray copyWith:view)
-		    ].
-		    ^ self
-		]
-	    ].
-	].
-    ].
-
-    (isKeyEvent 
-     or:[isButtonEvent 
-     or:[isPointerEvent]]) ifTrue:[
-	view realized ifFalse:[
-	    ^ self
-	]
-    ].
-
-    "
-     if there is a controller, that one gets all user events
-    "
-    eventReceiver := view.
-    (controller := view controller) notNil ifTrue:[  
-	(isKeyEvent 
-	 or:[isButtonEvent 
-	 or:[isPointerEvent
-	 or:[(type == #focusIn)
-	 or:[(type == #focusOut)]]]]) ifTrue:[
-	    eventReceiver := controller.
-	]
-    ].
-
-    "
-     finally, another one:
-     if the view has a transformation, edit the selector
-     from #foo to #deviceFoo...
-     This allows the view to handle the event either in device or
-     logical coordinates. (since the deviceFoo-messages default implementation
-     in DisplaySurface translates and resends).
-     Actually, I could always send deviceXXX without speed penalty
-     (event sending is no high frequency operation), but that just adds 
-     another context to any debuggers walkback, making things less clear.
-    "
-    selector := type.
-
-    view transformation notNil ifTrue:[
-	(isKeyEvent
-	 or:[isButtonEvent
-	 or:[isPointerEvent
-	 or:[(type == #'exposeX:y:width:height:')
-	 or:[(type == #'graphicsExposeX:y:width:height:final:')]]]]) ifTrue:[
-	    selector := deviceMessage
-	]        
-    ].
-
-    eventReceiver perform:selector withArguments:argArray
-
-    "Modified: / 31.10.1997 / 19:54:28 / cg"
-! !
-
 !WindowEvent methodsFor:'accessing'!
 
 arguments
@@ -678,30 +438,6 @@
     "Modified: 5.3.1997 / 11:27:40 / cg"
 ! !
 
-!WindowEvent methodsFor:'sending'!
-
-sendEvent
-    "forward the event represented by the receiver to the views delegate,
-     the views controller or the view. Ignore any focusView."
-
-    self sendEventWithFocusOn:nil
-!
-
-sendEventWithFocusOn:focusView
-    "forward the event represented by the receiver to the views delegate,
-     the views controller or the view. 
-     If focusView is nonNil, and the receiver is a keyboard event, 
-     the event will be forwarded to the focusView instead 
-     (or its delegate, or its controller)."
-
-    self class 
-	sendEvent:type 
-	arguments:arguments 
-	view:view 
-	withFocusOn:focusView
-	delegate:true
-! !
-
 !WindowEvent::InputEvent class methodsFor:'class initialization'!
 
 initialize
@@ -975,5 +711,5 @@
 !WindowEvent class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/Attic/WEvent.st,v 1.54 1998-01-29 22:09:13 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/Attic/WEvent.st,v 1.55 1998-05-20 23:53:32 cg Exp $'
 ! !
--- a/WGroup.st	Wed May 20 21:56:14 1998 +0200
+++ b/WGroup.st	Thu May 21 01:58:25 1998 +0200
@@ -1060,46 +1060,47 @@
 
     <resource: #keyboard (#Escape )>
 
-    |event ignore key focus modalTops modalTop modalDelegate syntheticEvent|
+    |event ignore key focus firstTop evView evType evArgs
+     modalTops modalTop modalDelegate syntheticEvent|
 
     self processExposeEvents.
 
     [mySensor hasEvents] whileTrue:[
-	event := mySensor nextEvent.
-	event notNil ifTrue:[
-	    ignore := false.
-	    focus := focusView.
-	    modalDelegate := false.
+        event := mySensor nextEvent.
+        event notNil ifTrue:[
+            ignore := false.
+            focus := focusView.
+            modalDelegate := false.
 
-	    modalGroup notNil ifTrue:[
-		"/ an incoming event for a masterView, 
-		"/ while being blocked by some other modalView.
+            modalGroup notNil ifTrue:[
+                "/ an incoming event for a masterView, 
+                "/ while being blocked by some other modalView.
 
-		modalTops := modalGroup topViews.
-		modalTops size > 0 ifTrue:[
-		    modalTop := modalTops first.
-		].
+                modalTops := modalGroup topViews.
+                modalTops size > 0 ifTrue:[
+                    modalTop := modalTops first.
+                ].
 
-		event isKeyEvent ifTrue:[
-		    "/ forward keyboard events to my modal
-		    "/ groups first topView ...
-		    modalTop notNil ifTrue:[
-			focus := modalTop.
-			modalDelegate := true.
-		    ]
-		] ifFalse:[
-		    event isFocusEvent ifTrue:[
-			event isFocusInEvent ifTrue:[
-			    "/ focusIn is forwarded to the modalGroup
-			    "/ (since keyboard is forwarded)
-			    event view:modalTop.
-			    focus := modalTop.
-			] ifFalse:[
-			    "/ focusOut goes to both the modal and
-			    "/ the blocked main-group
-			    "/ (actually, only the very first focusOut
-			    "/  is needed in the mainGroup (to turn off the cursor)
-			    "/  all others are only needed in the modalGroup)
+                event isKeyEvent ifTrue:[
+                    "/ forward keyboard events to my modal
+                    "/ groups first topView ...
+                    modalTop notNil ifTrue:[
+                        focus := modalTop.
+                        modalDelegate := true.
+                    ]
+                ] ifFalse:[
+                    event isFocusEvent ifTrue:[
+                        event isFocusInEvent ifTrue:[
+                            "/ focusIn is forwarded to the modalGroup
+                            "/ (since keyboard is forwarded)
+                            event view:modalTop.
+                            focus := modalTop.
+                        ] ifFalse:[
+                            "/ focusOut goes to both the modal and
+                            "/ the blocked main-group
+                            "/ (actually, only the very first focusOut
+                            "/  is needed in the mainGroup (to turn off the cursor)
+                            "/  all others are only needed in the modalGroup)
 "/                            syntheticEvent := event copy.
 "/                            syntheticEvent view:modalTop.
 "/                            LastEventQuerySignal handle:[:ex |
@@ -1107,93 +1108,103 @@
 "/                            ] do:[
 "/                                syntheticEvent sendEventWithFocusOn:nil.
 "/                            ].
-			    event view:modalTop.
-			].
-			modalDelegate := true.
-		    ] ifFalse:[
-			event isPointerLeaveEvent ifTrue:[
-			] ifFalse:[
-			    event isUserEvent ifTrue:[
-				ignore := true
-			    ]
-			]
-		    ]
-		]
-	    ].
+                            event view:modalTop.
+                        ].
+                        modalDelegate := true.
+                    ] ifFalse:[
+                        event isPointerLeaveEvent ifTrue:[
+                        ] ifFalse:[
+                            event isUserEvent ifTrue:[
+                                ignore := true
+                            ]
+                        ]
+                    ]
+                ]
+            ].
 
-	    ignore ifFalse:[
-		(views notNil or:[topViews notNil]) ifTrue:[
-		    LastEventQuerySignal handle:[:ex |
-			ex proceedWith:event
-		    ] do:[
-			(preEventHook  notNil 
-			and:[preEventHook processEvent:event]) ifTrue:[
-			    ignore := true.
-			].
+            ignore ifFalse:[
+                (views notNil or:[topViews notNil]) ifTrue:[
+                    LastEventQuerySignal handle:[:ex |
+                        ex proceedWith:event
+                    ] do:[
+                        (preEventHook  notNil 
+                        and:[preEventHook processEvent:event]) ifTrue:[
+                            ignore := true.
+                        ].
 
-			ignore ifFalse:[
-			    event isKeyPressEvent ifTrue:[
-				key := event key.
+                        ignore ifFalse:[
+                            evView := event view.
+
+                            event isKeyPressEvent ifTrue:[
+                                key := event key.
 
-				key == #Escape ifTrue:[
-				    modalDelegate ifTrue:[
-					modalTop hideRequest
-				    ] ifFalse:[
-					isModal ifTrue:[
-					    topViews first hideRequest
-					]
-				    ]
-				]
-			    ].
-			    event isPointerEnterEvent ifTrue:[
-				pointerView := event view
-			    ].
-			    event isPointerLeaveEvent ifTrue:[
-				pointerView := nil
-			    ].
+                                key == #Escape ifTrue:[
+                                    modalDelegate ifTrue:[
+                                        modalTop hideRequest
+                                    ] ifFalse:[
+                                        isModal ifTrue:[
+                                            topViews first hideRequest
+                                        ]
+                                    ]
+                                ]
+                            ] ifFalse:[
+                                "/
+                                "/ keep track of which view has the pointer
+                                "/
+                                event isPointerEnterEvent ifTrue:[
+                                    pointerView := evView
+                                ] ifFalse:[
+                                    event isPointerLeaveEvent ifTrue:[
+                                        pointerView := nil
+                                    ]
+                                ]
+                            ].
+
+                            "/
+                            "/  buttonPress events turn off explicit focus, and revert
+                            "/  to implicit focus control
+                            "/
+                            (focusView notNil
+                            and:[event isButtonPressEvent]) ifTrue:[
+                                self focusView:nil
+                            ].
 
-			    ignore ifFalse:[
-				"/
-				"/  buttonPress events turn off explicit focus, and revert
-				"/  to implicit focus control
-				"/
-				(focusView notNil
-				and:[event isButtonPressEvent]) ifTrue:[
-				    self focusView:nil
-				].
-				"/
-				"/ let the event forward itself
-				"/
-				LastActiveGroup := self.
-				LastActiveProcess := Processor activeProcess.
+                            LastActiveGroup := self.
+                            LastActiveProcess := Processor activeProcess.
+
+                            "
+                             if there is no view information in the event,
+                             it must have been sent directly to the sensor.
+                             Send it to the first topView.
+                            "
+                            evType := event type.
+                            evArgs := event arguments.
 
-				"
-				 if there is no view information in the event,
-				 it must have been sent directly to the sensor.
-				 Send it to the first topView.
-				"
-				event view isNil ifTrue:[
-				    topViews first notNil ifTrue:[
-					topViews first perform:event type withArguments:event arguments
-				    ]
-				] ifFalse:[
-				    event sendEventWithFocusOn:focus.
-				]
-			    ]
-			].
+                            evView isNil ifTrue:[
+                                (firstTop := topViews first) notNil ifTrue:[
+                                    firstTop perform:evType withArguments:evArgs
+                                ]
+                            ] ifFalse:[
+                                evView
+                                    dispatchEvent:evType 
+                                    arguments:evArgs 
+                                    withFocusOn:focus 
+                                    delegate:true
+                            ]
+                        ].
 
-			postEventHook notNil ifTrue:[
-			    postEventHook processEvent:event
-			].
-		    ]
-		]
-	    ].
-	    event := nil.
-	].
+                        postEventHook notNil ifTrue:[
+                            postEventHook processEvent:event
+                        ].
+                    ]
+                ]
+            ].
+            event := nil.
+        ].
     ]
 
-    "Created: 5.3.1997 / 11:33:11 / cg"
-    "Modified: 20.8.1997 / 15:23:31 / cg"
+    "Created: / 5.3.1997 / 11:33:11 / cg"
+    "Modified: / 21.5.1998 / 00:14:59 / cg"
 !
 
 processExposeEvents
@@ -1217,8 +1228,9 @@
                 ] do:[
                     (preEventHook notNil 
                     and:[preEventHook processEvent:event]) ifFalse:[
+                        view := event view.
+
                         event isDamage ifTrue:[
-                            view := event view.
                             "/
                             "/ if the view is no longer shown (iconified or closed),
                             "/ this is a leftover event and ignored.
@@ -1227,21 +1239,13 @@
                                 LastActiveGroup := self.
                                 LastActiveProcess := thisProcess.
 
-"/                                rect := event rectangle.
-"/                                x := rect left.
-"/                                y := rect top.
-"/                                w := rect width.
-"/                                h := rect height.
-"/
-"/                                view transformation notNil ifTrue:[
-"/                                    view deviceExposeX:x y:y width:w height:h
-"/                                ] ifFalse:[
-"/                                    view exposeX:x y:y width:w height:h
-"/                                ]
+                                view
+                                    dispatchEvent:(event type) 
+                                    arguments:(event arguments) 
+                                    withFocusOn:nil 
+                                    delegate:true
 
-                                event sendEventWithFocusOn:nil.
-
-                            ] ifFalse:[
+"/                            ] ifFalse:[
 "/                                ('WGROUP: damage for ' , view displayString , ' ignored') infoPrintCR.
                             ]
                         ] ifFalse:[
@@ -1250,7 +1254,12 @@
                             "
                             LastActiveGroup := self.
                             LastActiveProcess := thisProcess.
-                            event sendEventWithFocusOn:nil.
+                            "/ event sendEventWithFocusOn:nil.
+                            view
+                                dispatchEvent:(event type) 
+                                arguments:(event arguments) 
+                                withFocusOn:nil 
+                                delegate:true
                         ]
                     ].
                     postEventHook notNil ifTrue:[
@@ -1261,7 +1270,7 @@
         ]
     ]
 
-    "Modified: / 5.4.1998 / 11:35:21 / cg"
+    "Modified: / 21.5.1998 / 00:17:18 / cg"
 !
 
 processRealExposeEvents
@@ -1744,6 +1753,6 @@
 !WindowGroup class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/Attic/WGroup.st,v 1.134 1998-05-16 15:35:31 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/Attic/WGroup.st,v 1.135 1998-05-20 23:57:43 cg Exp $'
 ! !
 WindowGroup initialize!
--- a/WSensor.st	Wed May 20 21:56:14 1998 +0200
+++ b/WSensor.st	Thu May 21 01:58:25 1998 +0200
@@ -689,10 +689,10 @@
              type:#buttonMotion:x:y:
              arguments:args.
     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
-                          button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
+       button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
     self pushEvent:ev.
 
-    "Modified: 13.8.1997 / 22:19:06 / cg"
+    "Modified: / 21.5.1998 / 00:20:30 / cg"
 !
 
 buttonMultiPress:button x:x y:y view:aView
@@ -718,10 +718,10 @@
              type:#buttonMultiPress:x:y:
              arguments:(Array with:button with:x with:y).
     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
-                          button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
+       button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
     self pushEvent:ev.
 
-    "Modified: 13.8.1997 / 22:19:11 / cg"
+    "Modified: / 21.5.1998 / 00:20:40 / cg"
 !
 
 buttonPress:button x:x y:y view:aView
@@ -747,10 +747,10 @@
              type:#buttonPress:x:y:
              arguments:(Array with:button with:x with:y).
     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
-                          button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
+       button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
     self pushEvent:ev.
 
-    "Modified: 13.8.1997 / 22:19:13 / cg"
+    "Modified: / 21.5.1998 / 00:20:44 / cg"
 !
 
 buttonRelease:button x:x y:y view:aView
@@ -776,23 +776,24 @@
              type:#buttonRelease:x:y:
              arguments:(Array with:button with:x with:y).
     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
-                          button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
+       button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
     self pushEvent:ev.
 
-    "Modified: 13.8.1997 / 22:19:16 / cg"
+    "Modified: / 21.5.1998 / 00:21:19 / cg"
 !
 
 clientMessage:type format:format eventData:data view:aView
     "some other data sent to a view.
      This is an X-specific event."
 
-    self pushEvent:(WindowEvent clientEvent
+    self pushEvent:(WindowEvent 
+                        clientEvent
                              for:aView
                              type:#clientMessage:format:eventData:
                              arguments:(Array with:type with:format with:data)).
 
-    "Created: 4.4.1997 / 17:51:08 / cg"
-    "Modified: 4.4.1997 / 18:53:50 / cg"
+    "Created: / 4.4.1997 / 17:51:08 / cg"
+    "Modified: / 21.5.1998 / 00:20:56 / cg"
 !
 
 configureX:x y:y width:w height:h view:aView
@@ -2467,6 +2468,6 @@
 !WindowSensor class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/Attic/WSensor.st,v 1.121 1998-05-20 13:39:07 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/Attic/WSensor.st,v 1.122 1998-05-20 23:58:25 cg Exp $'
 ! !
 WindowSensor initialize!
--- a/WindowEvent.st	Wed May 20 21:56:14 1998 +0200
+++ b/WindowEvent.st	Thu May 21 01:58:25 1998 +0200
@@ -198,246 +198,6 @@
     "Created: 4.4.1997 / 13:41:44 / cg"
 ! !
 
-!WindowEvent class methodsFor:'forwarding events'!
-
-sendEvent:type arguments:arguments view:view
-    "forward the event represented by type and arguments to the views delegate,
-     the views controller or the view. 
-
-     If there is a delegate, only messages which are understood by it are 
-     forwarded. Also, the delegate is asked if it is willing to handle the event
-     before.
-     Delegated messages get the original view as an extra argument.
-     Delegation has higher priority than controller forwarding."
-
-    ^ self 
-	sendEvent:type 
-	arguments:arguments 
-	view:view 
-	withFocusOn:nil 
-	delegate:true
-!
-
-sendEvent:type arguments:argArray view:view withFocusOn:focusView
-    "forward the event represented by type and arguments to the views delegate,
-     the views controller or the view. 
-     If focusView is nonNil, and it is a keyboard event, it is forwarded to this
-     view (even if there is a delegate).
-
-     If there is a delegate, only messages which are understood by it are 
-     forwarded. Also, the delegate is asked if it is willing to handle the event
-     before.
-     Delegated messages get the original view as an extra argument.
-     Delegation has higher priority than both controller or focusView 
-     forwarding."
-
-    ^ self 
-	sendEvent:type 
-	arguments:argArray 
-	view:view 
-	withFocusOn:focusView 
-	delegate:true 
-!
-
-sendEvent:type arguments:argArray view:view withFocusOn:focusView delegate:doDelegate
-    "forward the event represented by type and arguments to the views delegate,
-     the views controller 
-     (which may be the view itself, if it implements the controller functionality itself). 
-     If focusView is nonNil, and it is a keyboard event, it is forwarded to this
-     view (but not if there was a delegate in the first place).
-
-     If doDelegate is true, keyboard and button events are forwarded to a
-     delegate object (if non-nil). DoDelegate may be passed as true, to
-     handle events which are already delegated.
-     If there is a delegate, only messages which are understood by it are 
-     forwarded. Also, the delegate is asked if it is willing to handle the event
-     before.
-     Delegated messages get the original view as an extra argument.
-     Delegation has higher priority than both controller or focusView 
-     forwarding."
-
-    |delegate selector delegateMessage delegateQuery 
-     eventReceiver controller deviceMessage
-     isKeyEvent isButtonEvent isPointerEvent trans
-     rect x y w h|
-
-    isKeyEvent := isButtonEvent := isPointerEvent := false.
-
-    type == #damage ifTrue:[
-	view shown ifTrue:[
-	    rect := argArray.
-	    x := rect left.
-	    y := rect top.
-	    w := rect width.
-	    h := rect height.
-	    view transformation notNil ifTrue:[
-		view deviceExposeX:x y:y width:w height:h
-	    ] ifFalse:[
-		view exposeX:x y:y width:w height:h
-	    ]
-	].
-	^ self
-    ].
-
-    (type == #'keyPress:x:y:') ifTrue:[
-	isKeyEvent := true.
-	deviceMessage := #'deviceKeyPress:x:y:'.
-	delegateMessage := #'keyPress:x:y:view:'.
-	delegateQuery := #'handlesKeyPress:inView:'.
-    ] ifFalse:[ (type == #'keyRelease:x:y:') ifTrue:[
-	isKeyEvent := true.
-	deviceMessage := #'deviceKeyRelease:x:y:'.
-	delegateMessage := #'keyRelease:x:y:view:'.
-	delegateQuery := #'handlesKeyRelease:inView:'.
-    ] ifFalse:[ (type == #'buttonMotion:x:y:') ifTrue:[
-	isButtonEvent := true.
-	deviceMessage := #'deviceButtonMotion:x:y:'.
-	delegateMessage := #'buttonMotion:x:y:view:'.
-	delegateQuery := #'handlesButtonMotion:inView:'.
-    ] ifFalse:[ (type == #'buttonPress:x:y:') ifTrue:[
-	isButtonEvent := true.
-	deviceMessage := #'deviceButtonPress:x:y:'.
-	delegateMessage := #'buttonPress:x:y:view:'.
-	delegateQuery := #'handlesButtonPress:inView:'.
-    ] ifFalse:[ (type == #'buttonRelease:x:y:') ifTrue:[
-	isButtonEvent := true.
-	deviceMessage := #'deviceButtonRelease:x:y:'.
-	delegateMessage := #'buttonRelease:x:y:view:'.
-	delegateQuery := #'handlesButtonRelease:inView:'.
-    ] ifFalse:[ (type == #'buttonShiftPress:x:y:') ifTrue:[
-	isButtonEvent := true.
-	deviceMessage := #'deviceButtonShiftPress:x:y:'.
-	delegateMessage := #'buttonShiftPress:x:y:view:'.
-	delegateQuery := #'handlesButtonShiftPress:inView:'.
-    ] ifFalse:[ (type == #'buttonMultiPress:x:y:') ifTrue:[
-	isButtonEvent := true.
-	deviceMessage := #'deviceButtonMultiPress:x:y:'.
-	delegateMessage := #'buttonMultiPress:x:y:view:'.
-	delegateQuery := #'handlesButtonMultiPress:inView:'.
-    ] ifFalse:[ (type == #'pointerEnter:x:y:') ifTrue:[
-	isPointerEvent := true.
-	deviceMessage := #'devicePointerEnter:x:y:'.
-	delegateMessage := #'pointerEnter:x:y:view:'.
-	delegateQuery := #'handlesPointerEnter:inView:'.
-    ] ifFalse:[ (type == #'pointerLeave:') ifTrue:[
-	isPointerEvent := true.
-	deviceMessage := type.
-	delegateMessage := #'pointerLeave:view:'.
-	delegateQuery := #'handlesPointerLeave:inView:'.
-    ] ifFalse:[ (type == #'exposeX:y:width:height:') ifTrue:[
-	deviceMessage := #'deviceExposeX:y:width:height:'.
-    ] ifFalse:[ (type == #'graphicsExposeX:y:width:height:final:') ifTrue:[
-	deviceMessage := #'deviceGraphicsExposeX:y:width:height:final:'.
-    ]]]]]]]]]]].
-
-    "
-     if there is a focusView, and its a keyboard event, pass it
-     to that view (or its controller, or its delegate). 
-     In this case, a coordinate which is outside of
-     the focusView (0 @ 0) is passed as x/y coordinates.
-    "
-    (focusView notNil 
-    and:[isKeyEvent]) ifTrue:[
-	self sendEvent:type 
-	     arguments:(Array with:(argArray at:1) with:0 with:0)
-	     view:focusView 
-	     withFocusOn:nil
-	     delegate:doDelegate.
-	^ self
-    ].
-
-    doDelegate ifTrue:[
-	"
-	 handle delegated messages
-	"
-	(isKeyEvent 
-	 or:[isButtonEvent 
-	 or:[isPointerEvent]]) ifTrue:[
-	    delegate := view delegate.
-
-	    "
-	     what a kludge - sending to delegate requires
-	     another selector and an additional argument ...
-	    "
-	    (delegate notNil
-	    and:[delegate respondsTo:delegateMessage]) ifTrue:[
-		"
-		 is the delegate interested in that event ?
-		 (if it does not respond to the handlesXXX message,
-		  we assume: NO)
-		"
-		((delegate respondsTo:delegateQuery) 
-		and:[delegate perform:delegateQuery with:(argArray at:1) with:view]) ifTrue:[
-		    "
-		     mhmh ... have to convert to logical coordinates
-		    "        
-		    (trans := view transformation) notNil ifTrue:[
-			argArray size > 2 ifTrue:[
-			    argArray at:2 put:(trans applyInverseToX:(argArray at:2)).
-			    argArray at:3 put:(trans applyInverseToY:(argArray at:3)).
-			].
-		    ].
-		    argArray isNil ifTrue:[
-			delegate perform:delegateMessage with:view
-		    ] ifFalse:[
-			delegate perform:delegateMessage withArguments:(argArray copyWith:view)
-		    ].
-		    ^ self
-		]
-	    ].
-	].
-    ].
-
-    (isKeyEvent 
-     or:[isButtonEvent 
-     or:[isPointerEvent]]) ifTrue:[
-	view realized ifFalse:[
-	    ^ self
-	]
-    ].
-
-    "
-     if there is a controller, that one gets all user events
-    "
-    eventReceiver := view.
-    (controller := view controller) notNil ifTrue:[  
-	(isKeyEvent 
-	 or:[isButtonEvent 
-	 or:[isPointerEvent
-	 or:[(type == #focusIn)
-	 or:[(type == #focusOut)]]]]) ifTrue:[
-	    eventReceiver := controller.
-	]
-    ].
-
-    "
-     finally, another one:
-     if the view has a transformation, edit the selector
-     from #foo to #deviceFoo...
-     This allows the view to handle the event either in device or
-     logical coordinates. (since the deviceFoo-messages default implementation
-     in DisplaySurface translates and resends).
-     Actually, I could always send deviceXXX without speed penalty
-     (event sending is no high frequency operation), but that just adds 
-     another context to any debuggers walkback, making things less clear.
-    "
-    selector := type.
-
-    view transformation notNil ifTrue:[
-	(isKeyEvent
-	 or:[isButtonEvent
-	 or:[isPointerEvent
-	 or:[(type == #'exposeX:y:width:height:')
-	 or:[(type == #'graphicsExposeX:y:width:height:final:')]]]]) ifTrue:[
-	    selector := deviceMessage
-	]        
-    ].
-
-    eventReceiver perform:selector withArguments:argArray
-
-    "Modified: / 31.10.1997 / 19:54:28 / cg"
-! !
-
 !WindowEvent methodsFor:'accessing'!
 
 arguments
@@ -678,30 +438,6 @@
     "Modified: 5.3.1997 / 11:27:40 / cg"
 ! !
 
-!WindowEvent methodsFor:'sending'!
-
-sendEvent
-    "forward the event represented by the receiver to the views delegate,
-     the views controller or the view. Ignore any focusView."
-
-    self sendEventWithFocusOn:nil
-!
-
-sendEventWithFocusOn:focusView
-    "forward the event represented by the receiver to the views delegate,
-     the views controller or the view. 
-     If focusView is nonNil, and the receiver is a keyboard event, 
-     the event will be forwarded to the focusView instead 
-     (or its delegate, or its controller)."
-
-    self class 
-	sendEvent:type 
-	arguments:arguments 
-	view:view 
-	withFocusOn:focusView
-	delegate:true
-! !
-
 !WindowEvent::InputEvent class methodsFor:'class initialization'!
 
 initialize
@@ -975,5 +711,5 @@
 !WindowEvent class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/WindowEvent.st,v 1.54 1998-01-29 22:09:13 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/WindowEvent.st,v 1.55 1998-05-20 23:53:32 cg Exp $'
 ! !
--- a/WindowGroup.st	Wed May 20 21:56:14 1998 +0200
+++ b/WindowGroup.st	Thu May 21 01:58:25 1998 +0200
@@ -1060,46 +1060,47 @@
 
     <resource: #keyboard (#Escape )>
 
-    |event ignore key focus modalTops modalTop modalDelegate syntheticEvent|
+    |event ignore key focus firstTop evView evType evArgs
+     modalTops modalTop modalDelegate syntheticEvent|
 
     self processExposeEvents.
 
     [mySensor hasEvents] whileTrue:[
-	event := mySensor nextEvent.
-	event notNil ifTrue:[
-	    ignore := false.
-	    focus := focusView.
-	    modalDelegate := false.
+        event := mySensor nextEvent.
+        event notNil ifTrue:[
+            ignore := false.
+            focus := focusView.
+            modalDelegate := false.
 
-	    modalGroup notNil ifTrue:[
-		"/ an incoming event for a masterView, 
-		"/ while being blocked by some other modalView.
+            modalGroup notNil ifTrue:[
+                "/ an incoming event for a masterView, 
+                "/ while being blocked by some other modalView.
 
-		modalTops := modalGroup topViews.
-		modalTops size > 0 ifTrue:[
-		    modalTop := modalTops first.
-		].
+                modalTops := modalGroup topViews.
+                modalTops size > 0 ifTrue:[
+                    modalTop := modalTops first.
+                ].
 
-		event isKeyEvent ifTrue:[
-		    "/ forward keyboard events to my modal
-		    "/ groups first topView ...
-		    modalTop notNil ifTrue:[
-			focus := modalTop.
-			modalDelegate := true.
-		    ]
-		] ifFalse:[
-		    event isFocusEvent ifTrue:[
-			event isFocusInEvent ifTrue:[
-			    "/ focusIn is forwarded to the modalGroup
-			    "/ (since keyboard is forwarded)
-			    event view:modalTop.
-			    focus := modalTop.
-			] ifFalse:[
-			    "/ focusOut goes to both the modal and
-			    "/ the blocked main-group
-			    "/ (actually, only the very first focusOut
-			    "/  is needed in the mainGroup (to turn off the cursor)
-			    "/  all others are only needed in the modalGroup)
+                event isKeyEvent ifTrue:[
+                    "/ forward keyboard events to my modal
+                    "/ groups first topView ...
+                    modalTop notNil ifTrue:[
+                        focus := modalTop.
+                        modalDelegate := true.
+                    ]
+                ] ifFalse:[
+                    event isFocusEvent ifTrue:[
+                        event isFocusInEvent ifTrue:[
+                            "/ focusIn is forwarded to the modalGroup
+                            "/ (since keyboard is forwarded)
+                            event view:modalTop.
+                            focus := modalTop.
+                        ] ifFalse:[
+                            "/ focusOut goes to both the modal and
+                            "/ the blocked main-group
+                            "/ (actually, only the very first focusOut
+                            "/  is needed in the mainGroup (to turn off the cursor)
+                            "/  all others are only needed in the modalGroup)
 "/                            syntheticEvent := event copy.
 "/                            syntheticEvent view:modalTop.
 "/                            LastEventQuerySignal handle:[:ex |
@@ -1107,93 +1108,103 @@
 "/                            ] do:[
 "/                                syntheticEvent sendEventWithFocusOn:nil.
 "/                            ].
-			    event view:modalTop.
-			].
-			modalDelegate := true.
-		    ] ifFalse:[
-			event isPointerLeaveEvent ifTrue:[
-			] ifFalse:[
-			    event isUserEvent ifTrue:[
-				ignore := true
-			    ]
-			]
-		    ]
-		]
-	    ].
+                            event view:modalTop.
+                        ].
+                        modalDelegate := true.
+                    ] ifFalse:[
+                        event isPointerLeaveEvent ifTrue:[
+                        ] ifFalse:[
+                            event isUserEvent ifTrue:[
+                                ignore := true
+                            ]
+                        ]
+                    ]
+                ]
+            ].
 
-	    ignore ifFalse:[
-		(views notNil or:[topViews notNil]) ifTrue:[
-		    LastEventQuerySignal handle:[:ex |
-			ex proceedWith:event
-		    ] do:[
-			(preEventHook  notNil 
-			and:[preEventHook processEvent:event]) ifTrue:[
-			    ignore := true.
-			].
+            ignore ifFalse:[
+                (views notNil or:[topViews notNil]) ifTrue:[
+                    LastEventQuerySignal handle:[:ex |
+                        ex proceedWith:event
+                    ] do:[
+                        (preEventHook  notNil 
+                        and:[preEventHook processEvent:event]) ifTrue:[
+                            ignore := true.
+                        ].
 
-			ignore ifFalse:[
-			    event isKeyPressEvent ifTrue:[
-				key := event key.
+                        ignore ifFalse:[
+                            evView := event view.
+
+                            event isKeyPressEvent ifTrue:[
+                                key := event key.
 
-				key == #Escape ifTrue:[
-				    modalDelegate ifTrue:[
-					modalTop hideRequest
-				    ] ifFalse:[
-					isModal ifTrue:[
-					    topViews first hideRequest
-					]
-				    ]
-				]
-			    ].
-			    event isPointerEnterEvent ifTrue:[
-				pointerView := event view
-			    ].
-			    event isPointerLeaveEvent ifTrue:[
-				pointerView := nil
-			    ].
+                                key == #Escape ifTrue:[
+                                    modalDelegate ifTrue:[
+                                        modalTop hideRequest
+                                    ] ifFalse:[
+                                        isModal ifTrue:[
+                                            topViews first hideRequest
+                                        ]
+                                    ]
+                                ]
+                            ] ifFalse:[
+                                "/
+                                "/ keep track of which view has the pointer
+                                "/
+                                event isPointerEnterEvent ifTrue:[
+                                    pointerView := evView
+                                ] ifFalse:[
+                                    event isPointerLeaveEvent ifTrue:[
+                                        pointerView := nil
+                                    ]
+                                ]
+                            ].
+
+                            "/
+                            "/  buttonPress events turn off explicit focus, and revert
+                            "/  to implicit focus control
+                            "/
+                            (focusView notNil
+                            and:[event isButtonPressEvent]) ifTrue:[
+                                self focusView:nil
+                            ].
 
-			    ignore ifFalse:[
-				"/
-				"/  buttonPress events turn off explicit focus, and revert
-				"/  to implicit focus control
-				"/
-				(focusView notNil
-				and:[event isButtonPressEvent]) ifTrue:[
-				    self focusView:nil
-				].
-				"/
-				"/ let the event forward itself
-				"/
-				LastActiveGroup := self.
-				LastActiveProcess := Processor activeProcess.
+                            LastActiveGroup := self.
+                            LastActiveProcess := Processor activeProcess.
+
+                            "
+                             if there is no view information in the event,
+                             it must have been sent directly to the sensor.
+                             Send it to the first topView.
+                            "
+                            evType := event type.
+                            evArgs := event arguments.
 
-				"
-				 if there is no view information in the event,
-				 it must have been sent directly to the sensor.
-				 Send it to the first topView.
-				"
-				event view isNil ifTrue:[
-				    topViews first notNil ifTrue:[
-					topViews first perform:event type withArguments:event arguments
-				    ]
-				] ifFalse:[
-				    event sendEventWithFocusOn:focus.
-				]
-			    ]
-			].
+                            evView isNil ifTrue:[
+                                (firstTop := topViews first) notNil ifTrue:[
+                                    firstTop perform:evType withArguments:evArgs
+                                ]
+                            ] ifFalse:[
+                                evView
+                                    dispatchEvent:evType 
+                                    arguments:evArgs 
+                                    withFocusOn:focus 
+                                    delegate:true
+                            ]
+                        ].
 
-			postEventHook notNil ifTrue:[
-			    postEventHook processEvent:event
-			].
-		    ]
-		]
-	    ].
-	    event := nil.
-	].
+                        postEventHook notNil ifTrue:[
+                            postEventHook processEvent:event
+                        ].
+                    ]
+                ]
+            ].
+            event := nil.
+        ].
     ]
 
-    "Created: 5.3.1997 / 11:33:11 / cg"
-    "Modified: 20.8.1997 / 15:23:31 / cg"
+    "Created: / 5.3.1997 / 11:33:11 / cg"
+    "Modified: / 21.5.1998 / 00:14:59 / cg"
 !
 
 processExposeEvents
@@ -1217,8 +1228,9 @@
                 ] do:[
                     (preEventHook notNil 
                     and:[preEventHook processEvent:event]) ifFalse:[
+                        view := event view.
+
                         event isDamage ifTrue:[
-                            view := event view.
                             "/
                             "/ if the view is no longer shown (iconified or closed),
                             "/ this is a leftover event and ignored.
@@ -1227,21 +1239,13 @@
                                 LastActiveGroup := self.
                                 LastActiveProcess := thisProcess.
 
-"/                                rect := event rectangle.
-"/                                x := rect left.
-"/                                y := rect top.
-"/                                w := rect width.
-"/                                h := rect height.
-"/
-"/                                view transformation notNil ifTrue:[
-"/                                    view deviceExposeX:x y:y width:w height:h
-"/                                ] ifFalse:[
-"/                                    view exposeX:x y:y width:w height:h
-"/                                ]
+                                view
+                                    dispatchEvent:(event type) 
+                                    arguments:(event arguments) 
+                                    withFocusOn:nil 
+                                    delegate:true
 
-                                event sendEventWithFocusOn:nil.
-
-                            ] ifFalse:[
+"/                            ] ifFalse:[
 "/                                ('WGROUP: damage for ' , view displayString , ' ignored') infoPrintCR.
                             ]
                         ] ifFalse:[
@@ -1250,7 +1254,12 @@
                             "
                             LastActiveGroup := self.
                             LastActiveProcess := thisProcess.
-                            event sendEventWithFocusOn:nil.
+                            "/ event sendEventWithFocusOn:nil.
+                            view
+                                dispatchEvent:(event type) 
+                                arguments:(event arguments) 
+                                withFocusOn:nil 
+                                delegate:true
                         ]
                     ].
                     postEventHook notNil ifTrue:[
@@ -1261,7 +1270,7 @@
         ]
     ]
 
-    "Modified: / 5.4.1998 / 11:35:21 / cg"
+    "Modified: / 21.5.1998 / 00:17:18 / cg"
 !
 
 processRealExposeEvents
@@ -1744,6 +1753,6 @@
 !WindowGroup class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/WindowGroup.st,v 1.134 1998-05-16 15:35:31 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/WindowGroup.st,v 1.135 1998-05-20 23:57:43 cg Exp $'
 ! !
 WindowGroup initialize!
--- a/WindowSensor.st	Wed May 20 21:56:14 1998 +0200
+++ b/WindowSensor.st	Thu May 21 01:58:25 1998 +0200
@@ -689,10 +689,10 @@
              type:#buttonMotion:x:y:
              arguments:args.
     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
-                          button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
+       button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
     self pushEvent:ev.
 
-    "Modified: 13.8.1997 / 22:19:06 / cg"
+    "Modified: / 21.5.1998 / 00:20:30 / cg"
 !
 
 buttonMultiPress:button x:x y:y view:aView
@@ -718,10 +718,10 @@
              type:#buttonMultiPress:x:y:
              arguments:(Array with:button with:x with:y).
     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
-                          button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
+       button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
     self pushEvent:ev.
 
-    "Modified: 13.8.1997 / 22:19:11 / cg"
+    "Modified: / 21.5.1998 / 00:20:40 / cg"
 !
 
 buttonPress:button x:x y:y view:aView
@@ -747,10 +747,10 @@
              type:#buttonPress:x:y:
              arguments:(Array with:button with:x with:y).
     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
-                          button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
+       button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
     self pushEvent:ev.
 
-    "Modified: 13.8.1997 / 22:19:13 / cg"
+    "Modified: / 21.5.1998 / 00:20:44 / cg"
 !
 
 buttonRelease:button x:x y:y view:aView
@@ -776,23 +776,24 @@
              type:#buttonRelease:x:y:
              arguments:(Array with:button with:x with:y).
     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
-                          button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
+       button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
     self pushEvent:ev.
 
-    "Modified: 13.8.1997 / 22:19:16 / cg"
+    "Modified: / 21.5.1998 / 00:21:19 / cg"
 !
 
 clientMessage:type format:format eventData:data view:aView
     "some other data sent to a view.
      This is an X-specific event."
 
-    self pushEvent:(WindowEvent clientEvent
+    self pushEvent:(WindowEvent 
+                        clientEvent
                              for:aView
                              type:#clientMessage:format:eventData:
                              arguments:(Array with:type with:format with:data)).
 
-    "Created: 4.4.1997 / 17:51:08 / cg"
-    "Modified: 4.4.1997 / 18:53:50 / cg"
+    "Created: / 4.4.1997 / 17:51:08 / cg"
+    "Modified: / 21.5.1998 / 00:20:56 / cg"
 !
 
 configureX:x y:y width:w height:h view:aView
@@ -2467,6 +2468,6 @@
 !WindowSensor class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/WindowSensor.st,v 1.121 1998-05-20 13:39:07 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/WindowSensor.st,v 1.122 1998-05-20 23:58:25 cg Exp $'
 ! !
 WindowSensor initialize!