use timestamp matching hack to detect key repeat events instead of globally disabling keyboard repeating

This commit is contained in:
Elias Naur 2007-05-13 20:13:37 +00:00
parent 691f471f7d
commit b5e6d79ea9
2 changed files with 37 additions and 14 deletions

View File

@ -404,7 +404,6 @@ final class LinuxDisplay implements DisplayImplementation {
minimized = false; minimized = false;
dirty = true; dirty = true;
updateInputGrab(); updateInputGrab();
nSetRepeatMode(getDisplay(), AutoRepeatModeOff);
} finally { } finally {
peer_info.unlock(); peer_info.unlock();
} }
@ -435,7 +434,6 @@ final class LinuxDisplay implements DisplayImplementation {
blank_cursor = None; blank_cursor = None;
ungrabKeyboard(); ungrabKeyboard();
nDestroyWindow(getDisplay(), getWindow()); nDestroyWindow(getDisplay(), getWindow());
nSetRepeatMode(getDisplay(), AutoRepeatModeDefault);
decDisplay(); decDisplay();
} finally { } finally {
unlockAWT(); unlockAWT();
@ -764,7 +762,6 @@ final class LinuxDisplay implements DisplayImplementation {
if (isLegacyFullscreen() || input_released) if (isLegacyFullscreen() || input_released)
return; return;
input_released = true; input_released = true;
nSetRepeatMode(getDisplay(), AutoRepeatModeDefault);
updateInputGrab(); updateInputGrab();
if (current_window_mode == FULLSCREEN_NETWM) { if (current_window_mode == FULLSCREEN_NETWM) {
nIconifyWindow(getDisplay(), getWindow(), getDefaultScreen()); nIconifyWindow(getDisplay(), getWindow(), getDefaultScreen());
@ -782,7 +779,6 @@ final class LinuxDisplay implements DisplayImplementation {
if (isLegacyFullscreen() || !input_released) if (isLegacyFullscreen() || !input_released)
return; return;
input_released = false; input_released = false;
nSetRepeatMode(getDisplay(), AutoRepeatModeOff);
updateInputGrab(); updateInputGrab();
if (current_window_mode == FULLSCREEN_NETWM) { if (current_window_mode == FULLSCREEN_NETWM) {
try { try {

View File

@ -47,8 +47,6 @@ import java.nio.charset.Charset;
final class LinuxKeyboard { final class LinuxKeyboard {
private static final int LockMapIndex = 1; private static final int LockMapIndex = 1;
private static final int KeyPress = 2;
private static final int KeyRelease = 3;
private static final long NoSymbol = 0; private static final long NoSymbol = 0;
private static final long ShiftMask = 1 << 0; private static final long ShiftMask = 1 << 0;
private static final long LockMask = 1 << 1; private static final long LockMask = 1 << 1;
@ -76,6 +74,13 @@ final class LinuxKeyboard {
private final CharsetDecoder utf8_decoder = Charset.forName("UTF-8").newDecoder(); private final CharsetDecoder utf8_decoder = Charset.forName("UTF-8").newDecoder();
private final CharBuffer char_buffer = CharBuffer.allocate(KEYBOARD_BUFFER_SIZE); private final CharBuffer char_buffer = CharBuffer.allocate(KEYBOARD_BUFFER_SIZE);
// Deferred key released event, to detect key repeat
private boolean has_deferred_event = true;
private int deferred_keycode;
private int deferred_event_keycode;
private long deferred_nanos;
private byte deferred_key_state;
public LinuxKeyboard(long display, long window) { public LinuxKeyboard(long display, long window) {
long modifier_map = getModifierMapping(display); long modifier_map = getModifierMapping(display);
int tmp_numlock_mask = 0; int tmp_numlock_mask = 0;
@ -153,10 +158,12 @@ final class LinuxKeyboard {
private static native void closeIM(long xim); private static native void closeIM(long xim);
public void read(ByteBuffer buffer) { public void read(ByteBuffer buffer) {
flushDeferredEvent();
event_queue.copyEvents(buffer); event_queue.copyEvents(buffer);
} }
public void poll(ByteBuffer keyDownBuffer) { public void poll(ByteBuffer keyDownBuffer) {
flushDeferredEvent();
int old_position = keyDownBuffer.position(); int old_position = keyDownBuffer.position();
keyDownBuffer.put(key_down_buffer); keyDownBuffer.put(key_down_buffer);
keyDownBuffer.position(old_position); keyDownBuffer.position(old_position);
@ -204,14 +211,10 @@ final class LinuxKeyboard {
return lookupStringISO88591(event_ptr, translation_buffer); return lookupStringISO88591(event_ptr, translation_buffer);
} }
private void translateEvent(long event_ptr, int event_type, int keycode, byte key_state, long nanos) { private void translateEvent(long event_ptr, int keycode, byte key_state, long nanos) {
int num_chars, i; int num_chars, i;
int ch; int ch;
if (event_type == KeyRelease) {
putKeyboardEvent(keycode, key_state, 0, nanos);
return;
}
num_chars = lookupString(event_ptr, temp_translation_buffer); num_chars = lookupString(event_ptr, temp_translation_buffer);
if (num_chars > 0) { if (num_chars > 0) {
ch = temp_translation_buffer[0]; ch = temp_translation_buffer[0];
@ -287,9 +290,9 @@ final class LinuxKeyboard {
private byte getKeyState(int event_type) { private byte getKeyState(int event_type) {
switch (event_type) { switch (event_type) {
case KeyPress: case LinuxEvent.KeyPress:
return 1; return 1;
case KeyRelease: case LinuxEvent.KeyRelease:
return 0; return 0;
default: default:
throw new IllegalArgumentException("Unknown event_type: " + event_type); throw new IllegalArgumentException("Unknown event_type: " + event_type);
@ -300,7 +303,31 @@ final class LinuxKeyboard {
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);
key_down_buffer[keycode] = key_state; key_down_buffer[keycode] = key_state;
translateEvent(event_ptr, event_type, keycode, key_state, millis*1000000); long nanos = millis*1000000;
if (event_type == LinuxEvent.KeyPress) {
if (has_deferred_event) {
if (nanos == deferred_nanos && event_keycode == deferred_event_keycode) {
has_deferred_event = false;
return; // Repeated event, ignore it
}
flushDeferredEvent();
}
translateEvent(event_ptr, keycode, key_state, nanos);
} else {
flushDeferredEvent();
has_deferred_event = true;
deferred_keycode = keycode;
deferred_event_keycode = event_keycode;
deferred_nanos = nanos;
deferred_key_state = key_state;
}
}
private void flushDeferredEvent() {
if (has_deferred_event) {
putKeyboardEvent(deferred_keycode, deferred_key_state, 0, deferred_nanos);
has_deferred_event = false;
}
} }
public boolean filterEvent(LinuxEvent event) { public boolean filterEvent(LinuxEvent event) {