diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 81e90accb701ee1d67d94ae738b260a2231fc9b9..406bc9cf478853e41e548f36b468884540e0ea55 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -30,13 +30,6 @@
 
 
 
-//---------------------------
-// Coppied from indra_constants.h
-//#include "indra_constats.h"
-const uint32_t MASK_CONTROL =		0x0001;		// Mapped to cmd on Macs
-const uint32_t MASK_ALT =			0x0002;
-const uint32_t MASK_SHIFT =			0x0004;
-//const uint32_t MASK_MAC_CONTROL =	0x0008;		// Un-mapped Ctrl key on Macs, not used on Windows
 
 //---------------------------
 
@@ -72,29 +65,16 @@ const uint32_t MASK_SHIFT =			0x0004;
 
 void extractKeyDataFromEvent (NSEvent *theEvent, NativeKeyEventData * eventData)
 {
-    if ([theEvent characters].length)
-    {
-        eventData->mCharacter = (wchar_t)[[theEvent characters] characterAtIndex:0];
-    }
-    else
-    {
-        eventData->mCharacter = [theEvent keyCode];
-    }
     eventData->mKeyEvent = NativeKeyEventData::KEYUNKNOWN;
-    eventData->mKeyCode = [theEvent keyCode];
+    eventData->mEventType = [theEvent type];
+    eventData->mEventModifiers = [theEvent modifierFlags];
+    eventData->mEventKeyCode = [theEvent keyCode];
+    NSString *strEventChars = [theEvent characters];
+    eventData->mEventChars = (strEventChars.length) ? [strEventChars characterAtIndex:0] : 0;
+    NSString *strEventUChars = [theEvent charactersIgnoringModifiers];
+    eventData->mEventUnmodChars = (strEventUChars.length) ? [strEventUChars characterAtIndex:0] : 0;
+    eventData->mEventRepeat = [theEvent isARepeat];
 
-    unsigned int modifiers = [theEvent modifierFlags];
-    
-    if (modifiers & (NSAlphaShiftKeyMask | NSShiftKeyMask))
-        modifiers |= MASK_SHIFT;
-    if (modifiers & NSAlternateKeyMask)
-        modifiers |= MASK_ALT;
-    if (modifiers & NSControlKeyMask)
-        modifiers |= MASK_CONTROL;
-    
-    eventData->mKeyModifiers = modifiers;
-    eventData->mScanCode = [theEvent keyCode ];
-    eventData->mKeyboardType = 0;
 }
 
 
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 2455d6aeb9dbcb3c7515c51f26573856a2f9052a..dc184b91fbd5129b7b3c945a6ec40ce91668c0db 100755
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -56,11 +56,12 @@ struct NativeKeyEventData {
     };
     
     EventType   mKeyEvent;
