[squeak-dev] Re: ActiveEvent/Object>>currentEvent broken by Morphic-mt.1283?

marcel.taeumel Marcel.Taeumel at hpi.de
Sat Aug 20 10:28:26 UTC 2016


marcel.taeumel wrote
> 
> tim Rowledge wrote
>> After loading my development scratch code into the rc1 image I got a
>> really weird dNU where an instvar of PaintCanvas is nil a few bytecodes
>> after it is set to definitely-not-nil. The code is pretty simple - 
>> !PaintCanvas methodsFor: 'event handling' stamp: 'tpr 8/19/2016 18:30'!
>> selectRectangleStartingAt: aPoint
>> 	"Set selectionRect to a rectangular area starting at the given canvas
>> point."
>> 
>> 	| p |
>> 	selectionRect := aPoint extent: 0 at 0.
>> 	showSelection := true.
>> 	World activeHand showTemporaryCursor: nil.
>> 	Cursor crossHair showWhile: [
>> 		[self currentEvent anyButtonPressed] whileTrue: [
>> 			p := self cursorPoint.
>> 			self autoScroll: p.
>> 			self canvasChanged: selectionRect.
>> 			selectionRect := aPoint rect: (self screenToCanvas: p).
>> 			selectionRect := selectionRect intersect: canvasForm boundingBox.
>> 			self canvasChanged: selectionRect.
>> 			World doOneCycle]].
>> 	showSelection := false.
>> 	self changed.
>> 	World displayWorld.
>> 
>> 	selectionRect area = 0 ifTrue: [selectionRect := nil].
>> 	^ selectionRect
>> 
>> 
>> In PaintCanvas>>selectRectangleStartingAt: we set selectionRect to a
>> rectangle in the first line. On line 8
>> `self canvasChanged: selectionRect.` 
>> it appears selectionRect is nil. In the debugger it is indeed nil. I
>> can’t see any path that should make it nil on an initial go-round, so
>> something is wrong in the loop that follows, which spins on `self
>> currentEvent anyButtonPressed`
>> After sticking some counting code in the loop to see if the problem was
>> happening during the first pass I was startled to see it was more usually
>> occurring after 160-180 loops! And to make life even more interesting
>> with some checking code added before each use of the ‘selectionRect’ ivar
>> it appeared to be getting nilled between the bottom of the loop and the
>> immediately following top. This got me worrying about the vm doing
>> something bad as you might imagine.
>> 
>> However, trying this out in an update #15314 image caused no problems,
>> which at least seems to clear the vm of guilt. After much diffing  of
>> recent updates to Morphic I *think* there must be some interaction
>> between Object>>currentEvent (which uses the ActiveEvent global) and
>> Morphic-mt.1283 changes in HandMorph - purely since they alter the usage
>> of Active Event. The symptom seems to centre around the event not being
>> updated properly.
>> 
>> If I revert the HandMorph>>sendFocusEvent:to:clear: &
>> sendEvent:focus:clear: methods to the versions prior to Morphic-mt.1283
>> then the PaintCanvas code works as before. The bit that really confuses
>> me is that it seems that more event processing must be going on that
>> invokes PaintCanvas>>mouseDown: *within* the loop above - that’s the only
>> current path I can find to nil the selectionRect ivar. Weird.
>> 
>> There is also some possible confusion in the system between
>> Morph>>cursorPoint, which simply gets the currentHand’s lastEvent
>> cursorPoint, and Object>>currentEvent which gives one either the
>> ActiveEvent global or the currentHand’s lastEvent. Seems to me one or the
>> other is giving wrong info.
>> 
>> tim
>> --
>> tim Rowledge; 

>> tim@

>> ; http://www.rowledge.org/tim
>> CChheecckk yyoouurr dduupplleexx sswwiittcchh..
> Hi Tim,
> 
> that code is tricky in the sense that it is exactly like MVC's "[Sensor
> anyButtonPressed]" loops but you should favor Morphic's event dispatching
> style.
> 
> Yes, it should still work this way. In the course of fixing strange
> behavior in Morphic tests, we make set and clear of ActiveWorld,
> ActiveHand, and ActiveEvent more robust. Nothing what would interfere with
> this here.
> 
> Here is a simpler version:
> 
> [self currentEvent hand anyButtonPressed]
> 	whileFalse: [
> 		Transcript showln: self currentEvent hand position.
> 		World doOneCycle].
> 
> This works in the following cases:
> - Do-it with keyboard shortcut, e.g., in Workspace
> - Do-it with mouse/pop-up menu, e.g., in Workspace
> - Invoking it in response to any event dispatching, e.g., a button click
> 
> This, however, will not work, if you invoke it outside of any event
> dispatching such as "Project addDeferredUIMessage: [...]".
> 
> I would at least add this "hand" call to the event. You cannot be sure to
> always get a mouse event here.
> 
> ---------------
> 
> So, what could be the issue then? :-/ 
> 
> I noticed that the selection tool in the Paint Editor does not work at
> all. And the nil-debugger appears *only* if I try to draw a rectangle
> after trying to select something, which did not work.
> 
> So, does the selection tool work for you? I would fix that first.
> 
> My tip would be to do something in the paint editor and then hit CMD+. and
> see whether the stack looks as expected. It seems not and hence
> selectionRect gets nil'ed by code in PaintCanvas.
> 
> My guess is that Scratch can be fixed to work again. It seems to do very
> strange strings. Especially when having a system window *above* the paint
> editor, the mouse cursor keeps changing to a cross. :-D
> 
> Best,
> Marcel

Hey Tim,

using "currentHand" instead of "currentEvent" in both places fixes it.
Somewhat. Dragging the selection does not work then.

At this point in the code, "self currentEvent" would always be the same
event object in the middle of event dispatching. So will "currentHand".
Hence, this whileTrue will never end if you ask the same (immutable) event
object over and over again. You nil-bug occures if you ivoke another event
inside this loop, which will then call some code in PaintCanvas that makes
selectionRect nil. 

I know that this observable behavior of "currentEvent" changed recently in
the course of fixing Morphic some tests. But taking local state for global
state is not, in my opinion, the intention in Morphic. If you want to do
function-based spinning, use Sensor like MVC does. If you want to do it
state-based, use Morph >> #mouseMove: etc. like Morphic does and manage your
state. SystemWindow's corner grip morphs do this, for example, when
fast-dragging is disabled. Any mixture of these styles, as here in this
piece of scratch code, is really tricky to maintain in the long term.

...aaand we do want to make "worlds in worlds" work again, right? ^___^

Best,
Marcel



--
View this message in context: http://forum.world.st/ActiveEvent-Object-currentEvent-broken-by-Morphic-mt-1283-tp4912022p4912039.html
Sent from the Squeak - Dev mailing list archive at Nabble.com.


More information about the Squeak-dev mailing list