Detecting keyboard state / finding older fixes

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

Detecting keyboard state / finding older fixes

Stan Shepherd
(resend, as previously not subscribed and message blocked waiting
approval)

I'm using my qwerty/azerty keyboard for input to a game. The issue is that when
you press and hold a key, you receive repeats of the key press from the
operating system. I'd like to check the real position of a key, up or down, so I
can ignore the repeats. I can't find any way to do this.

There is a reference here
http://thread.gmane.org/gmane.comp.lang.smalltalk.squeak.general/4034 to a fix
to do this, but the links:
http://swiki.gsug.org:8080/sqfixes/2634.html
http://209.143.91.36/super/589
http://swiki.gsug.org/sqfixes/2629.html
Are all dead; they date from 2002.

Is there a way in the current version to do what I need, or is there a more
recent archive of fixes that I'm missing?

...Stan

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Detecting keyboard state / finding older fixes

Herbert König
Hello Stan,

sff> operating system. I'd like to check the real position of a key, up or down, so I
sff> can ignore the repeats. I can't find any way to do this.

Keyboard event understands #isKeyDown and #isKeyUp.


Cheers

Herbert                            mailto:[hidden email]

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Detecting keyboard state / finding older fixes

Herbert König
Hello Stan,

I forgot:

sff>> operating system. I'd like to check the real position of a key, up or down, so I
sff>> can ignore the repeats. I can't find any way to do this.

HK> Keyboard event understands #isKeyDown and #isKeyUp.

and don't forget to check the event's timestamp. Never did this myself
but you can not rely on the fact that you will receive keyDown before
keyUp.



Cheers

Herbert                            mailto:[hidden email]

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Detecting keyboard state / finding older fixes

Stan Shepherd
Thanks Herbert.

Unfortunately these methods seem to be 'fooled' by the operating system as well.

for example:

handleKeyUp: anEvent
        Transcript show: ' evt is down ',anEvent isKeyDown asString; cr.
        "now press and hold a key"

shows

 evt is down false
 evt is down false
 evt is down false
 evt is down false
 evt is down false
 evt is down false
 evt is down false
 evt is down false - while the key is clearly down.

I suppose this is logical, as the event is being triggered by the OS. Our test needs to give the 'real' position of the key.

On Linux you can switch off the auto repeat in keyboard settings, but it's not very friendly for other programs like text editing.

...Stan



Herbert König wrote
Hello Stan,

I forgot:

sff>> operating system. I'd like to check the real position of a key, up or down, so I
sff>> can ignore the repeats. I can't find any way to do this.

HK> Keyboard event understands #isKeyDown and #isKeyUp.

and don't forget to check the event's timestamp. Never did this myself
but you can not rely on the fact that you will receive keyDown before
keyUp.



Cheers

Herbert                            mailto:herbertkoenig@gmx.net

_______________________________________________
Beginners mailing list
Beginners@lists.squeakfoundation.org
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Detecting keyboard state / finding older fixes

Bert Freudenberg
On Mar 4, 2008, at 19:19 , stan shepherd wrote:

> handleKeyUp: anEvent
> Transcript show: ' evt is down ',anEvent isKeyDown asString; cr.
>         "now press and hold a key"
>
> shows
>
>  evt is down false

Which is of course expected since only keyUp events are passed into  
#handleKeyUp:, so #isKeyDown always is false.

You need to handle both keyDown and keyUp events, and track the state  
of pressed keys.

Note that the keyValue in up/down events is system-specific (unlike  
keyStroke events which have actual characters).

Also note that this behavior also depends on your OS and VM version.  
The Windows VM handles up/down events nicely for a long time, Mac VMs  
since recently, Unix VMs are broken I think.

I'm attaching a small example morph demonstrating this.

- Bert -


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners

