7124272: [macosx] VK_DELETE does produce an extraneous character in a TextArea or TextField
Reviewed-by: kizune, art
This commit is contained in:
parent
93c317d8e6
commit
8263a06f21
@ -158,11 +158,20 @@ final class CPlatformResponder {
|
|||||||
NSEvent.nsToJavaEventType(eventType);
|
NSEvent.nsToJavaEventType(eventType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char javaChar = NSEvent.nsToJavaChar(testChar, modifierFlags);
|
||||||
|
// Some keys may generate a KEY_TYPED, but we can't determine
|
||||||
|
// what that character is. That's likely a bug, but for now we
|
||||||
|
// just check for CHAR_UNDEFINED.
|
||||||
|
if (javaChar == KeyEvent.CHAR_UNDEFINED) {
|
||||||
|
postsTyped = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int jmodifiers = NSEvent.nsToJavaKeyModifiers(modifierFlags);
|
int jmodifiers = NSEvent.nsToJavaKeyModifiers(modifierFlags);
|
||||||
long when = System.currentTimeMillis();
|
long when = System.currentTimeMillis();
|
||||||
|
|
||||||
peer.dispatchKeyEvent(jeventType, when, jmodifiers,
|
peer.dispatchKeyEvent(jeventType, when, jmodifiers,
|
||||||
jkeyCode, testChar, jkeyLocation);
|
jkeyCode, javaChar, jkeyLocation);
|
||||||
|
|
||||||
// That's the reaction on the PRESSED (not RELEASED) event as it comes to
|
// That's the reaction on the PRESSED (not RELEASED) event as it comes to
|
||||||
// appear in MacOSX.
|
// appear in MacOSX.
|
||||||
@ -172,7 +181,7 @@ final class CPlatformResponder {
|
|||||||
boolean isMetaDown = (jmodifiers & KeyEvent.META_DOWN_MASK) != 0;
|
boolean isMetaDown = (jmodifiers & KeyEvent.META_DOWN_MASK) != 0;
|
||||||
if (jeventType == KeyEvent.KEY_PRESSED && postsTyped && !isMetaDown) {
|
if (jeventType == KeyEvent.KEY_PRESSED && postsTyped && !isMetaDown) {
|
||||||
peer.dispatchKeyEvent(KeyEvent.KEY_TYPED, when, jmodifiers,
|
peer.dispatchKeyEvent(KeyEvent.KEY_TYPED, when, jmodifiers,
|
||||||
KeyEvent.VK_UNDEFINED, testChar,
|
KeyEvent.VK_UNDEFINED, javaChar,
|
||||||
KeyEvent.KEY_LOCATION_UNKNOWN);
|
KeyEvent.KEY_LOCATION_UNKNOWN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,6 +245,12 @@ public final class NSEvent {
|
|||||||
*/
|
*/
|
||||||
public static native void nsKeyModifiersToJavaKeyInfo(int[] in, int[] out);
|
public static native void nsKeyModifiersToJavaKeyInfo(int[] in, int[] out);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There is a small number of NS characters that need to be converted
|
||||||
|
* into other characters before we pass them to AWT.
|
||||||
|
*/
|
||||||
|
public static native char nsToJavaChar(char nsChar, int modifierFlags);
|
||||||
|
|
||||||
public static boolean isPopupTrigger(int jmodifiers) {
|
public static boolean isPopupTrigger(int jmodifiers) {
|
||||||
final boolean isRightButtonDown = ((jmodifiers & InputEvent.BUTTON3_DOWN_MASK) != 0);
|
final boolean isRightButtonDown = ((jmodifiers & InputEvent.BUTTON3_DOWN_MASK) != 0);
|
||||||
final boolean isLeftButtonDown = ((jmodifiers & InputEvent.BUTTON1_DOWN_MASK) != 0);
|
final boolean isLeftButtonDown = ((jmodifiers & InputEvent.BUTTON1_DOWN_MASK) != 0);
|
||||||
|
@ -308,6 +308,9 @@ const nsKeyToJavaModifierTable[] =
|
|||||||
* Almost all unicode characters just go from NS to Java with no translation.
|
* Almost all unicode characters just go from NS to Java with no translation.
|
||||||
* For the few exceptions, we handle it here with this small table.
|
* For the few exceptions, we handle it here with this small table.
|
||||||
*/
|
*/
|
||||||
|
#define ALL_NS_KEY_MODIFIERS_MASK \
|
||||||
|
(NSShiftKeyMask | NSControlKeyMask | NSAlternateKeyMask | NSCommandKeyMask)
|
||||||
|
|
||||||
static struct _char {
|
static struct _char {
|
||||||
NSUInteger modifier;
|
NSUInteger modifier;
|
||||||
unichar nsChar;
|
unichar nsChar;
|
||||||
@ -315,17 +318,17 @@ static struct _char {
|
|||||||
}
|
}
|
||||||
const charTable[] = {
|
const charTable[] = {
|
||||||
// map enter on keypad to same as return key
|
// map enter on keypad to same as return key
|
||||||
{0, NSEnterCharacter, NSNewlineCharacter},
|
{0, NSEnterCharacter, NSNewlineCharacter},
|
||||||
|
|
||||||
// [3134616] return newline instead of carriage return
|
// [3134616] return newline instead of carriage return
|
||||||
{0, NSCarriageReturnCharacter, NSNewlineCharacter},
|
{0, NSCarriageReturnCharacter, NSNewlineCharacter},
|
||||||
|
|
||||||
// "delete" means backspace in Java
|
// "delete" means backspace in Java
|
||||||
{0, NSDeleteCharacter, NSBackspaceCharacter},
|
{ALL_NS_KEY_MODIFIERS_MASK, NSDeleteCharacter, NSBackspaceCharacter},
|
||||||
{0, NSDeleteFunctionKey, NSDeleteCharacter},
|
{ALL_NS_KEY_MODIFIERS_MASK, NSDeleteFunctionKey, NSDeleteCharacter},
|
||||||
|
|
||||||
// back-tab is only differentiated from tab by Shift flag
|
// back-tab is only differentiated from tab by Shift flag
|
||||||
{NSShiftKeyMask, NSBackTabCharacter, NSTabCharacter},
|
{NSShiftKeyMask, NSBackTabCharacter, NSTabCharacter},
|
||||||
|
|
||||||
{0, 0, 0}
|
{0, 0, 0}
|
||||||
};
|
};
|
||||||
@ -334,12 +337,8 @@ static unichar
|
|||||||
NsCharToJavaChar(unichar nsChar, NSUInteger modifiers)
|
NsCharToJavaChar(unichar nsChar, NSUInteger modifiers)
|
||||||
{
|
{
|
||||||
const struct _char *cur;
|
const struct _char *cur;
|
||||||
NSUInteger keyModifierFlags =
|
|
||||||
NSShiftKeyMask | NSControlKeyMask |
|
|
||||||
NSAlternateKeyMask | NSCommandKeyMask;
|
|
||||||
|
|
||||||
// Mask off just the keyboard modifiers from the event modifier mask.
|
// Mask off just the keyboard modifiers from the event modifier mask.
|
||||||
NSUInteger testableFlags = (modifiers & keyModifierFlags);
|
NSUInteger testableFlags = (modifiers & ALL_NS_KEY_MODIFIERS_MASK);
|
||||||
|
|
||||||
// walk through table & find the match
|
// walk through table & find the match
|
||||||
for (cur = charTable; cur->nsChar != 0 ; cur++) {
|
for (cur = charTable; cur->nsChar != 0 ; cur++) {
|
||||||
@ -507,189 +506,6 @@ NsKeyModifiersToJavaModifiers(NSUInteger nsFlags)
|
|||||||
return javaModifiers;
|
return javaModifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns the correct java character for a key event. Most unicode
|
|
||||||
* characters don't require any fussing, but a few seem to need adjusting,
|
|
||||||
* see nsCharToJavaChar.
|
|
||||||
*/
|
|
||||||
static unichar
|
|
||||||
GetJavaCharacter(NSEvent *event, unsigned int index)
|
|
||||||
{
|
|
||||||
unichar returnValue = java_awt_event_KeyEvent_CHAR_UNDEFINED;
|
|
||||||
NSString *chars = nil;
|
|
||||||
unichar testChar = 0, testDeadChar = 0;
|
|
||||||
jint javaModifiers = NsKeyModifiersToJavaModifiers([event modifierFlags]);
|
|
||||||
|
|
||||||
switch ([event type]) {
|
|
||||||
case NSFlagsChanged:
|
|
||||||
// no character for modifier keys
|
|
||||||
returnValue = java_awt_event_KeyEvent_CHAR_UNDEFINED;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NSKeyDown:
|
|
||||||
case NSKeyUp:
|
|
||||||
chars = [event characters];
|
|
||||||
if ([chars length] > 0) {
|
|
||||||
testChar = [chars characterAtIndex:index];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (javaModifiers == 0) {
|
|
||||||
// TODO: uses SPI...
|
|
||||||
//if (TSMGetDeadKeyState() != 0) {
|
|
||||||
// testDeadChar = [self deadKeyCharacter];
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (testChar != 0) {
|
|
||||||
returnValue = NsCharToJavaChar(testChar, [event modifierFlags]);
|
|
||||||
} else if (testDeadChar != 0) {
|
|
||||||
returnValue = NsCharToJavaChar(testDeadChar, [event modifierFlags]);
|
|
||||||
} else {
|
|
||||||
returnValue = java_awt_event_KeyEvent_CHAR_UNDEFINED;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
//[NSException raise:@"AWT error" format:@"Attempt to get character code from non-key event!"];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
static jchar
|
|
||||||
GetDeadKeyCharacter(NSEvent *event)
|
|
||||||
{
|
|
||||||
// If the current event is not a dead key, return 0.
|
|
||||||
// TODO: this uses SPI; it's an optimization but not strictly necessary
|
|
||||||
//if (TSMGetDeadKeyState() == 0) {
|
|
||||||
// return 0;
|
|
||||||
//}
|
|
||||||
|
|
||||||
// AppKit does not track dead-key states directly, but TSM does. Even then,
|
|
||||||
// it's not necessarily all that accurate, because the dead key can change
|
|
||||||
// given some combination of modifier keys on certain layouts.
|
|
||||||
// As a result, finding the unicode value for the front end of the dead
|
|
||||||
// key is a bit of a heuristic.
|
|
||||||
|
|
||||||
// This algorithm was suggested by Aki Inoue.
|
|
||||||
// When you get a dead key, you need to simiulate what would happen in
|
|
||||||
// the current dead-key and modifier state if the user hit the spacebar.
|
|
||||||
// That will tell you the front end of the dead-key combination.
|
|
||||||
|
|
||||||
unichar returnValue = 0;
|
|
||||||
const UInt16 VIRTUAL_KEY_SPACE = 49;
|
|
||||||
UInt32 deadKeyState = 0;
|
|
||||||
UInt32 appkitFlags = [event modifierFlags];
|
|
||||||
UniCharCount actualStringLength;
|
|
||||||
UniChar unicodeInputString[16];
|
|
||||||
TISInputSourceRef keyLayout;
|
|
||||||
const void *chrData;
|
|
||||||
|
|
||||||
keyLayout = TISCopyCurrentKeyboardLayoutInputSource();
|
|
||||||
CFDataRef cfUchrData =
|
|
||||||
TISGetInputSourceProperty(keyLayout, kTISPropertyUnicodeKeyLayoutData);
|
|
||||||
|
|
||||||
if (cfUchrData == NULL) {
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The actual 'uchr' table is inside the CFDataRef.
|
|
||||||
chrData = CFDataGetBytePtr(cfUchrData);
|
|
||||||
|
|
||||||
UInt8 keyboardType = LMGetKbdType();
|
|
||||||
UInt32 keyEventModifiers = 0;
|
|
||||||
if (appkitFlags & NSShiftKeyMask) keyEventModifiers |= shiftKey;
|
|
||||||
if (appkitFlags & NSCommandKeyMask) keyEventModifiers |= cmdKey;
|
|
||||||
if (appkitFlags & NSAlphaShiftKeyMask) keyEventModifiers |= alphaLock;
|
|
||||||
if (appkitFlags & NSControlKeyMask) keyEventModifiers |= controlKey;
|
|
||||||
if (appkitFlags & NSAlternateKeyMask) keyEventModifiers |= optionKey;
|
|
||||||
|
|
||||||
if (noErr == UCKeyTranslate(chrData,
|
|
||||||
VIRTUAL_KEY_SPACE,
|
|
||||||
([event type] == NSKeyDown ? kUCKeyActionDown : kUCKeyActionUp),
|
|
||||||
keyEventModifiers,
|
|
||||||
keyboardType,
|
|
||||||
kUCKeyTranslateNoDeadKeysMask,
|
|
||||||
&deadKeyState,
|
|
||||||
16,
|
|
||||||
&actualStringLength,
|
|
||||||
unicodeInputString))
|
|
||||||
{
|
|
||||||
if (actualStringLength > 0) {
|
|
||||||
returnValue = unicodeInputString[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
// REMIND: The fix for MACOSX_PORT-539 introduces Java-level implementation
|
|
||||||
// of the function below (see CPlatformResponder). Consider removing this code.
|
|
||||||
|
|
||||||
void
|
|
||||||
DeliverJavaKeyEvent(JNIEnv *env, NSEvent *event, jobject peer)
|
|
||||||
{
|
|
||||||
jint javaKeyType = java_awt_event_KeyEvent_KEY_PRESSED;
|
|
||||||
jint javaKeyCode = java_awt_event_KeyEvent_VK_UNDEFINED;
|
|
||||||
jint javaKeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN;
|
|
||||||
NSString *chars = nil;
|
|
||||||
BOOL postsTyped;
|
|
||||||
unichar testChar = java_awt_event_KeyEvent_CHAR_UNDEFINED;
|
|
||||||
unichar testDeadChar = 0;
|
|
||||||
jint javaModifiers = 0;
|
|
||||||
|
|
||||||
switch ([event type]) {
|
|
||||||
case NSFlagsChanged:
|
|
||||||
NsKeyModifiersToJavaKeyInfo([event modifierFlags],
|
|
||||||
[event keyCode],
|
|
||||||
&javaKeyCode,
|
|
||||||
&javaKeyLocation,
|
|
||||||
&javaKeyType);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NSKeyDown:
|
|
||||||
case NSKeyUp:
|
|
||||||
chars = [event charactersIgnoringModifiers];
|
|
||||||
if ([chars length] > 0) {
|
|
||||||
testChar = [chars characterAtIndex:0];
|
|
||||||
}
|
|
||||||
|
|
||||||
javaModifiers = NsKeyModifiersToJavaModifiers([event modifierFlags]);
|
|
||||||
if (javaModifiers == 0) {
|
|
||||||
// TODO: dead key chars
|
|
||||||
// testDeadChar = GetDeadKeyCharacter(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
NsCharToJavaVirtualKeyCode(testChar, testDeadChar,
|
|
||||||
[event modifierFlags], [event keyCode],
|
|
||||||
&javaKeyCode, &javaKeyLocation, &postsTyped);
|
|
||||||
if( !postsTyped ) {
|
|
||||||
testChar = java_awt_event_KeyEvent_CHAR_UNDEFINED;
|
|
||||||
}
|
|
||||||
|
|
||||||
javaKeyType = ([event type] == NSKeyDown) ?
|
|
||||||
java_awt_event_KeyEvent_KEY_PRESSED :
|
|
||||||
java_awt_event_KeyEvent_KEY_RELEASED;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
//[NSException raise:@"AWT error" format:@"Attempt to get virtual key code from non-key event!"];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (env != NULL) {
|
|
||||||
static JNF_CLASS_CACHE(jc_CPlatformView, "sun/lwawt/macosx/CPlatformView");
|
|
||||||
static JNF_MEMBER_CACHE(jm_deliverKeyEvent, jc_CPlatformView, "deliverKeyEvent", "(IICII)V");
|
|
||||||
JNFCallVoidMethod(env, peer, jm_deliverKeyEvent,
|
|
||||||
javaKeyType, javaModifiers,
|
|
||||||
testChar, javaKeyCode, javaKeyLocation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jint GetJavaMouseModifiers(NSInteger button, NSUInteger modifierFlags)
|
jint GetJavaMouseModifiers(NSInteger button, NSUInteger modifierFlags)
|
||||||
{
|
{
|
||||||
// Mousing needs the key modifiers
|
// Mousing needs the key modifiers
|
||||||
@ -726,217 +542,6 @@ jint GetJavaMouseModifiers(NSInteger button, NSUInteger modifierFlags)
|
|||||||
return modifiers;
|
return modifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Converts an NSEvent button number to a MouseEvent constant.
|
|
||||||
*/
|
|
||||||
static jint
|
|
||||||
NSButtonToJavaButton(NSInteger nsButtonNumber)
|
|
||||||
{
|
|
||||||
jint jbutton = java_awt_event_MouseEvent_NOBUTTON;
|
|
||||||
|
|
||||||
if (nsButtonNumber == 0) { // left
|
|
||||||
jbutton = java_awt_event_MouseEvent_BUTTON1;
|
|
||||||
} else if (nsButtonNumber == 1) { // right
|
|
||||||
jbutton = java_awt_event_MouseEvent_BUTTON3;
|
|
||||||
} else if (nsButtonNumber == 2) { // middle
|
|
||||||
jbutton = java_awt_event_MouseEvent_BUTTON2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return jbutton;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static BOOL isDragging = NO;
|
|
||||||
|
|
||||||
void
|
|
||||||
DeliverMouseClickedEvent(JNIEnv *env, NSEvent *event, jobject peer)
|
|
||||||
{
|
|
||||||
NSPoint pt = [event locationInWindow];
|
|
||||||
NSPoint pOnScreen = [NSEvent mouseLocation];
|
|
||||||
jint etype = java_awt_event_MouseEvent_MOUSE_CLICKED;
|
|
||||||
jint modifiers = GetJavaMouseModifiers([event buttonNumber], [event modifierFlags]);
|
|
||||||
jint clickCount = [event clickCount];
|
|
||||||
jint button = NSButtonToJavaButton([event buttonNumber]);
|
|
||||||
|
|
||||||
if (env != NULL) {
|
|
||||||
static JNF_CLASS_CACHE(jc_CPlatformView, "sun/lwawt/macosx/CPlatformView");
|
|
||||||
static JNF_MEMBER_CACHE(jm_deliverMouseEvent, jc_CPlatformView,
|
|
||||||
"deliverMouseEvent", "(IIIIFFFF)V");
|
|
||||||
JNFCallVoidMethod(env, peer, jm_deliverMouseEvent,
|
|
||||||
etype, modifiers,
|
|
||||||
clickCount, button,
|
|
||||||
pt.x, pt.y,
|
|
||||||
pOnScreen.x, pOnScreen.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* After every key down event, this is called to make the matching
|
|
||||||
* KEY_TYPED (if this key posts those). We use the same NSEvent for it,
|
|
||||||
* but create a KEY_TYPED java event this time.
|
|
||||||
* If this key doesn't post typed, we don't post the event.
|
|
||||||
*
|
|
||||||
* TODO: some duplicated effort here; could just fold it
|
|
||||||
* into DeliverJavaKeyEvent...
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
DeliverKeyTypedEvents(JNIEnv *env, NSEvent *nsEvent, jobject peer)
|
|
||||||
{
|
|
||||||
if (peer == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
jint javaKeyCode, javaKeyLocation;
|
|
||||||
BOOL postsTyped = NO;
|
|
||||||
unichar testChar, testDeadChar = 0;
|
|
||||||
jint javaModifiers = NsKeyModifiersToJavaModifiers([nsEvent modifierFlags]);
|
|
||||||
|
|
||||||
if (javaModifiers == 0) {
|
|
||||||
testDeadChar = [nsEvent deadKeyCharacter];
|
|
||||||
}
|
|
||||||
|
|
||||||
NSString *theChars = [nsEvent characters];
|
|
||||||
unsigned i, stringLength = [theChars length];
|
|
||||||
|
|
||||||
for (i = 0; i < stringLength; i++) {
|
|
||||||
testChar = [theChars characterAtIndex:i];
|
|
||||||
NsCharToJavaVirtualKeyCode(testChar, testDeadChar,
|
|
||||||
[nsEvent modifierFlags], [nsEvent keyCode],
|
|
||||||
&javaKeyCode, &javaKeyLocation, &postsTyped);
|
|
||||||
|
|
||||||
if (postsTyped) {
|
|
||||||
// Some keys may generate a KEY_TYPED, but we can't determine
|
|
||||||
// what that character is. That's likely a bug, but for now we
|
|
||||||
// just check for CHAR_UNDEFINED.
|
|
||||||
unichar theChar = GetJavaCharacter(nsEvent, i);
|
|
||||||
if (theChar != java_awt_event_KeyEvent_CHAR_UNDEFINED) {
|
|
||||||
if (env != NULL) {
|
|
||||||
static JNF_CLASS_CACHE(jc_CPlatformView,
|
|
||||||
"sun/lwawt/macosx/CPlatformView");
|
|
||||||
static JNF_MEMBER_CACHE(jm_deliverKeyEvent, jc_CPlatformView,
|
|
||||||
"deliverKeyEvent", "(IICII)V");
|
|
||||||
JNFCallVoidMethod(env, peer, jm_deliverKeyEvent,
|
|
||||||
java_awt_event_KeyEvent_KEY_TYPED,
|
|
||||||
javaModifiers,
|
|
||||||
theChar,
|
|
||||||
java_awt_event_KeyEvent_VK_UNDEFINED,
|
|
||||||
java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* There are a couple of extra events that Java expects to get that don't
|
|
||||||
* actually correspond to a direct NSEvent, KEY_TYPED and MOUSE_CLICKED are
|
|
||||||
* both extra events that are sort of redundant with ordinary
|
|
||||||
* key downs and mouse ups. In this extra message, we take the original
|
|
||||||
* input event and if necessary, cons up a special follow-on event which
|
|
||||||
* we dispatch over to Java.
|
|
||||||
*
|
|
||||||
* For Java, keyDown's generate a KeyPressed (for each hardware key as it
|
|
||||||
* goes down) and then a "logical KeyTyped" event for the key event. (So
|
|
||||||
* a shift-a generates two presses, one keytyped of "A", and then two
|
|
||||||
* releases). The standard event utility function converts a key down to
|
|
||||||
* a key pressed. When appropriate, we need to cons up another event
|
|
||||||
* (KEY_TYPED) to follow a keyDown.
|
|
||||||
*
|
|
||||||
* Java expects you to send a clicked event if you got a down & up, with no
|
|
||||||
* intervening drag. So in addition to the MOUSE_RELEASED event that a
|
|
||||||
* mouseUp is translated to, we also have to cons up a MOUSE_CLICKED event
|
|
||||||
* for that case. Mike Paquette, god of Window Server event handling,
|
|
||||||
* confirmed this fact about how to determine if a mouse up event had an
|
|
||||||
* intervening drag:
|
|
||||||
* An initial mouse-down gets a click count of 1. Subsequent left or right
|
|
||||||
* mouse-downs within the space/time tolerance limits increment the click
|
|
||||||
* count. A mouse-up will have the clickCount of the last mouseDown if
|
|
||||||
* mouse is not outside the tolerance limits, but 0 otherwise. Thus, a
|
|
||||||
* down-up sequence without any intervening drag will have a click count
|
|
||||||
* of 0 in the mouse-up event. NOTE: The problem with this is that
|
|
||||||
* clickCount goes to zero after some point in time. So a long, click &
|
|
||||||
* hold without moving and then release the mouse doesn't create a
|
|
||||||
* MOUSE_CLICK event as it should. Java AWT now tracks the drag state itself.
|
|
||||||
*
|
|
||||||
* As another add-on, we also check for the status of mouse-motion events
|
|
||||||
* after a mouse-down, so we know whether to generate mouse-dragged events
|
|
||||||
* during this down sequence.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
SendAdditionalJavaEvents(JNIEnv *env, NSEvent *nsEvent, jobject peer)
|
|
||||||
{
|
|
||||||
AWT_ASSERT_APPKIT_THREAD;
|
|
||||||
|
|
||||||
NSEventType type = [nsEvent type];
|
|
||||||
switch (type) {
|
|
||||||
case NSKeyDown:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NSLeftMouseUp:
|
|
||||||
case NSRightMouseUp:
|
|
||||||
case NSOtherMouseUp:
|
|
||||||
// TODO: we may need to pull in changedDragToMove here...
|
|
||||||
//if (!isDragging && ([NSViewAWT changedDragToMove]==NO)) {
|
|
||||||
if (!isDragging) {
|
|
||||||
// got down/up pair with no dragged in between; ignores drag events
|
|
||||||
// that have been morphed to move events
|
|
||||||
DeliverMouseClickedEvent(env, nsEvent, peer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// TODO: to be implemented...
|
|
||||||
#if 0
|
|
||||||
case NSLeftMouseDragged:
|
|
||||||
case NSRightMouseDragged:
|
|
||||||
case NSOtherMouseDragged:
|
|
||||||
//
|
|
||||||
// During a drag, the AppKit does not send mouseEnter and mouseExit
|
|
||||||
// events. It turns out that doing a hitTest causes the window's
|
|
||||||
// view hierarchy to be locked from drawing and that, of course,
|
|
||||||
// slows everything way down. Synthesize mouseEnter and mouseExit
|
|
||||||
// then forward.
|
|
||||||
//
|
|
||||||
NSView *hitView = [[source model] hitTest:[nsEvent locationInWindow]];
|
|
||||||
|
|
||||||
if ((hitView != nil) &&
|
|
||||||
([hitView conformsToProtocol:@protocol(AWTPeerControl)]))
|
|
||||||
{
|
|
||||||
if (sLastMouseDraggedView == nil) {
|
|
||||||
sLastMouseDraggedView = hitView;
|
|
||||||
}
|
|
||||||
else if (hitView != sLastMouseDraggedView) {
|
|
||||||
// We know sLastMouseDraggedView is a AWTPeerControl.
|
|
||||||
jobject lastPeer =
|
|
||||||
[(id <AWTPeerControl>)sLastMouseDraggedView peer];
|
|
||||||
|
|
||||||
// Send mouseExit to sLastMouseDraggedView
|
|
||||||
jobject exitEvent =
|
|
||||||
makeMouseEvent(env, nsEvent, lastPeer,
|
|
||||||
sLastMouseDraggedView,
|
|
||||||
java_awt_event_MouseEvent_MOUSE_EXITED);
|
|
||||||
pushEventForward(exitEvent, env);
|
|
||||||
(*env)->DeleteLocalRef(env, exitEvent);
|
|
||||||
|
|
||||||
// Send mouseEnter to hitView
|
|
||||||
jobject enterEvent =
|
|
||||||
makeMouseEvent(env, nsEvent, peer, hitView,
|
|
||||||
java_awt_event_MouseEvent_MOUSE_ENTERED);
|
|
||||||
pushEventForward(enterEvent, env);
|
|
||||||
|
|
||||||
(*env)->DeleteLocalRef(env, enterEvent);
|
|
||||||
|
|
||||||
// Set sLastMouseDraggedView = hitView
|
|
||||||
sLastMouseDraggedView = hitView;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jlong UTC(NSEvent *event) {
|
jlong UTC(NSEvent *event) {
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
if (gettimeofday(&tv, NULL) == 0) {
|
if (gettimeofday(&tv, NULL) == 0) {
|
||||||
@ -1069,3 +674,23 @@ JNF_COCOA_ENTER(env);
|
|||||||
|
|
||||||
JNF_COCOA_EXIT(env);
|
JNF_COCOA_EXIT(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: sun_lwawt_macosx_event_NSEvent
|
||||||
|
* Method: nsToJavaChar
|
||||||
|
* Signature: (CI)C
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_sun_lwawt_macosx_event_NSEvent_nsToJavaChar
|
||||||
|
(JNIEnv *env, jclass cls, char nsChar, jint modifierFlags)
|
||||||
|
{
|
||||||
|
jchar javaChar = 0;
|
||||||
|
|
||||||
|
JNF_COCOA_ENTER(env);
|
||||||
|
|
||||||
|
javaChar = NsCharToJavaChar(nsChar, modifierFlags);
|
||||||
|
|
||||||
|
JNF_COCOA_EXIT(env);
|
||||||
|
|
||||||
|
return javaChar;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user