[BUG] Dead key press events filtered out by XFilterEvent

Started by ClémentV, August 20, 2014, 12:53:07

Previous topic - Next topic

ClémentV

I am using a french keyboard (azerty layout) on Linux. The dead key ^ does not generate any press event.

Using the simple test program:
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;

public class KeyboardTest {
        public static void main (String[] args) {
                try {
                        Display.setDisplayMode (new DisplayMode (800, 600));
                        Display.create ();
                }
                catch (LWJGLException e) {
                        e.printStackTrace ();
                        System.exit (0);
                }

                while (!Display.isCloseRequested ()) {
                        while (Keyboard.next ()) {
                                String state;
                                if (Keyboard.getEventKeyState ())
                                        state = "pressed";
                                else
                                        state = "released";
                                int key = Keyboard.getEventKey ();
                                char c = Keyboard.getEventCharacter ();
                                System.out.println (Keyboard.getKeyName (key) + " (" + c + ", " + key + ") " + state);
                        }
                        Display.update ();
                }

                Display.destroy ();
        }
}


Pressing "^", then "a" gives :
CIRCUMFLEX (, 144) released
NONE (â, 0) pressed
A (, 30) released

Both the CIRCUMFLEX and A press events are missing.

I found a patch for SDL fixing a similar bug: http://lists.libsdl.org/pipermail/commits-libsdl.org/2013-November/007586.html
Discussion can be found here: http://lists.libsdl.org/pipermail/sdl-libsdl.org/2013-November/091894.html

I don't really understand how XFilterEvent works (or more generally X11 input API). But I tried to make the same hack in lwjgl :
JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_LinuxEvent_nFilterEvent(JNIEnv *env, jclass unused, jobject event_buffer, jlong window_ptr) {
	XEvent *event = (XEvent *)(*env)->GetDirectBufferAddress(env, event_buffer);
	Window window = (Window)window_ptr;
	int keycode = 0;
	if (event->type == KeyPress || event->type == KeyRelease)
		keycode = event->xkey.keycode;
	if (XFilterEvent(event, window) == True) {
		if (keycode != 0) {
			event->xkey.keycode = keycode;
			return JNI_FALSE;
		}
		return JNI_TRUE;
	}
	else
		return JNI_FALSE;
}

Now, my test program is giving the expected result:
CIRCUMFLEX (, 144) pressed
CIRCUMFLEX (, 144) released
A (a, 30) pressed
NONE (â, 0) pressed
A (, 30) released


I don't know the X11 API enough to say if it is a Xorg or LWJGL bug, but the SDL guys seem to think it was worth a workaround.

Edit: I investigated this issue because of a bug in Minecraft: https://bugs.mojang.com/browse/MC-30704
Using this hack in Minecraft make the ^ key usable for in game action, but when writing in the chat two characters are printed: a and â.