[squeak-dev] wait2ms (The Trunk: ST80-dtl.141.mcz)

David T. Lewis lewis at mail.msen.com
Sat Feb 9 18:48:06 UTC 2013


Hi Bob, thanks for this.

I am hopelessly out of my depth on multilingual processing and multibyte
characters, but I'm sure others on the list will know: Are there cases
(e.g. in Japan or Korea) where keyboards provide multi-byte inputs, either
directly or through X11? If so, the "sensor keyboardPressed whileTrue:"
may be necessary in order to process those key entries. Otherwise, I
suspect you are right that it is easier to just process one character at
a time. I note also that the "whileTrue:" approach dates back to at least
2002, well before introduction of multilingual support in Squeak. I don't
know if that's significant, or if that's just the way it happened to have
been done.

Just by way of explanation, here is how I found and verified the change
to zapSelectionWithCompositionWith: in ST80-dtl.141.mcz:

1) In the original method, I forced the method to always execute the
multi-character path through the code, even if the input string was one
character long (the normal case). So I changed from this:

  ((aString isEmpty or: [(beforeChar := self charBefore) isNil]) or: [
    aString size = 1 and: [(Unicode isComposition: aString first) not]]) ifTrue: [
      ^ self zapSelectionWith: (Text string: aString emphasis: emphasisHere)].

to this:

  ((aString isEmpty or: [(beforeChar := self charBefore) isNil]) or: [
    aString size = 1 and: [(Unicode isComposition: aString first) not]]) ifTrue: [
      "^ self zapSelectionWith: (Text string: aString emphasis: emphasisHere)" ].

Result: All characters typed into an MVC workspace resulted in the cursor
positioned incorrectly to the left of the current character.

2) I changed the method to reposition the cursor correctly, leaving the
above change in place to continue forcing execution of the multi-byte code
path. This fixed the cursor positioning problem in the MVC workspace.

3) I removed the change from step 1 so that single character input would
be handled through the normal path, and verified that the MVC workspace
still worked.

4) I filed the updated method into another image that still has the wait2ms
delays, and I ran that image on a Linux interpreter VM (with "2 ms" delays
that might be more like 15 ms). Result: Cursor positioning now worked correctly
in the MVC workspace, even though keyboard entry was slow.

Conclusion: The patch in ST80-dtl.141.mcz does address a real bug in cursor
positioning that occured only in cases where sluggish key entry resulted
in multi-byte strings (presumably two characters) being handled in the
zapSelectionWithCompositionWith: method.

The problem that you identified with your "z123" test does not seem to be
occurring in practice, but it certainly looks as though it *could* occur.
I tested only by typing into a workspace from my US ascii keyboard, so I
certainly would not rule out the possibility of further problems.

I do not know if it is safe to make the change you suggest to process one
character at a time. It looks to me like it would be good to do that, but
I don't know if it might cause problems for non-US keyboards or locales.

If it was safe to make that change, then the entire bit of code for handling
multi-byte strings in zapSelectionWithCompositionWith: would become irrelevant,
and we could just get rid of it.

Hopefully someone with experience in this area can help?

Dave


On Sat, Feb 09, 2013 at 06:52:43AM -0500, Bob Arning wrote:
> I fear that doesn't even work with ordinary USASCII input. I tweaked 
> readKeyboard to simulate additional characters arriving in close succession:
> 
>         self hasSelection ifTrue: "save highlighted characters"
>             [UndoSelection := self selection].
> *((model isKindOf: Workspace) and: [char = $z]) ifTrue: [typeAhead 
> nextPutAll: '123'].*
> 
>         self zapSelectionWithCompositionWith: typeAhead contents.
> 
> and what I get by typing some z's in a Workspace is:
> 
> z123zzzzzz123123123123123123
> 
> I think the safest way to guard against multiple characters arriving in 
> quick succession is to simply process each one completely before 
> proceeding to the next. This, after all, is the likeliest case by far 
> for modern computers and ordinary humans typing:
> 
>         self deselect.
> *sensor keyboardPressed ifTrue: "was a whileTrue:"*
>             [char := sensor keyboardPeek.
>             (self dispatchOnCharacter: char with: typeAhead) ifTrue:
>                 [self doneTyping.
>                 self setEmphasisHere.
>                 ^self selectAndScroll; updateMarker].
>             self openTypeIn].
> 
> Cheers,
> Bob
> 
> On 2/9/13 1:01 AM, commits at source.squeak.org wrote:
> >aText := Text string: newString emphasis: emphasisHere.
> >- 	self markBlock < self pointBlock
> >- 		ifTrue: [self setMark: self markBlock stringIndex - 1]
> >- 		ifFalse: [self setPoint: self  pointBlock stringIndex - 1].
> >-
> >   	wasComposition := true.
> >+ 	self markBlock < self pointBlock
> >+ 		ifTrue: [ self setMark: self markBlock stringIndex - 1.
> >+ 				self zapSelectionWith: aText.
> >+ 				self setMark: self markBlock stringIndex + 1]
> >+ 		ifFalse: [ self setPoint: self pointBlock stringIndex - 1.
> >+ 				self zapSelectionWith: aText.
> >+ 				self setPoint: self pointBlock stringIndex + 
> >1]
> >- 	self zapSelectionWith: aText.
> 

> 



More information about the Squeak-dev mailing list