Linux: use XkbSetDetectableAutoRepeat to detect repeated key events more reliably
This commit is contained in:
parent
b5aef81f7e
commit
8f677f1585
|
@ -857,7 +857,7 @@ final class LinuxDisplay implements DisplayImplementation {
|
||||||
public void destroyKeyboard() {
|
public void destroyKeyboard() {
|
||||||
lockAWT();
|
lockAWT();
|
||||||
try {
|
try {
|
||||||
keyboard.destroy();
|
keyboard.destroy(getDisplay());
|
||||||
keyboard = null;
|
keyboard = null;
|
||||||
} finally {
|
} finally {
|
||||||
unlockAWT();
|
unlockAWT();
|
||||||
|
|
|
@ -41,6 +41,7 @@ import java.nio.charset.Charset;
|
||||||
import java.nio.charset.CharsetDecoder;
|
import java.nio.charset.CharsetDecoder;
|
||||||
|
|
||||||
import org.lwjgl.BufferUtils;
|
import org.lwjgl.BufferUtils;
|
||||||
|
import org.lwjgl.LWJGLUtil;
|
||||||
import org.lwjgl.input.Keyboard;
|
import org.lwjgl.input.Keyboard;
|
||||||
|
|
||||||
final class LinuxKeyboard {
|
final class LinuxKeyboard {
|
||||||
|
@ -122,13 +123,14 @@ final class LinuxKeyboard {
|
||||||
modeswitch_mask = tmp_modeswitch_mask;
|
modeswitch_mask = tmp_modeswitch_mask;
|
||||||
caps_lock_mask = tmp_caps_lock_mask;
|
caps_lock_mask = tmp_caps_lock_mask;
|
||||||
shift_lock_mask = tmp_shift_lock_mask;
|
shift_lock_mask = tmp_shift_lock_mask;
|
||||||
|
setDetectableKeyRepeat(display, true);
|
||||||
xim = openIM(display);
|
xim = openIM(display);
|
||||||
if (xim != 0) {
|
if (xim != 0) {
|
||||||
xic = createIC(xim, window);
|
xic = createIC(xim, window);
|
||||||
if (xic != 0) {
|
if (xic != 0) {
|
||||||
setupIMEventMask(display, window, xic);
|
setupIMEventMask(display, window, xic);
|
||||||
} else {
|
} else {
|
||||||
destroy();
|
destroy(display);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
xic = 0;
|
xic = 0;
|
||||||
|
@ -146,11 +148,19 @@ final class LinuxKeyboard {
|
||||||
private static native void setupIMEventMask(long display, long window, long xic);
|
private static native void setupIMEventMask(long display, long window, long xic);
|
||||||
private static native ByteBuffer allocateComposeStatus();
|
private static native ByteBuffer allocateComposeStatus();
|
||||||
|
|
||||||
public void destroy() {
|
private static void setDetectableKeyRepeat(long display, boolean enabled) {
|
||||||
|
boolean success = nSetDetectableKeyRepeat(display, enabled);
|
||||||
|
if (!success)
|
||||||
|
LWJGLUtil.log("Failed to set detectable key repeat");
|
||||||
|
}
|
||||||
|
private static native boolean nSetDetectableKeyRepeat(long display, boolean enabled);
|
||||||
|
|
||||||
|
public void destroy(long display) {
|
||||||
if (xic != 0)
|
if (xic != 0)
|
||||||
destroyIC(xic);
|
destroyIC(xic);
|
||||||
if (xim != 0)
|
if (xim != 0)
|
||||||
closeIM(xim);
|
closeIM(xim);
|
||||||
|
setDetectableKeyRepeat(display, false);
|
||||||
}
|
}
|
||||||
private static native void destroyIC(long xic);
|
private static native void destroyIC(long xic);
|
||||||
private static native void closeIM(long xim);
|
private static native void closeIM(long xim);
|
||||||
|
@ -300,10 +310,10 @@ final class LinuxKeyboard {
|
||||||
private void handleKeyEvent(long event_ptr, long millis, int event_type, int event_keycode, int event_state) {
|
private void handleKeyEvent(long event_ptr, long millis, int event_type, int event_keycode, int event_state) {
|
||||||
int keycode = getKeycode(event_ptr, event_state);
|
int keycode = getKeycode(event_ptr, event_state);
|
||||||
byte key_state = getKeyState(event_type);
|
byte key_state = getKeyState(event_type);
|
||||||
|
boolean repeat = key_state == key_down_buffer[keycode];
|
||||||
key_down_buffer[keycode] = key_state;
|
key_down_buffer[keycode] = key_state;
|
||||||
long nanos = millis*1000000;
|
long nanos = millis*1000000;
|
||||||
if (event_type == LinuxEvent.KeyPress) {
|
if (event_type == LinuxEvent.KeyPress) {
|
||||||
boolean repeat = false;
|
|
||||||
if (has_deferred_event) {
|
if (has_deferred_event) {
|
||||||
if (nanos == deferred_nanos && event_keycode == deferred_event_keycode) {
|
if (nanos == deferred_nanos && event_keycode == deferred_event_keycode) {
|
||||||
has_deferred_event = false;
|
has_deferred_event = false;
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
|
|
||||||
#include <X11/X.h>
|
#include <X11/X.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/XKBlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
#include "common_tools.h"
|
#include "common_tools.h"
|
||||||
|
@ -52,6 +53,14 @@ JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_getModifierMapping(J
|
||||||
return (intptr_t)modifier_map;
|
return (intptr_t)modifier_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_nSetDetectableKeyRepeat(JNIEnv *env, jclass unused, jlong display_ptr, jboolean set_enabled) {
|
||||||
|
Display *disp = (Display *)(intptr_t)display_ptr;
|
||||||
|
Bool result;
|
||||||
|
Bool enabled = set_enabled == JNI_TRUE ? True : False;
|
||||||
|
Bool success = XkbSetDetectableAutoRepeat(disp, enabled, &result);
|
||||||
|
return success && enabled == result ? JNI_TRUE : JNI_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_freeModifierMapping(JNIEnv *env, jclass unused, jlong mapping_ptr) {
|
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_freeModifierMapping(JNIEnv *env, jclass unused, jlong mapping_ptr) {
|
||||||
XModifierKeymap *modifier_map = (XModifierKeymap *)(intptr_t)mapping_ptr;
|
XModifierKeymap *modifier_map = (XModifierKeymap *)(intptr_t)mapping_ptr;
|
||||||
XFreeModifiermap(modifier_map);
|
XFreeModifiermap(modifier_map);
|
||||||
|
|
Loading…
Reference in New Issue