BertsKeys.st.gz (694 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Detecting keyboard state / finding older fixes

Stan Shepherd
Bert, Thanks for the reply and example.

To get around the repeat key issue, I'm testing the elapsed time since last keystroke. If it's too short, assume it's repeat key from the OS:

        keyDelay := (anEvent timeStamp) - (lastEventTime at: noteNo) .
        lastEventTime at: noteNo put: anEvent timeStamp.
        (keyDelay < 250) ifTrue: [ "Transcript show: 'key repeat ignored'; cr."
                                ^self].    "assume it's a key repeat'"
       
...Stan

p.s. I'm sure there is a 'Squeakier' way to do this.

Bert Freudenberg wrote
On Mar 4, 2008, at 19:19 , stan shepherd wrote:

> handleKeyUp: anEvent
> Transcript show: ' evt is down ',anEvent isKeyDown asString; cr.
>         "now press and hold a key"
>
> shows
>
>  evt is down false

Which is of course expected since only keyUp events are passed into  
#handleKeyUp:, so #isKeyDown always is false.

You need to handle both keyDown and keyUp events, and track the state  
of pressed keys.

Note that the keyValue in up/down events is system-specific (unlike  
keyStroke events which have actual characters).

Also note that this behavior also depends on your OS and VM version.  
The Windows VM handles up/down events nicely for a long time, Mac VMs  
since recently, Unix VMs are broken I think.

I'm attaching a small example morph demonstrating this.

- Bert -


 
_______________________________________________
Beginners mailing list
Beginners@lists.squeakfoundation.org
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Detecting keyboard state / finding older fixes

Bert Freudenberg
Assuming this is for a game, you would effectively prevent someone  
"hammering" on a key to do some action repeatedly. Also this depends  
on the actual repeat rate which varies widely between systems. In my  
example there is no such fixed timeout, you simply would check if the  
key is pressed already (i.e. it is in the keys set).

- Bert -

Am Mar 5, 2008 um 18:46 schrieb stan shepherd <[hidden email]>:

>
> Bert, Thanks for the reply and example.
>
> To get around the repeat key issue, I'm testing the elapsed time  
> since last
> keystroke. If it's too short, assume it's repeat key from the OS:
>
>    keyDelay :=    (anEvent timeStamp) - (lastEventTime at: noteNo) .
>    lastEventTime at: noteNo put: anEvent timeStamp.
>    (keyDelay < 250) ifTrue: [        "Transcript show: 'key repeat  
> ignored'; cr."
>                ^self].    "assume it's a key repeat'"
>
> ...Stan
>
> p.s. I'm sure there is a 'Squeakier' way to do this.
>
>
> Bert Freudenberg wrote:
>>
>> On Mar 4, 2008, at 19:19 , stan shepherd wrote:
>>
>>> handleKeyUp: anEvent
>>>    Transcript show: ' evt is down ',anEvent isKeyDown asString; cr.
>>>        "now press and hold a key"
>>>
>>> shows
>>>
>>> evt is down false
>>
>> Which is of course expected since only keyUp events are passed into
>> #handleKeyUp:, so #isKeyDown always is false.
>>
>> You need to handle both keyDown and keyUp events, and track the state
>> of pressed keys.
>>
>> Note that the keyValue in up/down events is system-specific (unlike
>> keyStroke events which have actual characters).
>>
>> Also note that this behavior also depends on your OS and VM version.
>> The Windows VM handles up/down events nicely for a long time, Mac VMs
>> since recently, Unix VMs are broken I think.
>>
>> I'm attaching a small example morph demonstrating this.
>>
>> - Bert -
>>
>>
>>
>> _______________________________________________
>> Beginners mailing list
>> [hidden email]
>> http://lists.squeakfoundation.org/mailman/listinfo/beginners
>>
>>
>
> --
> View this message in context: http://www.nabble.com/Detecting-keyboard-state---finding-older-fixes-tp15779144p15855607.html
> Sent from the Squeak - Beginners mailing list archive at Nabble.com.
>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/beginners
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Detecting keyboard state / finding older fixes

Stan Shepherd
Where I was confused is that checking if the key is pressed already doesn't appear to differentiate between a 'real' key down and a repeat. For example :

keyDown: anEvent
        (keys includes: anEvent keyValue)
                ifTrue: [Transcript show: 'skipped ' , anEvent asString; cr]
                ifFalse: [keys add: anEvent keyValue. "
                        Transcript show: 'key down ' , anEvent asString; cr.
                        self changed]

always takes the 'key down' branch, even for key held down.

Was this what you meant?

On the other hand, looping over this in a thread:

keyStrokes
        keys
                do: [:key | key
                                ifNotNil: [(oldKeys includes: key)
                                                ifFalse: [Transcript show: 'key added ' , key asString;
                                                                 cr]]].
        oldKeys do: [:key | key
                                ifNotNil: [(keys includes: key)
                                                ifFalse: [Transcript show: 'key removed ' , key asString;
                                                                 cr]]].
        oldKeys := keys copy.

has the desired effect of only showing real key moves.

Is this over complicating things?
...Stan


Bert Freudenberg wrote
Assuming this is for a game, you would effectively prevent someone  
"hammering" on a key to do some action repeatedly. Also this depends  
on the actual repeat rate which varies widely between systems. In my  
example there is no such fixed timeout, you simply would check if the  
key is pressed already (i.e. it is in the keys set).

- Bert -
Reply | Threaded
Open this post in threaded view
|

Re: Detecting keyboard state / finding older fixes

Bert Freudenberg
On Mar 7, 2008, at 14:54 , stan shepherd wrote:

>
> Where I was confused is that checking if the key is pressed already  
> doesn't
> appear to differentiate between a 'real' key down and a repeat. For  
> example
> :
>
> keyDown: anEvent
> (keys includes: anEvent keyValue)
> ifTrue: [Transcript show: 'skipped ' , anEvent asString; cr]
> ifFalse: [keys add: anEvent keyValue. "
> Transcript show: 'key down ' , anEvent asString; cr.
> self changed]
>
> always takes the 'key down' branch, even for key held down.
>
> Was this what you meant?

Yes. The code above works as expected on Mac OS X, printing  
"skipped..." for auto-repeats.


> On the other hand, looping over this in a thread:
>
> keyStrokes
> keys
> do: [:key | key
> ifNotNil: [(oldKeys includes: key)
> ifFalse: [Transcript show: 'key added ' , key asString;
> cr]]].
> oldKeys do: [:key | key
> ifNotNil: [(keys includes: key)
> ifFalse: [Transcript show: 'key removed ' , key asString;
> cr]]].
> oldKeys := keys copy.
>
> has the desired effect of only showing real key moves.
>
> Is this over complicating things?

It indeed sounds overly complicated, unless your platform forces you  
to resort to such things. Are you on Linux by chance?

- Bert -
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Detecting keyboard state / finding older fixes

Stan Shepherd
I am indeed on Linux. I have a feeling that Windows was the same (coding in Java). That is, in the programming language a real key down and a repeat are indistinguishable.

Stan

Bert Freudenberg wrote
On Mar 7, 2008, at 14:54 , stan shepherd wrote:

>
> Where I was confused is that checking if the key is pressed already  
> doesn't
> appear to differentiate between a 'real' key down and a repeat. For  
> example
> :
>
> keyDown: anEvent
> (keys includes: anEvent keyValue)
> ifTrue: [Transcript show: 'skipped ' , anEvent asString; cr]
> ifFalse: [keys add: anEvent keyValue. "
> Transcript show: 'key down ' , anEvent asString; cr.
> self changed]
>
> always takes the 'key down' branch, even for key held down.
>
> Was this what you meant?

Yes. The code above works as expected on Mac OS X, printing  
"skipped..." for auto-repeats.


> On the other hand, looping over this in a thread:
>
> keyStrokes
> keys
> do: [:key | key
> ifNotNil: [(oldKeys includes: key)
> ifFalse: [Transcript show: 'key added ' , key asString;
> cr]]].
> oldKeys do: [:key | key
> ifNotNil: [(keys includes: key)
> ifFalse: [Transcript show: 'key removed ' , key asString;
> cr]]].
> oldKeys := keys copy.
>
> has the desired effect of only showing real key moves.
>
> Is this over complicating things?

It indeed sounds overly complicated, unless your platform forces you  
to resort to such things. Are you on Linux by chance?

- Bert -
_______________________________________________
Beginners mailing list
Beginners@lists.squeakfoundation.org
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Detecting keyboard state / finding older fixes

Bert Freudenberg
On Mar 7, 2008, at 17:53 , stan shepherd wrote:

>
> I am indeed on Linux. I have a feeling that Windows was the same  
> (coding in
> Java).

I am pretty sure it works in the Windows VM. You should get multiple  
keyDown events but a single keyUp:

Down ... (pause) ... down - down - down - down - down - up.

> That is, in the programming language a real key down and a repeat are
> indistinguishable.

The problem is that from the X11 VM you get this:

Down ... (pause) ... up down - up down - up down - up down - up.

Now, the up and down events bear the same time stamp (they are  
synthesized together) so the VM could actually filter out the  
unwanted up events, but it does not (yet anyway). Also, you do not  
get events for all keys like Shift etc. (IIRC only Windows gets that  
right).

It's a shame to admit this is still not working ...

- Bert -


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Detecting keyboard state / finding older fixes

Stan Shepherd
As I have dual boot Linux/Windows, I'll try and verify the Windows result in the next day or two.

Bert Freudenberg wrote
I am pretty sure it works in the Windows VM. You should get multiple  
keyDown events but a single keyUp:

Down ... (pause) ... down - down - down - down - down - up.

> That is, in the programming language a real key down and a repeat are
> indistinguishable.

The problem is that from the X11 VM you get this:

Down ... (pause) ... up down - up down - up down - up down - up.

Now, the up and down events bear the same time stamp (they are  
synthesized together) so the VM could actually filter out the  
unwanted up events, but it does not (yet anyway). Also, you do not  
get events for all keys like Shift etc. (IIRC only Windows gets that  
right).

It's a shame to admit this is still not working ...

- Bert -