diff options
author | Sven Gothel <[email protected]> | 2012-10-26 16:43:13 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2012-10-26 16:43:13 +0200 |
commit | b008de41549e38aebdfcb7b094046235a8dde72f (patch) | |
tree | 4e51584207f22bd7203d1cc64bdab25e7a171eae /src/newt | |
parent | 4f05d5add18048c2fbd1837c0563446c11177e8c (diff) |
Fix Bug 601 - Auto-Repeat Behavior: Adding unit tests for typed key order w/ and w/o auto repeat. Incl. fix for Windows.
Auto-Repeat tests recognizes whether auto-repeat could be triggered by AWT Robot.
The latter is not possible on Windows, hence manual testing was required on this platform.
Impact: X11, Windows and OSX produce proper key sequence incl. auto-repeat modifier mask.
Diffstat (limited to 'src/newt')
-rw-r--r-- | src/newt/classes/com/jogamp/newt/event/KeyEvent.java | 11 | ||||
-rw-r--r-- | src/newt/classes/com/jogamp/newt/event/NEWTEvent.java | 6 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java | 82 | ||||
-rw-r--r-- | src/newt/native/X11Display.c | 2 |
4 files changed, 61 insertions, 40 deletions
diff --git a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java index 7daaeada6..b6f4264f5 100644 --- a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java +++ b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java @@ -48,6 +48,17 @@ package com.jogamp.newt.event; * Besides regular modifiers like {@link InputEvent#SHIFT_MASK} etc., * the {@link InputEvent#AUTOREPEAT_MASK} bit is added if repetition is detected. * </p> + * <p> + * Auto-Repeat shall behave as follow: + * <pre> + D = pressed, U = released, T = typed + 0 = normal, 1 = auto-repeat + + D(0), [ U(1), T(1), D(1), U(1) T(1) ..], U(0) T(0) + * </pre> + * The idea is if you mask out auto-repeat in your event listener + * you just get one long pressed key D/U/T triple. + * </p> */ @SuppressWarnings("serial") public class KeyEvent extends InputEvent diff --git a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java index fd5b69ccc..9d8d92ff6 100644 --- a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java +++ b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java @@ -161,11 +161,7 @@ public class NEWTEvent extends java.util.EventObject { return sb.append("NEWTEvent[sys:").append(isSystemEvent()).append(", source:").append(getSource().getClass().getName()).append(", when:").append(getWhen()).append(" d ").append((System.currentTimeMillis()-getWhen())).append("ms]"); } - public static String toHexString(int hex) { + static String toHexString(int hex) { return "0x" + Integer.toHexString(hex); } - - public static String toHexString(long hex) { - return "0x" + Long.toHexString(hex); - } } diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java index 71437c461..c211bac61 100644 --- a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java @@ -279,61 +279,73 @@ public class WindowDriver extends WindowImpl { return keyCode; } private int lastPressedKeyCode = 0; + private char lastTypedKeyChar = 0; private int pressedKeyBalance = 0; private int autoRepeat = 0; - @Override - public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { + private final void emitKeyEvent(boolean send, boolean wait, int eventType, int modifiers, int keyCode, char keyChar) { + if( send ) { + super.sendKeyEvent(eventType, modifiers, keyCode, keyChar); + } else { + super.enqueueKeyEvent(wait, eventType, modifiers, keyCode, keyChar); + } + } + + private final void handleKeyEvent(boolean send, boolean wait, int eventType, int modifiers, int keyCode, char keyChar) { + // System.err.println("*** handleKeyEvent: event "+KeyEvent.getEventTypeString(eventType)+", mods "+toHexString(modifiers)); + // Note that we have to regenerate the keyCode for EVENT_KEY_TYPED on this platform keyCode = validateKeyCode(eventType, modifiers, keyCode, keyChar); + + // Reorder: WINDOWS delivery order is PRESSED, TYPED and RELEASED -> NEWT order: PRESSED, RELEASED and TYPED + // Auto-Repeat: WINDOWS delivers only PRESSED and TYPED. switch(eventType) { case KeyEvent.EVENT_KEY_RELEASED: - // reorder: WINDOWS delivery order is PRESSED, TYPED and RELEASED -> NEWT order: PRESSED, RELEASED and TYPED + if( 0 != autoRepeat ) { + // AR out - send out missing PRESSED + emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_PRESSED, modifiers | autoRepeat, keyCode, lastTypedKeyChar); + } + autoRepeat = 0; + emitKeyEvent(send, wait, eventType, modifiers, keyCode, keyChar); + if( 0 != lastTypedKeyChar ) { + emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_TYPED, modifiers, keyCode, lastTypedKeyChar); + lastTypedKeyChar = 0; + } break; case KeyEvent.EVENT_KEY_PRESSED: - if(pressedKeyBalance > 1) { - // Auto-Repeat: WINDOWS delivers only PRESSED and TYPED. - // Since reordering already injects RELEASE, we only need to set the AUTOREPEAT_MASK. + if( pressedKeyBalance > 1 ) { pressedKeyBalance--; - autoRepeat |= InputEvent.AUTOREPEAT_MASK; + if ( 0 == autoRepeat ) { + // AR in - skip already send PRESSED + autoRepeat = InputEvent.AUTOREPEAT_MASK; + } else { + emitKeyEvent(send, wait, eventType, modifiers | autoRepeat, keyCode, (char)-1); + } } else { - autoRepeat &= ~InputEvent.AUTOREPEAT_MASK; + autoRepeat = 0; + emitKeyEvent(send, wait, eventType, modifiers, keyCode, (char)-1); } - super.sendKeyEvent(eventType, modifiers | autoRepeat, keyCode, (char)-1); break; case KeyEvent.EVENT_KEY_TYPED: - modifiers |= autoRepeat; - super.sendKeyEvent(KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, (char)-1); - super.sendKeyEvent(eventType, modifiers, keyCode, keyChar); + if( 0 == autoRepeat ) { + lastTypedKeyChar = keyChar; + } else { + modifiers |= autoRepeat; + emitKeyEvent(send, wait, KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, (char)-1); + emitKeyEvent(send, wait, eventType, modifiers, keyCode, keyChar); + } break; } } @Override + public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { + handleKeyEvent(true, false, eventType, modifiers, keyCode, keyChar); + } + + @Override public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) { - // Note that we have to regenerate the keyCode for EVENT_KEY_TYPED on this platform - keyCode = validateKeyCode(eventType, modifiers, keyCode, keyChar); - switch(eventType) { - case KeyEvent.EVENT_KEY_RELEASED: - // reorder: WINDOWS delivery order is PRESSED, TYPED and RELEASED -> NEWT order: PRESSED, RELEASED and TYPED - break; - case KeyEvent.EVENT_KEY_PRESSED: - if(pressedKeyBalance > 1) { - // Auto-Repeat: WINDOWS delivers only PRESSED and TYPED. - // Since reordering already injects RELEASE, we only need to set the AUTOREPEAT_MASK. - pressedKeyBalance--; - autoRepeat |= InputEvent.AUTOREPEAT_MASK; - } else { - autoRepeat &= ~InputEvent.AUTOREPEAT_MASK; - } - super.enqueueKeyEvent(wait, eventType, modifiers | autoRepeat, keyCode, (char)-1); - break; - case KeyEvent.EVENT_KEY_TYPED: - modifiers |= autoRepeat; - super.enqueueKeyEvent(wait, KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, (char)-1); - super.enqueueKeyEvent(wait, eventType, modifiers, keyCode, keyChar); - break; - } + handleKeyEvent(false, wait, eventType, modifiers, keyCode, keyChar); } //---------------------------------------------------------------------- diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c index d8202fcde..9f29acc0c 100644 --- a/src/newt/native/X11Display.c +++ b/src/newt/native/X11Display.c @@ -381,6 +381,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage } else { autoRepeatModifiers &= ~EVENT_AUTOREPEAT_MASK; } + } else { + autoRepeatModifiers &= ~EVENT_AUTOREPEAT_MASK; } // fall through intended case KeyPress: |