-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
Description
Unlike JAVA2D, P2D/P3D engines supress key repeats, i.e. no matter how long you hold the key, there will always be a single keyPressed() event. I find this key repeat supression to be too agressive, as sometimes it can cause loss of an unrelated keyPressed() event.
When the user holds down a key, only a single keyPressed() event is triggered - consequent keyPressed() events are ignored. However, if a user presses another key at the exact same time a repeated keyPressed() event of the first key is ignored, that another key's keyPressed() event gets dropped too, resulting in that second key getting completely lost until it is released, which will trigger a keyReleased() event for that second key out of nowhere.
This behavior is more likely as I increase key repeat rate in my OS settings, and less likely as I decrease it.
I believe that this is due to more key repeat events happening when I increase key repeat rate, therefore more key repeat events per second are supressed, therefore there's a higher chance of this behavior happening.
Example code
int n1,n2;
boolean held1, held2;
void setup(){size(100,100,P2D);}
void draw(){
background(0);
text(n1+" "+held1,0,15);
text(n2+" "+held2,0,30);
}
void keyPressed(){
if(key=='1'){ n1++; held1=true;}
if(key=='2'){ n2++; held2=true;}
}
void keyReleased(){
if(key=='1'){ n1--; held1=false;}
if(key=='2'){ n2--; held2=false;}
}
This code displays 2 counters n1 and n2, corresponding to keys 1 and 2 on the keyboard respectively. Each time one of those keys is pressed, a respective counter increases by 1, and on release, decreases by 1.
Expected Behavior
Both keys trigger keyPressed() events as pressed/held. Both counters displayed by the example code (n1 and n2) are always either 0 or 1, as there can't be more keyReleased() events than keyPressed() events.
Current Behavior
Second key sometimes does not trigger keyPressed() event and is left unnoticed. Second key's counter counts into negative numbers as there are more keyReleased() events than keyPressed() events.
This (shoddily filmed; sorry!) video demonstrates this behavior:
https://www.youtube.com/watch?v=wfbz_kYtNB4
The issue completely dissapears when I disable key repeat (on Linux with xset r off).
Steps to Reproduce
- Set key repeat rate to an extreme number to increase likelihood of this happening. For example, on Linux, with
xset r rate 200 255(for 200ms delay before repeat, and 255 key repeats per second) - Load and start example code above
- Hold down key
1and wait for key repeating to begin (wait 200ms with example command above) - While holding key
1, without releasing it, start holding key2 - Release both keys
- If second counter does not have a value of -1, repeat from step 3
Behavior is, obviously, also observed by first holding key 2, and then holding key 1.
Expanding the example code to also feature counters for keys 3, 4, 5, and so on allows skipping multiple keyPressed() events at once, by, instead of pressing key 2, pressing multiple keys at once. (Even more shoddily filmed - sorry for that supernova at the end!) demonstration: https://www.youtube.com/watch?v=lLmKjxQzMK0
(Note extreme key rate observed by how I moved that window using my keyboard at first - it instantly flew offscreen :D)
Expanded example code:
int n1,n2,n3,n4,n5;
boolean held1, held2, held3, held4, held5;
void setup(){size(500,500,P2D);}
void draw(){
background(0);
text(n1+" "+held1,0,15);
text(n2+" "+held2,0,30);
text(n3+" "+held3,0,45);
text(n4+" "+held4,0,60);
text(n5+" "+held5,0,75);
}
void keyPressed(){
if(key=='1'){ n1++; held1=true;}
if(key=='2'){ n2++; held2=true;}
if(key=='3'){ n3++; held3=true;}
if(key=='4'){ n4++; held4=true;}
if(key=='5'){ n5++; held5=true;}
}
void keyReleased(){
if(key=='1'){ n1--; held1=false;}
if(key=='2'){ n2--; held2=false;}
if(key=='3'){ n3--; held3=false;}
if(key=='4'){ n4--; held4=false;}
if(key=='5'){ n5--; held5=false;}
}
Your Environment
- Processing version: Processing installed from Arch Linux repositories, package version 3.5.3-3, while Processing labels itself as “Processing 0269” (as seen in example videos).
- Operating System and OS version: Arch Linux - latest version of all packages as of 6th August 2019
- Other information: Happens regardless of choice of display servers, desktop environments or window managers.
- Very unlikely to be reproduced with slow/normal key repeat rate. That's why, I guess, I'm the first one to note it, as I like really fast key repeating.
- Absolutely no applications of any kind ever drop any key press events under any circumstances or any key repeat speeds except Processing sketches on P2D/P3D.
Possible Solutions
Simple way around - introduce a function/variable that will allow key repeat events to go through on P2D/P3D, i.e. removing the suppression therefore getting rid of the bug and letting the user handle it in their code instead as they wish?
I personally would rather prefer this to be fixed, so that expected behavior would always be observed regardless of key repeat rate.
Relevant discussion: https://discourse.processing.org/t/keypressed-events-get-missed-when-another-key-is-held/12696/15