Keyboard weirdness

Howdy

Immediately after calling Display.update(), I use


while( Keyboard.next() )
{
	int key = Keyboard.getEventKey();
	boolean down = Keyboard.getEventKeyState();
	boolean repeat = Keyboard.isRepeatEvent();

	for( int j = 0; j < keyListeners.size(); j++ )
	{
		if( down )
			keyListeners.get( j ).keyDown( key, repeat );
		else
			keyListeners.get( j ).keyUp( key );
	}
}

to process pending key events. The problem is that there are occasional erroneous events. When holding down “W”, for example, i get something like:


Down W at 2.517
	Up W at 5.621
Down W at 5.621
	Up W at 6.358
Down W at 6.358
	Up W at 9.075
Down W at 9.075
	Up W at 11.39
Down W at 11.39
	Up W at 20.246
Down W at 20.246
	Up W at 33.866
Down W at 33.866
	Up W at 35.208
Down W at 35.208
	Up W at 35.275

The KeyboardTest does not exhibit this behaviour, so PEBKAC applies, but I haven’t the foggiest what I could be doing to cause this behaviour.

I did find a similar case on the LWJGL forums, but he was doing multithreaded stuff, which I am not.
This is running on Linux, by the way

Has anyone seen anything similar?

Wild guess: wireless keyboard…?

Good thought, but I’m on a laptop.

Also, LWJGL’s keyboard test works perfectly, so I’m fairly sure it’s something I’m doing.

Curiouser and curiouser, it might be the case that this is someone else’s problem.

I’ve pared it down to this:


public class KeyboardTest
{
	private static boolean weirdKeyboardRepeatPlease = true;

	public static void main( String[] args )
	{
		Display.setVSyncEnabled( weirdKeyboardRepeatPlease )

		try
		{
			Display.create();

			while( !Display.isCloseRequested() )
			{
				Display.update();
				while( Keyboard.next() )
				{
					System.out.println( "Checking key:" + Keyboard.getKeyName( Keyboard.getEventKey() ) );
					System.out.println( "Pressed:" + Keyboard.getEventKeyState() );
				}
			}
		}
		catch( Exception e )
		{
			e.printStackTrace();
		}
	}
}

When the flag is true, this will consistently display the odd key repeat behaviour within about ten seconds of holding a key down. When the flag is false, it behaves as expected.

Can anyone repeat this oddity, or am I loosing it?

edit: Just tested, and it doesn’t matter if vsync is enabled before or after Display.create(). When vsync is enabled, I get the odd key repeat behaviour. Time to test in Windows methinks…

edit2: Everything works fine on windows.

edit3: It happens in both fullscreen and windowed modes

You get the exact same problem with the AWT event queue under Linux ; you have to filter the key repeat behavior.
You can see how it is done in jinput (AWTKeyboard class) or looking into Kevin Glass tutorial on the subject.

Vincent

No, this behaviour is different. The AWT key repeat happens frequently and regularly, like a good key repeat should.

The behaviour I am seeing is infrequent and very irregular (see the timestamps in the first post - those values are in seconds). In addition KeyBoard.areRepeatEventsEnabled() return false and Keyboard.isRepeatEvent() also returns false for the erroneous key events. On top of that, it only happens when vsync mode is on.

In summary, I wish it was just the AWT key repeat.

Thanks a lot for the accurate bug report. I managed to reproduce it with your test example, and I’ve comitted a fix to subversion. The problem is that X11 won’t tell us by default whether a key event is repeated so lwjgl uses a heuristic to detect them instead. The heuristic apparently fails once in a while depending on timing. The fix was to try and use an extension function to enable detection of repeated key events.

  • elias

:smiley: Great stuff

Why don’t you do like me?

if(System.getProperty(“os.name”).compareToIgnoreCase(“Linux”)==0)
try{Runtime.getRuntime().exec(“xset -r off”);
System.out.println(“xset -r off”);
}
catch(final IOException ioe)
{ioe.printStackTrace();}

and in a shutdown hook :

if(System.getProperty(“os.name”).compareToIgnoreCase(“Linux”)==0)
{try{Runtime.getRuntime().exec(“xset -r on”);
System.out.println(“xset -r on”);
}
catch(IOException ioe)
{ioe.printStackTrace();}
}

It might be improved but it works fine in TUER.