lwjgl3ify

lwjgl3ify

1.6k Downloads

WASD keys sometimes become sticky under the new version 1.2.1/1.2.2

Frefreak opened this issue ยท 2 comments

commented

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

commented

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):
image

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
                 }
commented

Reproduction steps that work for me:

  • Enable fcitx IME on arch linux
  • Limit FPS to 30 or lower
  • Hold W to walk forward until key repeat events appear
  • Release W
    Fix incoming