-    uint32_t    mKeyCode;
-    uint32_t    mScanCode;
-    uint32_t    mKeyModifiers;
-    uint32_t    mKeyboardType;
-    wchar_t     mCharacter;
+    uint32_t    mEventType;
+    uint32_t    mEventModifiers;
+    uint32_t    mEventKeyCode;
+    uint32_t    mEventChars;
+    uint32_t    mEventUnmodChars;
+    bool        mEventRepeat;
 };
 
 typedef const NativeKeyEventData * NSKeyEventRef;
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 7bc5d263e406611fb2a966199e8d0824e13413f2..952c6751dbd595b4ae01ce4a87dc747577d22334 100755
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -1726,39 +1726,12 @@ LLSD LLWindowMacOSX::getNativeKeyData()
 #if 1
 	if(mRawKeyEvent)
 	{
-
-        result["char_code"] = (S32)(mRawKeyEvent)->mCharacter;
-        result["scan_code"] = (S32)(mRawKeyEvent)->mScanCode;
-		result["key_code"] = (S32)(mRawKeyEvent->mKeyCode);
-		result["modifiers"] = (S32)(mRawKeyEvent->mKeyModifiers);
-		result["keyboard_type"] = (S32)(mRawKeyEvent->mKeyboardType);
-
-        
-#if 0
-		// This causes trouble for control characters -- apparently character codes less than 32 (escape, control-A, etc)
-		// cause llsd serialization to create XML that the llsd deserializer won't parse!
-		std::string unicode;
-		S32 err = noErr;
-		EventParamType actualType = typeUTF8Text;
-		UInt32 actualSize = 0;
-		char *buffer = NULL;
-
-		err = GetEventParameter (mRawKeyEvent, kEventParamKeyUnicodes, typeUTF8Text, &actualType, 0, &actualSize, NULL);
-		if(err == noErr)
-		{
-			// allocate a buffer and get the actual data.
-			buffer = new char[actualSize];
-			err = GetEventParameter (mRawKeyEvent, kEventParamKeyUnicodes, typeUTF8Text, &actualType, actualSize, &actualSize, buffer);
-			if(err == noErr)
-			{
-				unicode.assign(buffer, actualSize);
-			}
-			delete[] buffer;
-		}
-
-		result["unicode"] = unicode;
-#endif
-
+        result["event_type"] = LLSD::Integer(mRawKeyEvent->mEventType);
+        result["event_modifiers"] = LLSD::Integer(mRawKeyEvent->mEventModifiers);
+        result["event_keycode"] = LLSD::Integer(mRawKeyEvent->mEventKeyCode);
+        result["event_chars"] = (mRawKeyEvent->mEventChars) ? LLSD(LLSD::Integer(mRawKeyEvent->mEventChars)) : LLSD();
+        result["event_umodchars"] = (mRawKeyEvent->mEventUnmodChars) ? LLSD(LLSD::Integer(mRawKeyEvent->mEventUnmodChars)) : LLSD();
+        result["event_isrepeat"] = LLSD::Boolean(mRawKeyEvent->mEventRepeat);
 	}
 #endif
 
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 86157bf852d3337010d2a9e46f8cf2376ce53c35..9e7c390eb2260a3c3e307fbcddb8cfc0be4b0062 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -726,46 +726,18 @@ void MediaPluginCEF::deserializeKeyboardData(LLSD native_key_data, uint32_t& nat
 void MediaPluginCEF::keyEvent(LLCEFLib::EKeyEvent key_event, int key, LLCEFLib::EKeyboardModifier modifiers_x, LLSD native_key_data = LLSD::emptyMap())
 {
 #if LL_DARWIN
-	std::string utf8_text;
 
-    uint32_t native_char_code = native_key_data["char_code"].asInteger();
-    uint32_t native_scan_code = native_key_data["scan_code"].asInteger();
-    uint32_t native_virtual_key = native_key_data["key_code"].asInteger();
-    uint32_t native_modifiers = native_key_data["modifiers"].asInteger();
-    
-	if (key < 128)
-	{
-		utf8_text = (char)native_virtual_key;
-	}
-    
-    unsigned int modifers = LLCEFLib::KM_MODIFIER_NONE;
-
-    if (native_modifiers & (MASK_CONTROL | MASK_MAC_CONTROL))
-        modifers |= LLCEFLib::KM_MODIFIER_CONTROL;
-    if (native_modifiers & MASK_SHIFT)
-        modifers |= LLCEFLib::KM_MODIFIER_SHIFT;
-    if (native_modifiers & MASK_ALT)
-        modifers |= LLCEFLib::KM_MODIFIER_ALT;
-
-    //modifers |= LLCEFLib::KM_MODIFIER_META;
-    
-	switch ((KEY)key)
-    
-	{
-		case KEY_BACKSPACE:		utf8_text = (char)8;		break;
-		case KEY_TAB:			utf8_text = (char)9;		break;
-		case KEY_RETURN:		utf8_text = (char)13;		break;
-		case KEY_PAD_RETURN:	utf8_text = (char)13;		break;
-		case KEY_ESCAPE:		utf8_text = (char)27;		break;
-
-	default:
-		break;
-	}
+    uint32_t eventType = native_key_data["event_type"].asInteger();
+    uint32_t eventModifiers = native_key_data["event_modifiers"].asInteger();
+    uint32_t eventKeycode = native_key_data["event_keycode"].asInteger();
+    char eventChars = static_cast<char>(native_key_data["event_chars"].isUndefined() ? 0 : native_key_data["event_chars"].asInteger());
+    char eventUChars = static_cast<char>(native_key_data["event_umodchars"].isUndefined() ? 0 : native_key_data["event_umodchars"].asInteger());
+    bool eventIsRepeat = native_key_data["event_isrepeat"].asBoolean();
 
-	mLLCEFLib->keyboardEvent(key_event, native_char_code, utf8_text.c_str(),
-            static_cast<LLCEFLib::EKeyboardModifier>(modifers),
-            native_scan_code, native_virtual_key, native_modifiers);
     
+    mLLCEFLib->keyboardEventOSX(eventType, eventModifiers, (eventChars) ? &eventChars : NULL,
+                                (eventUChars) ? &eventUChars : NULL, eventIsRepeat, eventKeycode);
+        
 #elif LL_WINDOWS
 	U32 msg = ll_U32_from_sd(native_key_data["msg"]);
 	U32 wparam = ll_U32_from_sd(native_key_data["w_param"]);