stack overflow using #inline anchor

Chris Muller asqueaker at gmail.com
Thu Oct 4 04:48:50 UTC 2007


I am making my own TextMorph (subclass) in which I want to be able to
drag any Morph embedded directly into the text.

TextMorph already supports this via #anchorMorph:at:type:.  I am
interested in providing an enriched #inline embedding.

What I've done in MyTextMorph is express interest in mouse-over
dragging by overriding #mouseEnterDragging: and #mouseLeaveDragging:
which #startTrackingDropZones and #stopTrackingDropZones,
respectively.

Tracking drop zones is nothing more than stepping real fast to show a
"marker" morph by calling the above mentioned method:

	...
	self
		anchorMorph: spacer
		at: hand position
		type: #inline

It works great!  Except.. *sometimes*, when being rough with it,
shaking a big morph around in the text it gets into an infinite
recursion (sans stack overflow error), which I've pasted at the end of
this message.

There is a guard in CompositionScanner>>#placeEmbeddedObject: anchoredMorph
	| descent |
	"Workaround: The following should really use #textAnchorType"
	anchoredMorph relativeTextAnchorPosition ifNotNil:[^true].

which piqued my interest because of the comment,

and another in TextAnchor>>#emphasizeScanner: aScanner
	self anchoredMorph ifNil: [ ^ self ].
	aScanner placeEmbeddedObject: self anchoredMorph.

which is interesting because of the fact it is related to its #anchoredMorph.

Unfortunately, an infiinite recursion is a bad show-stopper, I need
advice to help find an appropriate guard to prevent the recursion.

Any help is much appreciated.

 - Chris



From: chris
To: squeak-dev at lists.squeakfoundation.org
Subject: [BUG]IdentityDictionary(Dictionary)>>at:ifAbsent:

here insert explanation of what you were doing, suspect changes you've
made and so forth.

4 October 2007 12:41:17 am

VM: Win32 - a SmalltalkImage
Image: Squeak3.9 [latest update: #7067]

SecurityManager state:
Restricted: false
FileAccess: true
SocketAccess: true

IdentityDictionary(Dictionary)>>at:ifAbsent:
	Receiver: an IdentityDictionary()
	Arguments and temporary variables:
		key: 	#relativeTextAnchorPosition
		aBlock: 	[] in MorphExtension>>valueOfProperty:ifAbsent: {[^ aBlock value]}
		assoc: 	nil
	Receiver's instance variables:
		tally: 	0
		array: 	#(nil nil nil nil nil)

MorphExtension>>valueOfProperty:ifAbsent:
	Receiver: a MorphExtension (602)
	Arguments and temporary variables:
		aSymbol: 	#relativeTextAnchorPosition
		aBlock: 	[] in MorphExtension>>valueOfProperty: {[]}
	Receiver's instance variables:
		locked: 	false
		visible: 	true
		sticky: 	false
		balloonText: 	nil
		balloonTextSelector: 	nil
		externalName: 	nil
		isPartsDonor: 	false
		actorState: 	nil
		player: 	nil
		eventHandler: 	nil
		otherProperties: 	nil

MorphExtension>>valueOfProperty:
	Receiver: a MorphExtension (602)
	Arguments and temporary variables:
		aSymbol: 	#relativeTextAnchorPosition
	Receiver's instance variables:
		locked: 	false
		visible: 	true
		sticky: 	false
		balloonText: 	nil
		balloonTextSelector: 	nil
		externalName: 	nil
		isPartsDonor: 	false
		actorState: 	nil
		player: 	nil
		eventHandler: 	nil
		otherProperties: 	nil

RectangleMorph(Morph)>>valueOfProperty:
	Receiver: a RectangleMorph(749)
	Arguments and temporary variables:
		aSymbol: 	#relativeTextAnchorPosition
	Receiver's instance variables:
		bounds: 	0 at 0 corner: 94 at 142
		owner: 	nil
		submorphs: 	#()
		fullBounds: 	0 at 0 corner: 94 at 142
		color: 	Color transparent
		extension: 	a MorphExtension (602)
		borderWidth: 	1
		borderColor: 	Color green


--- The full stack ---
IdentityDictionary(Dictionary)>>at:ifAbsent:
MorphExtension>>valueOfProperty:ifAbsent:
MorphExtension>>valueOfProperty:
RectangleMorph(Morph)>>valueOfProperty:
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RectangleMorph(Morph)>>relativeTextAnchorPosition
CompositionScanner>>placeEmbeddedObject:
TextAnchor>>emphasizeScanner:
[] in CompositionScanner(CharacterScanner)>>setFont {[:att | att
emphasizeScanner: self]}
Array(SequenceableCollection)>>do:
CompositionScanner(CharacterScanner)>>setFont
CompositionScanner>>setFont
CompositionScanner(CharacterScanner)>>placeEmbeddedObject:
CompositionScanner>>placeEmbeddedObject:
TextAnchor>>emphasizeScanner:
[] in CompositionScanner(CharacterScanner)>>setFont {[:att | att
emphasizeScanner: self]}
Array(SequenceableCollection)>>do:
CompositionScanner(CharacterScanner)>>setFont
CompositionScanner>>setFont
CompositionScanner(CharacterScanner)>>placeEmbeddedObject:
CompositionScanner>>placeEmbeddedObject:
TextAnchor>>emphasizeScanner:
[] in CompositionScanner(CharacterScanner)>>setFont {[:att | att
emphasizeScanner: self]}
Array(SequenceableCollection)>>do:
CompositionScanner(CharacterScanner)>>setFont
CompositionScanner>>setFont
CompositionScanner(CharacterScanner)>>placeEmbeddedObject:
CompositionScanner>>placeEmbeddedObject:
TextAnchor>>emphasizeScanner:
[] in CompositionScanner(CharacterScanner)>>setFont {[:att | att
emphasizeScanner: self]}
Array(SequenceableCollection)>>do:
CompositionScanner(CharacterScanner)>>setFont
CompositionScanner>>setFont
CompositionScanner(CharacterScanner)>>placeEmbeddedObject:
CompositionScanner>>placeEmbeddedObject:
TextAnchor>>emphasizeScanner:
[] in CompositionScanner(CharacterScanner)>>setFont {[:att | att
emphasizeScanner: self]}
Array(SequenceableCollection)>>do:
CompositionScanner(CharacterScanner)>>setFont
CompositionScanner>>setFont
CompositionScanner(CharacterScanner)>>placeEmbeddedObject:
CompositionScanner>>placeEmbeddedObject:
TextAnchor>>emphasizeScanner:
[] in CompositionScanner(CharacterScanner)>>setFont {[:att | att
emphasizeScanner: self]}
Array(SequenceableCollection)>>do:
CompositionScanner(CharacterScanner)>>setFont
CompositionScanner>>setFont
CompositionScanner(CharacterScanner)>>placeEmbeddedObject:
CompositionScanner>>placeEmbeddedObject:
TextAnchor>>emphasizeScanner:
[] in CompositionScanner(CharacterScanner)>>setFont {[:att | att
emphasizeScanner: self]}
...etc...



More information about the Squeak-dev mailing list