WASD keys sometimes become sticky under the new version 1.2.1/1.2.2
Frefreak opened this issue ยท 2 comments
After #28 the input issue has been fixed, but I notice that sometimes the wasd keys behave like it is kept being pressed, so that the character will keep moving to one direction even without any key pressed. This is relatively easy to trigger once you start walking around for a short distance.
My keyboard should be fine as I haven't noticed similar behavior under other applications.
FYI I tried lwjgl3ify 1.2.1 and 1.2.2 and they both have this annoyance. In 1.1.44 this does not happen (but it has the input issue).
OS: archlinux
EDIT: changed "arrow" key to "wasd" key
I played around for a bit with the code locally. It seems to me that sometimes the charCallback for those keys (char window
in log) will be called after the release key for them in keyCallback (key window
in log).
This is normal when I stop pressing a direction (action = 0
being the last line of this sequence):
And when it is not normal there will be additional "char window" lines for the same char after the corresponding action = 0
line, and the "sticky" issue is very likely to happen in this case.
I'm not sure what causes this that doesn't make the release event being the last event when player stops pressing the key. The most reliable way I can get to work around this is to append the release event in Keyboard.eventQueue
if there are multiple events already (so chances are that we were holding the key). Something like below:
diff --git a/src/main/java/org/lwjglx/opengl/Display.java b/src/main/java/org/lwjglx/opengl/Display.java
index 4c6f132..d862c61 100644
--- a/src/main/java/org/lwjglx/opengl/Display.java
+++ b/src/main/java/org/lwjglx/opengl/Display.java
@@ -6,6 +6,7 @@ import static org.lwjgl.system.MemoryUtil.NULL;
import java.awt.event.KeyEvent;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
+import java.util.ArrayList;
import me.eigenraven.lwjgl3ify.Lwjgl3ify;
import me.eigenraven.lwjgl3ify.core.Config;
@@ -61,6 +62,7 @@ public class Display {
private static Keyboard.KeyEvent ingredientKeyEvent;
private static ByteBuffer[] savedIcons;
+ private static ArrayList<Keyboard.KeyEvent> releaseEvents = new ArrayList<>();
static {
Sys.initialize(); // init using dummy sys method
@@ -208,9 +210,18 @@ public class Display {
if (cancelNextChar) { // Char event being cancelled
cancelNextChar = false;
} else if (ingredientKeyEvent != null) {
+ releaseEvents.clear();
+ if (Keyboard.eventQueue.size() > 1) {
+ for (Keyboard.KeyEvent evt : Keyboard.eventQueue) {
+ if (!evt.state.isPressed) {
+ releaseEvents.add(evt);
+ }
+ }
+ }
ingredientKeyEvent.aChar = (char) codepoint; // Send char with ASCII key event here
Keyboard.eventQueue.add(ingredientKeyEvent);
ingredientKeyEvent = null;
+ Keyboard.eventQueue.addAll(releaseEvents);
} else {
Keyboard.addCharEvent(0, (char) codepoint); // Non-ASCII chars
}
Using this hacky patch the problem happens a lot less frequently, but it does still happen from time to time. There should be a better way... However with this patch the game has become playable to me so I will use this personally for now.
UPDATE: this one seems to be more reliable (https://github.com/Frefreak/lwjgl3ify/commits/fix_sticky_direction_key)
diff --git a/src/main/java/org/lwjglx/opengl/Display.java b/src/main/java/org/lwjglx/opengl/Display.java
index 4c6f132..e82b187 100644
--- a/src/main/java/org/lwjglx/opengl/Display.java
+++ b/src/main/java/org/lwjglx/opengl/Display.java
@@ -6,6 +6,7 @@ import static org.lwjgl.system.MemoryUtil.NULL;
import java.awt.event.KeyEvent;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
+import java.util.ArrayList;
import me.eigenraven.lwjgl3ify.Lwjgl3ify;
import me.eigenraven.lwjgl3ify.core.Config;
@@ -61,6 +62,7 @@ public class Display {
private static Keyboard.KeyEvent ingredientKeyEvent;
private static ByteBuffer[] savedIcons;
+ private static ArrayList<Keyboard.KeyEvent> releaseEvents = new ArrayList<>();
static {
Sys.initialize(); // init using dummy sys method
@@ -208,9 +210,20 @@ public class Display {
if (cancelNextChar) { // Char event being cancelled
cancelNextChar = false;
} else if (ingredientKeyEvent != null) {
+ releaseEvents.clear();
+ for (Keyboard.KeyEvent evt : Keyboard.eventQueue) {
+ if (!evt.state.isPressed) {
+ releaseEvents.add(evt);
+ }
+ }
ingredientKeyEvent.aChar = (char) codepoint; // Send char with ASCII key event here
Keyboard.eventQueue.add(ingredientKeyEvent);
+ if (ingredientKeyEvent.state == Keyboard.KeyState.PRESS) {
+ ingredientKeyEvent = null;
+ return;
+ }
ingredientKeyEvent = null;
+ Keyboard.eventQueue.addAll(releaseEvents);
} else {
Keyboard.addCharEvent(0, (char) codepoint); // Non-ASCII chars
}