Bug 1106 : keyPressed()/keyReleased() missing events
Last modified: 2009-02-19 18:28




Status:
RESOLVED
Resolution:
INVALID -
Priority:
P2
Severity:
normal

 

Reporter:
44v
Assigned To:
fry

Attachment Type Created Size Actions

Description:   Opened: 2008-12-19 13:05
During development of our game, we noticed that the keyboard input system
seems to miss events sometimes. We are using simple arrow key controls, and
occasionally, releasing two keys at once (say, left and up arrows) will
result in a missing keyReleased for one of the keys. The end result for us
was the player character getting stuck moving left on screen. This happened
both on Ubuntu Linux 8.10 and on Windows XP. Printing the keyReleased calls
shows that when this happened, we received no release for the left arrow key.

I wrote a simple test which counts the number of pressed/released received
for each key. It seems to show MORE released events than pressed events.
Thus not in line with what we saw in our larger project, but still
irritating - as you'd expect the sums to be zero:

int states[] = new int[256];

void keyReleased()
{
states[keyCode]++;
}

void keyPressed()
{
states[keyCode]--;
}

void draw()
{
for(int i=0; i<256; ++i)
if(!keyPressed && states[i]!=0)
println(i + " = " + states[i]);
}

Try holding more than one arrow key, and releasing them together a few
times. Just hammer it for a while and the effect should show up.

If this is not the same problem I will try to make a true smallest-possible
repro of the exact problem in our game.

This is all using Processing v1.0.1, Ubuntu 8.10 and XP on Dell Latitude
D830's.
Additional Comment #1 From 44v 2008-12-19 13:12
No wonder it shows negative numbers, I accidentally reversed the two event
handlers. So yes, this repro also shows missing keyReleased calls. :)
Additional Comment #2 From fry 2008-12-19 14:21
try testing with the full java version instead (but note that you should
not do any drawing to the screen inside this version of keyPressed)

public void keyPressed(KeyEvent e) {
char k = e.getKeyChar();
int c = e.getKeyCode();
// now use k/c instead of key and keyCode
}

are events still dropped? if so, then it's a java problem. if not, then it
may be a processing bug.
Additional Comment #3 From 44v 2008-12-19 15:01
I'm still getting stuck keys, so I guess it's a Java problem then. Curious.

Is there no unbuffered keyboard input support in Java btw? I have noted the
lack of this in Processing. For the majority of input you'd typically use
in Processing (e.g. games and demos), it seems buffered input with the
repeat functionality is nearly useless. JInput/proControll would be
promising, but is nearly useless as device enumeration is broken IMHO (Have
to specify exact device strings and key names that vary between OS's,
vendors, and even with locale. Truly bizarre and not practical.).

I might try to look for a solution to this issue. Is there a starting point
or other pointers you can give re. the Processing source code? I'm fluent
in C-based languages and know a bit of Java, so it's more a question of
where to look. If you might have suspicions etc.
Additional Comment #4 From fry 2008-12-19 15:07
I've seen it discussed in Java game programming books (there are two big
ones that I can't recall off the top of my head) along with some APIs that
fix it or workarounds (e.g. I feel like Java3D might have something that
fixes it w/ native code, but I could be mistaken). You might try one of
those books or online sites that cover Java gaming in general.

Definitely let us know if you find anything. I suspect it's not something
we can fix in the core API, but it would be good to have a workaround to
point people at, even if it just goes in the 'hacks' section.
Additional Comment #5 From 44v 2008-12-20 08:28
I tried implementing KeyEventDispatcher in the PApplet class, and still
there are release events missing.

Is there something not being pumped? Something causing AWT events getting
stuck? I don't have much insight into the Processing threads design yet.
Additional Comment #6 From 44v 2008-12-20 09:18
Here's a trace of what I get through the KeyEventDispatcher I hooked into
PApplet:

starting...
ev+ 37 at 1229793259674
ev- 37 at 1229793259717
ev+ 38 at 1229793260287
ev- 38 at 1229793260358
ev+ 37 at 1229793261721
ev+ 38 at 1229793261743
ev- 37 at 1229793261796
ev- 38 at 1229793261807
ev+ 38 at 1229793262764
ev+ 37 at 1229793262800
ev- 38 at 1229793262854
ev- 37 at 1229793262875
ev+ 37 at 1229793264203
ev+ 38 at 1229793264219
ev- 38 at 1229793264283

...key 37 stuck here for a while until i press "v"...

ev+ 86 at 1229793268221
ev- 37 at 1229793268223
ev- 86 at 1229793268281

The long numbers are e.getWhen(). So "ev- 37" is held back until AFTER I
press the "v".. very odd. I'm going to make a pure Java repro next.
Additional Comment #7 From 44v 2008-12-22 02:18
It would also be great if someone else could test the Processing repro code
on different hardware. See the initial description for the snippet.
Additional Comment #8 From fry 2009-02-19 18:28
Unfortunately this doesn't look like something we can fix since Java isn't
even giving us the event.

Marking as "invalid" since it's not a Processing bug, but please follow up
with Sun in their bugs DB to see if you can get them to fix it in a future
release.