diff --git a/widget/src/cocoa/nsChildView.h b/widget/src/cocoa/nsChildView.h index 9402df726439..924098f80863 100644 --- a/widget/src/cocoa/nsChildView.h +++ b/widget/src/cocoa/nsChildView.h @@ -92,7 +92,7 @@ class nsIEventSink; // create a gecko key event out of a cocoa event - (void) convert:(NSEvent*)aKeyEvent message:(PRUint32)aMessage - isChar:(PRBool*)outIsChar convertChar:(PRBool)aConvertChar + isChar:(PRBool*)outIsChar toGeckoEvent:(nsKeyEvent*)outGeckoEvent; - (NSWindow*) getNativeWindow; diff --git a/widget/src/cocoa/nsChildView.mm b/widget/src/cocoa/nsChildView.mm index cd570d111386..cae2784a015a 100644 --- a/widget/src/cocoa/nsChildView.mm +++ b/widget/src/cocoa/nsChildView.mm @@ -1911,24 +1911,6 @@ const PRInt32 kNumLines = 4; mGeckoChild->DispatchWindowEvent(geckoEvent); } - -- (void)keyDown:(NSEvent*)theEvent; -{ - //nsKeyEvent geckoEvent; - printf("got keydown in view\n"); - - -} - - -- (void)keyUp:(NSEvent*)theEvent; -{ - printf("got keyup in view\n"); - - -} - - // // -convert:message:toGeckoEvent: // @@ -1940,22 +1922,24 @@ const PRInt32 kNumLines = 4; outGeckoEvent->widget = [self widget]; outGeckoEvent->nativeMsg = inEvent; outGeckoEvent->time = PR_IntervalNow(); - NSPoint mouseLoc = [inEvent locationInWindow]; - outGeckoEvent->refPoint.x = NS_STATIC_CAST(nscoord, mouseLoc.x); - outGeckoEvent->refPoint.y = NS_STATIC_CAST(nscoord, mouseLoc.y); - - // setup modifier keys + + if (outGeckoEvent->eventStructType != NS_KEY_EVENT) { + NSPoint mouseLoc = [inEvent locationInWindow]; + outGeckoEvent->refPoint.x = NS_STATIC_CAST(nscoord, mouseLoc.x); + outGeckoEvent->refPoint.y = NS_STATIC_CAST(nscoord, mouseLoc.y); + + // convert point to view coordinate system + NSPoint localPoint = [self convertPoint:mouseLoc fromView:nil]; + outGeckoEvent->point.x = NS_STATIC_CAST(nscoord, localPoint.x); + outGeckoEvent->point.y = NS_STATIC_CAST(nscoord, localPoint.y); + } + + // set up modifier keys unsigned int modifiers = [inEvent modifierFlags]; outGeckoEvent->isShift = ((modifiers & NSShiftKeyMask) != 0); outGeckoEvent->isControl = ((modifiers & NSControlKeyMask) != 0); outGeckoEvent->isAlt = ((modifiers & NSAlternateKeyMask) != 0); outGeckoEvent->isMeta = ((modifiers & NSCommandKeyMask) != 0); - - // convert point to view coordinate system - NSPoint localPoint = [self convertPoint:mouseLoc fromView:nil]; - outGeckoEvent->point.x = NS_STATIC_CAST(nscoord, localPoint.x); - outGeckoEvent->point.y = NS_STATIC_CAST(nscoord, localPoint.y); - } // convert:toGeckoEvent: @@ -1969,104 +1953,356 @@ const PRInt32 kNumLines = 4; return NS_STATIC_CAST(nsIWidget*, mGeckoChild); } +- (void)keyDown:(NSEvent*)theEvent; +{ + PRBool isChar = PR_FALSE; + BOOL isARepeat = [theEvent isARepeat]; + if (!isARepeat) { + // Fire a key down. + nsKeyEvent geckoEvent; + geckoEvent.point.x = geckoEvent.point.y = 0; + [self convert: theEvent message: NS_KEY_DOWN + isChar: &isChar + toGeckoEvent: &geckoEvent]; + geckoEvent.isChar = isChar; + mGeckoChild->DispatchWindowEvent(geckoEvent); + } + + // Check to see if we are still the first responder. + // The key down event may have shifted the focus, in which + // case we should not fire the key press. + NSResponder* resp = [[self window] firstResponder]; + if (resp != (NSResponder*)self) { + printf("No soup for you!\n"); + return; + } + + // Fire a key press. + nsKeyEvent geckoEvent; + geckoEvent.point.x = geckoEvent.point.y = 0; + isChar = PR_FALSE; + [self convert: theEvent message: NS_KEY_PRESS + isChar: &isChar + toGeckoEvent: &geckoEvent]; + geckoEvent.isChar = isChar; + if (isChar) { + // Get the chars of the event and loop over our list + // of chars, setting each one. + NSString* text = [theEvent characters]; + PRUint32 length = [text length]; + for (PRUint32 i = 0; i < length; i++) { + unichar c = [text characterAtIndex: i]; + geckoEvent.charCode = c; + mGeckoChild->DispatchWindowEvent(geckoEvent); + } + } + else { + // XXXdwh. Check to see if we're a context menu key. If so, + // fire a context menu event instead. + mGeckoChild->DispatchWindowEvent(geckoEvent); + } +} +- (void)keyUp:(NSEvent*)theEvent; +{ + // Fire a key up. + nsKeyEvent geckoEvent; + geckoEvent.point.x = geckoEvent.point.y = 0; + PRBool isChar; + [self convert: theEvent message: NS_KEY_UP + isChar: &isChar + toGeckoEvent: &geckoEvent]; + mGeckoChild->DispatchWindowEvent(geckoEvent); +} + +//------------------------------------------------------------------------- +// +// ConvertMacToRaptorKeyCode +// +//------------------------------------------------------------------------- + + +// Key code constants +enum +{ + kEscapeKeyCode = 0x35, + kCommandKeyCode = 0x37, + kShiftKeyCode = 0x38, + kCapsLockKeyCode = 0x39, + kControlKeyCode = 0x3B, + kOptionkeyCode = 0x3A, // left and right option keys + kClearKeyCode = 0x47, + + // function keys + kF1KeyCode = 0x7A, + kF2KeyCode = 0x78, + kF3KeyCode = 0x63, + kF4KeyCode = 0x76, + kF5KeyCode = 0x60, + kF6KeyCode = 0x61, + kF7KeyCode = 0x62, + kF8KeyCode = 0x64, + kF9KeyCode = 0x65, + kF10KeyCode = 0x6D, + kF11KeyCode = 0x67, + kF12KeyCode = 0x6F, + kF13KeyCode = 0x69, + kF14KeyCode = 0x6B, + kF15KeyCode = 0x71, + + kPrintScreenKeyCode = kF13KeyCode, + kScrollLockKeyCode = kF14KeyCode, + kPauseKeyCode = kF15KeyCode, + + // keypad + kKeypad0KeyCode = 0x52, + kKeypad1KeyCode = 0x53, + kKeypad2KeyCode = 0x54, + kKeypad3KeyCode = 0x55, + kKeypad4KeyCode = 0x56, + kKeypad5KeyCode = 0x57, + kKeypad6KeyCode = 0x58, + kKeypad7KeyCode = 0x59, + kKeypad8KeyCode = 0x5B, + kKeypad9KeyCode = 0x5C, + + kKeypadMultiplyKeyCode = 0x43, + kKeypadAddKeyCode = 0x45, + kKeypadSubtractKeyCode = 0x4E, + kKeypadDecimalKeyCode = 0x41, + kKeypadDivideKeyCode = 0x4B, + kKeypadEqualsKeyCode = 0x51, // no correpsonding raptor key code + kEnterKeyCode = 0x4C, + kReturnKeyCode = 0x24, + kPowerbookEnterKeyCode = 0x34, // Enter on Powerbook's keyboard is different + + kInsertKeyCode = 0x72, // also help key + kDeleteKeyCode = 0x75, // also forward delete key + kTabKeyCode = 0x30, + kBackspaceKeyCode = 0x33, + kHomeKeyCode = 0x73, + kEndKeyCode = 0x77, + kPageUpKeyCode = 0x74, + kPageDownKeyCode = 0x79, + kLeftArrowKeyCode = 0x7B, + kRightArrowKeyCode = 0x7C, + kUpArrowKeyCode = 0x7E, + kDownArrowKeyCode = 0x7D + +}; + +static PRUint32 ConvertMacToRaptorKeyCode(UInt32 keyCode, nsKeyEvent* aKeyEvent, NSString* characters) +{ + PRUint32 raptorKeyCode = 0; + PRUint8 charCode = [characters characterAtIndex: 0]; + + switch (keyCode) + { +// case ?? : raptorKeyCode = NS_VK_CANCEL; break; // don't know what this key means. Nor does joki + +// modifiers. We don't get separate events for these + case kEscapeKeyCode: raptorKeyCode = NS_VK_ESCAPE; break; + case kShiftKeyCode: raptorKeyCode = NS_VK_SHIFT; break; +// case kCommandKeyCode: raptorKeyCode = NS_VK_META; break; + case kCapsLockKeyCode: raptorKeyCode = NS_VK_CAPS_LOCK; break; + case kControlKeyCode: raptorKeyCode = NS_VK_CONTROL; break; + case kOptionkeyCode: raptorKeyCode = NS_VK_ALT; break; + case kClearKeyCode: raptorKeyCode = NS_VK_CLEAR; break; + +// function keys + case kF1KeyCode: raptorKeyCode = NS_VK_F1; break; + case kF2KeyCode: raptorKeyCode = NS_VK_F2; break; + case kF3KeyCode: raptorKeyCode = NS_VK_F3; break; + case kF4KeyCode: raptorKeyCode = NS_VK_F4; break; + case kF5KeyCode: raptorKeyCode = NS_VK_F5; break; + case kF6KeyCode: raptorKeyCode = NS_VK_F6; break; + case kF7KeyCode: raptorKeyCode = NS_VK_F7; break; + case kF8KeyCode: raptorKeyCode = NS_VK_F8; break; + case kF9KeyCode: raptorKeyCode = NS_VK_F9; break; + case kF10KeyCode: raptorKeyCode = NS_VK_F10; break; + case kF11KeyCode: raptorKeyCode = NS_VK_F11; break; + case kF12KeyCode: raptorKeyCode = NS_VK_F12; break; +// case kF13KeyCode: raptorKeyCode = NS_VK_F13; break; // clash with the 3 below +// case kF14KeyCode: raptorKeyCode = NS_VK_F14; break; +// case kF15KeyCode: raptorKeyCode = NS_VK_F15; break; + case kPauseKeyCode: raptorKeyCode = NS_VK_PAUSE; break; + case kScrollLockKeyCode: raptorKeyCode = NS_VK_SCROLL_LOCK; break; + case kPrintScreenKeyCode: raptorKeyCode = NS_VK_PRINTSCREEN; break; + +// keypad + case kKeypad0KeyCode: raptorKeyCode = NS_VK_NUMPAD0; break; + case kKeypad1KeyCode: raptorKeyCode = NS_VK_NUMPAD1; break; + case kKeypad2KeyCode: raptorKeyCode = NS_VK_NUMPAD2; break; + case kKeypad3KeyCode: raptorKeyCode = NS_VK_NUMPAD3; break; + case kKeypad4KeyCode: raptorKeyCode = NS_VK_NUMPAD4; break; + case kKeypad5KeyCode: raptorKeyCode = NS_VK_NUMPAD5; break; + case kKeypad6KeyCode: raptorKeyCode = NS_VK_NUMPAD6; break; + case kKeypad7KeyCode: raptorKeyCode = NS_VK_NUMPAD7; break; + case kKeypad8KeyCode: raptorKeyCode = NS_VK_NUMPAD8; break; + case kKeypad9KeyCode: raptorKeyCode = NS_VK_NUMPAD9; break; + + case kKeypadMultiplyKeyCode: raptorKeyCode = NS_VK_MULTIPLY; break; + case kKeypadAddKeyCode: raptorKeyCode = NS_VK_ADD; break; + case kKeypadSubtractKeyCode: raptorKeyCode = NS_VK_SUBTRACT; break; + case kKeypadDecimalKeyCode: raptorKeyCode = NS_VK_DECIMAL; break; + case kKeypadDivideKeyCode: raptorKeyCode = NS_VK_DIVIDE; break; +// case ?? : raptorKeyCode = NS_VK_SEPARATOR; break; + + +// these may clash with forward delete and help + case kInsertKeyCode: raptorKeyCode = NS_VK_INSERT; break; + case kDeleteKeyCode: raptorKeyCode = NS_VK_DELETE; break; + + case kBackspaceKeyCode: raptorKeyCode = NS_VK_BACK; break; + case kTabKeyCode: raptorKeyCode = NS_VK_TAB; break; + case kHomeKeyCode: raptorKeyCode = NS_VK_HOME; break; + case kEndKeyCode: raptorKeyCode = NS_VK_END; break; + case kPageUpKeyCode: raptorKeyCode = NS_VK_PAGE_UP; break; + case kPageDownKeyCode: raptorKeyCode = NS_VK_PAGE_DOWN; break; + case kLeftArrowKeyCode: raptorKeyCode = NS_VK_LEFT; break; + case kRightArrowKeyCode: raptorKeyCode = NS_VK_RIGHT; break; + case kUpArrowKeyCode: raptorKeyCode = NS_VK_UP; break; + case kDownArrowKeyCode: raptorKeyCode = NS_VK_DOWN; break; + + default: + if (aKeyEvent->isControl) + charCode += 64; + + // if we haven't gotten the key code already, look at the char code + switch (charCode) + { + case kReturnCharCode: raptorKeyCode = NS_VK_RETURN; break; + case kEnterCharCode: raptorKeyCode = NS_VK_RETURN; break; // fix me! + case ' ': raptorKeyCode = NS_VK_SPACE; break; + case ';': raptorKeyCode = NS_VK_SEMICOLON; break; + case '=': raptorKeyCode = NS_VK_EQUALS; break; + case ',': raptorKeyCode = NS_VK_COMMA; break; + case '.': raptorKeyCode = NS_VK_PERIOD; break; + case '/': raptorKeyCode = NS_VK_SLASH; break; + case '`': raptorKeyCode = NS_VK_BACK_QUOTE; break; + case '{': + case '[': raptorKeyCode = NS_VK_OPEN_BRACKET; break; + case '\\': raptorKeyCode = NS_VK_BACK_SLASH; break; + case '}': + case ']': raptorKeyCode = NS_VK_CLOSE_BRACKET; break; + case '\'': + case '"': raptorKeyCode = NS_VK_QUOTE; break; + + default: + + if (charCode >= '0' && charCode <= '9') // numerals + { + raptorKeyCode = charCode; + } + else if (charCode >= 'a' && charCode <= 'z') // lowercase + { + raptorKeyCode = toupper(charCode); + } + else if (charCode >= 'A' && charCode <= 'Z') // uppercase + { + raptorKeyCode = charCode; + } + + break; + } + } + + return raptorKeyCode; +} + +static PRBool IsSpecialRaptorKey(UInt32 macKeyCode) +{ + PRBool isSpecial; + + // + // this table is used to determine which keys are special and should not generate a charCode + // + switch (macKeyCode) + { +// modifiers. We don't get separate events for these +// yet + case kEscapeKeyCode: isSpecial = PR_TRUE; break; + case kShiftKeyCode: isSpecial = PR_TRUE; break; + case kCommandKeyCode: isSpecial = PR_TRUE; break; + case kCapsLockKeyCode: isSpecial = PR_TRUE; break; + case kControlKeyCode: isSpecial = PR_TRUE; break; + case kOptionkeyCode: isSpecial = PR_TRUE; break; + case kClearKeyCode: isSpecial = PR_TRUE; break; + +// function keys + case kF1KeyCode: isSpecial = PR_TRUE; break; + case kF2KeyCode: isSpecial = PR_TRUE; break; + case kF3KeyCode: isSpecial = PR_TRUE; break; + case kF4KeyCode: isSpecial = PR_TRUE; break; + case kF5KeyCode: isSpecial = PR_TRUE; break; + case kF6KeyCode: isSpecial = PR_TRUE; break; + case kF7KeyCode: isSpecial = PR_TRUE; break; + case kF8KeyCode: isSpecial = PR_TRUE; break; + case kF9KeyCode: isSpecial = PR_TRUE; break; + case kF10KeyCode: isSpecial = PR_TRUE; break; + case kF11KeyCode: isSpecial = PR_TRUE; break; + case kF12KeyCode: isSpecial = PR_TRUE; break; + case kPauseKeyCode: isSpecial = PR_TRUE; break; + case kScrollLockKeyCode: isSpecial = PR_TRUE; break; + case kPrintScreenKeyCode: isSpecial = PR_TRUE; break; + + case kInsertKeyCode: isSpecial = PR_TRUE; break; + case kDeleteKeyCode: isSpecial = PR_TRUE; break; + case kTabKeyCode: isSpecial = PR_TRUE; break; + case kBackspaceKeyCode: isSpecial = PR_TRUE; break; + + case kHomeKeyCode: isSpecial = PR_TRUE; break; + case kEndKeyCode: isSpecial = PR_TRUE; break; + case kPageUpKeyCode: isSpecial = PR_TRUE; break; + case kPageDownKeyCode: isSpecial = PR_TRUE; break; + case kLeftArrowKeyCode: isSpecial = PR_TRUE; break; + case kRightArrowKeyCode: isSpecial = PR_TRUE; break; + case kUpArrowKeyCode: isSpecial = PR_TRUE; break; + case kDownArrowKeyCode: isSpecial = PR_TRUE; break; + case kReturnKeyCode: isSpecial = PR_TRUE; break; + case kEnterKeyCode: isSpecial = PR_TRUE; break; + case kPowerbookEnterKeyCode: isSpecial = PR_TRUE; break; + + default: isSpecial = PR_FALSE; break; + } + return isSpecial; +} - (void) convert:(NSEvent*)aKeyEvent message:(PRUint32)aMessage - isChar:(PRBool*)outIsChar convertChar:(PRBool)aConvertChar + isChar:(PRBool*)aIsChar toGeckoEvent:(nsKeyEvent*)outGeckoEvent { - outGeckoEvent->eventStructType = NS_KEY_EVENT; + outGeckoEvent->eventStructType = NS_KEY_EVENT; [self convert:aKeyEvent message:aMessage toGeckoEvent:outGeckoEvent]; - -#if 0 - // - // initalize the basic message parts - // - aKeyEvent.message = aMessage; - aKeyEvent.point.x = 0; - aKeyEvent.point.y = 0; - aKeyEvent.time = PR_IntervalNow(); - - // - // initalize the GUI event parts - // - aKeyEvent.widget = aFocusedWidget; - aKeyEvent.nativeMsg = (void*)&aOSEvent; - - // - // nsInputEvent parts - // - aKeyEvent.isShift = ((aOSEvent.modifiers & shiftKey) != 0); - aKeyEvent.isControl = ((aOSEvent.modifiers & controlKey) != 0); - aKeyEvent.isAlt = ((aOSEvent.modifiers & optionKey) != 0); - aKeyEvent.isMeta = ((aOSEvent.modifiers & cmdKey) != 0); -#endif - -#if 0 - // - // nsKeyEvent parts - // - if ( outIsChar ) - *outIsChar = PR_FALSE; - if (aMessage == NS_KEY_PRESS - && !IsSpecialRaptorKey((aOSEvent.message & keyCodeMask) >> 8) ) - { - if (aKeyEvent.isControl) - { - if (outIsChar) - *outIsChar = PR_TRUE; - if (aConvertChar) - { - aKeyEvent.charCode = (aOSEvent.message & charCodeMask); - if (aKeyEvent.charCode <= 26) - { - if (aKeyEvent.isShift) - aKeyEvent.charCode += 'A' - 1; - else - aKeyEvent.charCode += 'a' - 1; - } // if (aKeyEvent.charCode <= 26) - } - aKeyEvent.keyCode = 0; - } // if (aKeyEvent.isControl) - else // else for if (aKeyEvent.isControl) - { - if (!aKeyEvent.isMeta) - { - aKeyEvent.isShift = aKeyEvent.isControl = aKeyEvent.isAlt = aKeyEvent.isMeta = 0; - } // if (!aKeyEvent.isMeta) - - aKeyEvent.keyCode = 0; - if (outIsChar) - *outIsChar = PR_TRUE; - if (aConvertChar) - { - aKeyEvent.charCode = ConvertKeyEventToUnicode(aOSEvent); - if (aKeyEvent.isShift && aKeyEvent.charCode <= 'z' && aKeyEvent.charCode >= 'a') - { - aKeyEvent.charCode -= 32; - } - NS_ASSERTION(0 != aKeyEvent.charCode, "nsMacEventHandler::InitializeKeyEvent: ConvertKeyEventToUnicode returned 0."); - } - } // else for if (aKeyEvent.isControl) - } // if (message == NS_KEY_PRESS && !IsSpecialRaptorKey((aOSEvent.message & keyCodeMask) >> 8) ) - else - { - aKeyEvent.keyCode = ConvertMacToRaptorKeyCode(aOSEvent.message, aOSEvent.modifiers); - aKeyEvent.charCode = 0; - } // else for if (message == NS_KEY_PRESS && !IsSpecialRaptorKey((aOSEvent.message & keyCodeMask) >> 8) ) + + printf("The key code is: %d\n", [aKeyEvent keyCode]); - // - // obscure cursor if appropriate - // - if (aMessage == NS_KEY_PRESS - && !aKeyEvent.isMeta - && aKeyEvent.keyCode != NS_VK_PAGE_UP && aKeyEvent.keyCode != NS_VK_PAGE_DOWN - // also consider: function keys and sole modifier keys - ) - { + // Initialize the out boolean for whether or not we are using + // charCodes to false. + if (aIsChar) + *aIsChar = PR_FALSE; + + // Check to see if the message is a key press that does not involve + // one of our special key codes. + if (aMessage == NS_KEY_PRESS && !IsSpecialRaptorKey([aKeyEvent keyCode])) + { + if (!outGeckoEvent->isControl && !outGeckoEvent->isMeta) + outGeckoEvent->isShift = outGeckoEvent->isControl = outGeckoEvent->isAlt = outGeckoEvent->isMeta = 0; + + // We're not a special key. + outGeckoEvent->keyCode = 0; + if (aIsChar) + *aIsChar = PR_TRUE; + } + else + { + outGeckoEvent->keyCode = ConvertMacToRaptorKeyCode([aKeyEvent keyCode], outGeckoEvent, [aKeyEvent characters]); + outGeckoEvent->charCode = 0; + } + + if (aMessage == NS_KEY_PRESS && !outGeckoEvent->isMeta && outGeckoEvent->keyCode != NS_VK_PAGE_UP && + outGeckoEvent->keyCode != NS_VK_PAGE_DOWN) ::ObscureCursor(); - } // if (message == NS_KEY_PRESS && !aKeyEvent.isMeta && aKeyEvent.keyCode != NS_VK_PAGE_UP && aKeyEvent.keyCode != NS_VK_PAGE_DOWN -#endif } @end