Keylistener on Linux

I couldn’t find the old post about this, but wasn’t there an issue where on windows with a keylistener you’d get

KeyPressed

KeyReleased

But on linux with key repeat you’d get

KeyPressed
KeyReleased
KeyPressed
KeyReleased
KeyPressed
KeyReleased

which cause lots of annoying issues. Did anyone come up with a work around for the issue?

Kev

The only thing i’ve seen is where people write a wrapper over the top and have a delay, so the keyListener i listened to by another key listener, and that is the one the game listens too, that one, when it gets the first keyPressed starts a timer, if it doesn’t get another keyPressed in the keyboard repeat time, then and only then send the keyReleased even.

HTH

Endolf

I think I prefer my current workaround :-/

When the key released event comes in, I just peek() on the AWT event queue for the next KeyPressed event. If its for the same key code at the same time then ignore the key released.

This however seems a bit ugly.

Kev

Aye, sounds like a better solution. Still not ideal, but them’s the breaks. Probably find osX does it like linux, but don’t count on it :slight_smile:

Endolf

[quote]I think I prefer my current workaround :-/

When the key released event comes in, I just peek() on the AWT event queue for the next KeyPressed event. If its for the same key code at the same time then ignore the key released.
[/quote]
Well I tried your idea but it wasn’t successfull for me. Here is my code:


    eventQueue = gameWindow.getToolKit().getSystemEventQueue();
    ...
    public void keyReleased(KeyEvent e) {
          AWTEvent event = eventQueue.peekEvent();
          if (event != null && event instanceof KeyEvent && ((KeyEvent) event).getKeyCode() == keyPressedCode) {
                return;
          }
          keyReleasedCode = e.getKeyCode();
    }

Where keyPressedCode has been stored in previous keyPressed() method invocation.

Why is it not working?

I see another potential problem with this solition. Imagine I am using VK_UP as my ‘move forwards’ and VK_Z as my fire key. If I want to move forwards whilst continuously fireing, the player would hold both keys down.

so in the event key you get

VK_UP pressed VK_Z pressed VK_UP released VK_Z released VK_UP pressed VK_Z pressed VK_UP released VK_Z released

now, when you get to the VK_UP released it’s fine, scan for the next KEY_PRESSED and you get VK_UP, so you ignore it, then you get the VK_Z released and check, but unless you can consume the VK_UP pressed event, you’ll find that again. Is it possible/wise to start consuming events that arn’t at the front of the queue and have not been dispatched. Possible is easy to solve, try it (which I plan on doing, but not now), wise is another issue. What are the implications of removing a key pressed even, noting that when you are doing it, some things may have already been notified of the key released, and others may not (who knows where you are in the chain of listeners).

Just some thoughts.

Endolf

Actually, I don’t think you get that with multiple keys held down. Only one repeats (I think its actually caused by standard key repeat?)…

So you actually get…

VK_UP pressed
VK_Z pressed

VK_Z release
VK_Z pressed
VK_Z release
VK_Z pressed
VK_Z release
VK_UP release

Kev

Hmm, interesting, I feel some testing comming on tomorrow :slight_smile:

Endolf

kev, could post your solution here?

The class I use to wrap keyboard input is actually available as part of the SpaceInvaders 103 tutorial, heres the class:

http://www.cokeandcode.com/info/showsrc/showsrc.php?src=../spaceinvaders103/org/newdawn/spaceinvaders/util/Keyboard.java

the bit in particular that I did to get round linux was:


public void keyReleased(KeyEvent e) {
         KeyEvent nextPress = (KeyEvent) Toolkit.getDefaultToolkit().getSystemEventQueue().peekEvent(KeyEvent.KEY_PRESSED);
              
          if ((nextPress == null) || (nextPress.getWhen() != e.getWhen())) {
                keys[e.getKeyCode()] = false;
         }
              
}

Please understand, I’m not saying this is the only way to do it but it has worked for me in the past quite happily.

Kev

PS. I’m really thinking about adding a signature like NeHe’s:

but I assuming most people can tell that from the state of my code :slight_smile: