Hi fernando May be you know more than me on MorphicEventHandler. Gofer new squeaksource: 'PharoNonCorePackages'; package: 'Sound'; package: 'SoundMorphicUserInterface'; load. While trying to make PianoKeyboardMorph new openInWorld (which works in 1.4 and does not in 20). It breaks here: ------------- mouseUpPitch: pitch event: event noteMorph: noteMorph noteMorph color: ((#(0 1 3 5 6 8 10) includes: pitch \\12) ifTrue: [whiteKeyColor] ifFalse: [blackKeyColor]). soundPlaying ifNotNil: [soundPlaying stopGracefully]. pitch is nil because notify:from: uses valueParameter which is nil. ------------- mouseUpPitch is invoked by notify: anEvent from: sourceMorph which is invoked by notifyMorphsOfEvent: anEvent ofType: eventType from: sourceMorph notify: anEvent from: sourceMorph | arity | recipient ifNil: [^ self]. arity := selector numArgs. arity = 0 ifTrue: [^ recipient perform: selector]. arity = 1 ifTrue: [^ recipient perform: selector with: anEvent]. arity = 2 ifTrue: [^ recipient perform: selector with: anEvent with: sourceMorph]. arity = 3 ifTrue: [^ recipient perform: selector with: valueParameter with: anEvent with: sourceMorph]. ^^^^^^^^^^^^^^^^^^^^^^^ self error: 'Event handling selectors must be Symbols and take 0-3 arguments' notifyMorphsOfEvent: anEvent ofType: eventType from: sourceMorph | result | result := false. ((subscriptions includesKey: eventType) not or: [ (subscriptions at: eventType) isEmpty ]) ifTrue: [ ^false ]. (subscriptions at: eventType) do: [ :s | result := result | ((s notify: anEvent from: sourceMorph) == true) ]. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^result The idea is that morphs get notified when a certain event occurs so when we look at the morph creation and event registry we get: The buildKeyboard create morph and define event with a given value that will be used on: #mouseDown send: #mouseDownPitch:event:noteMorph: to: self withValue: i-1*12 + (#(2 4 7 9 11) at: j) below: buildKeyboard | wtWid bkWid keyRect octavePt nWhite nBlack | self removeAllMorphs. wtWid := 8. bkWid := 5. self extent: 10@10. 1 to: nOctaves+1 do: [:i | i <= nOctaves ifTrue: [nWhite := 7. nBlack := 5] ifFalse: [nWhite := 1. nBlack := 0 "High C"]. octavePt := self innerBounds topLeft + ((7*wtWid*(i-1)-1) @ -1). 1 to: nWhite do: [:j | keyRect := octavePt + (j-1*wtWid@0) extent: (wtWid+1)@36. self addMorph: ((RectangleMorph newBounds: keyRect color: whiteKeyColor) borderWidth: 1; on: #mouseDown send: #mouseDownPitch:event:noteMorph: to: self withValue: i-1*12 + (#(1 3 5 6 8 10 12) at: j))]. 1 to: nBlack do: [:j | keyRect := octavePt + ((#(6 15 29 38 47) at: j)@1) extent: bkWid@21. self addMorph: ((Morph newBounds: keyRect color: blackKeyColor) on: #mouseDown send: #mouseDownPitch:event:noteMorph: to: self withValue: i-1*12 + (#(2 4 7 9 11) at: j))]]. self submorphsDo: [:m | m on: #mouseMove send: #mouseMovePitch:event:noteMorph: to: self; on: #mouseUp send: #mouseUpPitch:event:noteMorph: to: self; on: #mouseEnterDragging send: #mouseDownPitch:event:noteMorph: to: self; on: #mouseLeaveDragging send: #mouseUpPitch:event:noteMorph: to: self]. self extent: (self fullBounds extent + borderWidth - 1) Now I can understand that #mouseDownPitch:event:noteMorph: get notified with a value because this is what is written. But I do not get why this would be the case with #mouseUpPitch:event:noteMorph: since we simply get on: #mouseUp send: #mouseUpPitch:event:noteMorph: to: self; And I do not get why this was working in 1.4