[Squeakland] Keyboard support for eToys?

Ned Konz ned at bike-nomad.com
Thu Dec 23 12:27:08 PST 2004

On Tuesday 21 December 2004 2:12 am, Marcus Denker wrote:

> On the german list the question came up about etoys and keyboard
> support.
> Is it possible to e.g. control the car with the keyboard? 

Interesting you ask that. I made a project that shows just that. You can get 
it at:


but be sure you have the keystroke fix loaded first. This is in the Squeakland 
update stream (just "get updates"), but you can also get it at:


> I searched 
> the list,
> and in 2002 Karl Ramberg posted an enhancement (etoy keystroke.5.cs).
> Has this (or something similar) been added to etoys in the meantime?

Yes. I have added simple (keystroke based) support for keys to the current 
Squeakland image, and have posted a fix CS to the Squeak-dev list that makes 
the (existing) support work with the current version work with Squeak 3.8.

Here is an excerpt from a message that I posted to the Squeakland list on 13 
December (I also posted a similar one to Squeak-dev on the 14th).

There are two parts:

* The World has a String-valued property called 'lastKeystroke'. This is a 
string that holds the keystroke, in a form that can be used in string 
comparisons, like:


So you can have a ticking script (for instance) testing the 
lastKeystroke property. But you may very well miss one, unless you use the 
other part:

* You can trigger a script that is owned by the World on a 'keyStroke' event.
You do this by clicking on the 'when this script should run' button, and 
choosing 'more' and then 'keyStroke'.

Since that time I posted the fix I mentioned.

Note that this does *not* do keyUp/keyDown events, just keystrokes. So if you 
want to, say, have the rocket thrusting while a key is down, that's not 
currently supported.

What I had intended to do is to provide a KeyMorph and perhaps also a 
KeyboardMorph that could provide this kind of support. The keystroke support 
that I added recently is much more modest, and doesn't suffer from the 
problems of different keyboard maps.

The problem is that the keyDown/keyUp events are not associated with any 
meaning when they come in. So depending on what keyboard you have, several 
different physical keys (and hence keycodes) may generate, say, the "1" 
keystroke. And this will differ by physical keyboard, operating system, etc.

When we get a keyUp event, we also ask the operating system how to interpret 
that key code number as a keystroke. But until that time we just know the 

I couldn't think of an easy way to deal with this problem in a cross-platform 
way, and I didn't want to make it so that people could make projects that 
couldn't easily be shared between different computers.

I am open to suggestions as to how to fix this. One idea I had was to learn 
the relationship: upon loading a project that uses particular keys, the 
KeyMorphs wouldn't know what numeric keycodes they needed to respond to. But 
they would know the keyStroke (like <left>). By watching *all* the 
keyUp/keyDown/keyStroke events (assuming the user is just pressing one key at 
once, and there are no combining or modifier keys also being used), we can 
see the correspondence between the keyUp events and the keyStroke events that 

Perhaps the KeyMorphs, upon being loaded or created, would prompt the user to 
press the given key so they could learn. Perhaps they could just not respond 
until the second press of their given key.

As I noted above, this is complicated by:

* modifier keys
* combining keys and key sequences
* sticky key states (Shift-Lock, Caps-Lock, Num-Lock, etc.)
* chording: pressing multiple non-modifier keys at once
* international input methods that may compress a long sequence of keys into 
one keystroke

> Another interesting question we got on the list (by a very motivated
> teacher):
> How to extend eToys. The teacher would like to build an eToy based
> environment for teaching math to older kids, and he would like to
> provide
> some pre-defined tiles.

It is easy to add vocabulary items to Morph classes, and probably not as easy 
to extend (say) Number operations. For instance, I don't know how you'd add 
unary Number operators like sin and cos.

> I think this view of eToys as a framework for building curriculums is
> quite
> interesting, but there is no documentation about how to do "etoy"
> Metaprogramming...

>From a recent message that I wrote to the Squeak-dev list:

To extend the vocabulary of a Morph, you can just add methods named like 
additionsToVocabularyCategory* to the class side (look for such methods to 
get an idea). For each item, you typically need a method in Player and the 
corresponding method(s) in your Morph class.

For example, here is Morph class >>
 "Answer viewer additions for the 'layout' category"

   (slot clipSubmorphs 'Whether or not to clip my submorphs' Boolean readWrite 
Player getClipSubmorphs Player setClipSubmorphs:)


So this adds the 'clipSubmorphs' slot to the 'layout' vocabulary category. 
That slot (a pseudo-variable) is read/write, and is implemented by the 
methods #getClipSubmorphs and #setClipSubmorphs on Player. Those methods just 
call back to the morph that is the Player's costume:

 "Getter for costume's clipSubmorphs"
 ^ costume renderedMorph clipSubmorphs

The other kind of thing you can add (besides the pseudo-variable 'slot' type) 
is the 'command' type, as in:

 "Answer viewer additions for the 'miscellaneous' category"
   (command doMenuItem: 'do the menu item' Menu)
   (command show 'make the object visible')

These don't have an associated return value, but they can have a single typed 

I don't know where the best place for this kind of documentation would be. Do 
we have a Squeakland Swiki set up, or would the Squeak Swiki be the best 
place for this?

Ned Konz

More information about the Squeakland mailing list