diff --git a/source/Irrlicht/CGUIEditBox.cpp b/source/Irrlicht/CGUIEditBox.cpp
index 395fb69..323c9a2 100644
--- a/source/Irrlicht/CGUIEditBox.cpp
+++ b/source/Irrlicht/CGUIEditBox.cpp
@@ -287,9 +287,11 @@ bool CGUIEditBox::processKey(const SEvent& event)
 				const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd;
 				const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;
 
-				core::stringc s;
-				s = Text.subString(realmbgn, realmend - realmbgn).c_str();
-				Operator->copyToClipboard(s.c_str());
+				const int max_char_size = sizeof(wchar_t) * 3 / 2;
+				int max_size = (realmend - realmbgn)*max_char_size + 1;
+				c8 *s = new char[max_size];
+				wcstombs(s, Text.subString(realmbgn, realmend-realmbgn).c_str(), max_size);
+				Operator->copyToClipboard(s);
 			}
 			break;
 		case KEY_KEY_X:
@@ -300,9 +302,11 @@ bool CGUIEditBox::processKey(const SEvent& event)
 				const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;
 
 				// copy
-				core::stringc sc;
-				sc = Text.subString(realmbgn, realmend - realmbgn).c_str();
-				Operator->copyToClipboard(sc.c_str());
+				const int max_char_size = sizeof(wchar_t) * 3 / 2;
+				int max_size = (realmend - realmbgn)*max_char_size + 1;
+				c8 *s = new char[max_size];
+				wcstombs(s, Text.subString(realmbgn, realmend-realmbgn).c_str(), max_size);
+				Operator->copyToClipboard(s);
 
 				if (isEnabled())
 				{
diff --git a/source/Irrlicht/MacOSX/AppDelegate.h b/source/Irrlicht/MacOSX/AppDelegate.h
index ccb116d..29705f2 100644
--- a/source/Irrlicht/MacOSX/AppDelegate.h
+++ b/source/Irrlicht/MacOSX/AppDelegate.h
@@ -10,7 +10,7 @@
 #import <Cocoa/Cocoa.h>
 #import "CIrrDeviceMacOSX.h"
 
-@interface AppDelegate : NSObject
+@interface AppDelegate : NSTextView <NSApplicationDelegate>
 {
 	BOOL			_quit;
 	irr::CIrrDeviceMacOSX	*_device;
diff --git a/source/Irrlicht/MacOSX/AppDelegate.mm b/source/Irrlicht/MacOSX/AppDelegate.mm
index 14a7f86..0ab0c43 100644
--- a/source/Irrlicht/MacOSX/AppDelegate.mm
+++ b/source/Irrlicht/MacOSX/AppDelegate.mm
@@ -74,6 +74,30 @@
 	return (_quit);
 }
 
+
+- (void)keyDown:(NSEvent *)event
+{
+	[self interpretKeyEvents:@[event]];
+}
+
+- (void)insertText:(id)string
+{
+	[self setString: @""];
+	if ([string isKindOfClass:[NSAttributedString class]])
+	{
+		_device->handleInputEvent([[string string] UTF8String]);
+	}
+	else
+	{
+		_device->handleInputEvent([string UTF8String]);
+	}
+}
+
+- (void)doCommandBySelector:(SEL)selector
+{
+	_device->processKeyEvent();
+}
+
 @end
 
 #endif // _IRR_COMPILE_WITH_OSX_DEVICE_
diff --git a/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.h b/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.h
index f629588..d2fefae 100644
--- a/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.h
+++ b/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.h
@@ -95,6 +95,8 @@ namespace irr
 		void setMouseLocation(int x, int y);
 		void setResize(int width, int height);
 		void setCursorVisible(bool visible);
+		void handleInputEvent(const char *str);
+		void processKeyEvent();
 
 	private:
 
diff --git a/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm b/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm
index ad493fc..8692d0c 100644
--- a/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm
+++ b/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm
@@ -496,7 +496,7 @@ CIrrDeviceMacOSX::CIrrDeviceMacOSX(const SIrrlichtCreationParameters& param)
 		{
 			[[NSAutoreleasePool alloc] init];
 			[NSApplication sharedApplication];
-			[NSApp setDelegate:(id<NSFileManagerDelegate>)[[[AppDelegate alloc] initWithDevice:this] autorelease]];
+			[NSApp setDelegate:[[[[AppDelegate alloc] initWithDevice:this] initWithFrame:NSZeroRect] autorelease]];
 			[NSBundle loadNibNamed:@"MainMenu" owner:[NSApp delegate]];
 			[NSApp finishLaunching];
 		}
@@ -592,6 +592,38 @@ void CIrrDeviceMacOSX::closeDevice()
 	CGLContext = NULL;
 }
 
+void CIrrDeviceMacOSX::processKeyEvent()
+{
+	irr::SEvent ievent;
+	NSEvent *event = [[NSApplication sharedApplication] currentEvent];
+	postKeyEvent(event, ievent, true);
+}
+
+void CIrrDeviceMacOSX::handleInputEvent(const char *cStr)
+{
+	SEvent ievent;
+
+	// TODO: we should have such a function in core::string
+	size_t lenOld = strlen(cStr);
+	wchar_t *ws = new wchar_t[lenOld + 1];
+	size_t len = mbstowcs(ws,cStr,lenOld);
+	ws[len] = 0;
+	irr::core::stringw widep(ws);
+	delete[] ws;
+
+	ievent.EventType = irr::EET_KEY_INPUT_EVENT;
+	ievent.KeyInput.Key = (irr::EKEY_CODE)0;
+	ievent.KeyInput.PressedDown = true;
+	ievent.KeyInput.Shift = false;
+	ievent.KeyInput.Control = false;
+
+	for (int i = 0; i < widep.size(); ++i)
+	{
+		ievent.KeyInput.Char = widep[i];
+		postEventFromUser(ievent);
+	}
+}
+
 bool CIrrDeviceMacOSX::createWindow()
 {
 	CGDisplayErr error;
@@ -881,6 +913,8 @@ bool CIrrDeviceMacOSX::createWindow()
 			newSwapInterval = (CreationParams.Vsync) ? 1 : 0;
 			CGLSetParameter(CGLContext,kCGLCPSwapInterval,&newSwapInterval);
 		}
+
+		[[Window contentView] addSubview:(AppDelegate*)[NSApp delegate]];
 	}
 
 	return (result);
@@ -971,6 +1005,33 @@ bool CIrrDeviceMacOSX::run()
 	os::Timer::tick();
 	storeMouseLocation();
 
+	auto focusElement = getGUIEnvironment()->getFocus();
+	bool editing = focusElement && focusElement->getType() == irr::gui::EGUIET_EDIT_BOX;
+
+	if (!editing)
+	{
+		[Window makeFirstResponder:nil];
+	}
+	else
+	{
+		auto textView = (NSTextView*)[NSApp delegate];
+		auto crect = focusElement->getAbsolutePosition();
+
+		// ensure font height enough to fill the rect, otherwize ime window will overlaps the edit box
+		[textView setFont:[NSFont userFontOfSize:crect.getHeight()]];
+
+		// change origin from top left to bottom right
+		NSRect rect = {
+			crect.UpperLeftCorner.X,
+			[[textView superview] frame].size.height - crect.LowerRightCorner.Y,
+			crect.getWidth(), crect.getHeight(),
+		};
+		[textView setFrame:rect];
+
+		// start to receive input events
+		[Window makeFirstResponder:textView];
+	}
+
 	event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES];
 	if (event != nil)
 	{
@@ -979,6 +1040,13 @@ bool CIrrDeviceMacOSX::run()
 		switch([(NSEvent *)event type])
 		{
 			case NSKeyDown:
+				if (editing)
+				{
+					// delegate to text edit control to handle text input
+					[NSApp sendEvent:event];
+					break;
+				}
+
 				postKeyEvent(event,ievent,true);
 				break;
 
@@ -1199,22 +1267,22 @@ void CIrrDeviceMacOSX::postKeyEvent(void *event,irr::SEvent &ievent,bool pressed
 			}
 			else
 			{
-				cStr = (unsigned char *)[str cStringUsingEncoding:NSWindowsCP1252StringEncoding];
+				cStr = (unsigned char *)[str UTF8String];
 				if (cStr != NULL && strlen((char*)cStr) > 0)
 				{
 					mchar = cStr[0];
 					mkey = toupper(mchar);
-					if ([(NSEvent *)event modifierFlags] & NSCommandKeyMask)
-					{
-						if (mkey == 'C' || mkey == 'V' || mkey == 'X')
-						{
-							mchar = 0;
-							skipCommand = true;
-						}
-					}
 				}
 			}
 		}
+		if ([(NSEvent *)event modifierFlags] & NSCommandKeyMask)
+		{
+			if (mkey == 'C' || mkey == 'V' || mkey == 'X')
+			{
+				mchar = 0;
+				skipCommand = true;
+			}
+		}
 
 		ievent.EventType = irr::EET_KEY_INPUT_EVENT;
 		ievent.KeyInput.Key = (irr::EKEY_CODE)mkey;
diff --git a/source/Irrlicht/MacOSX/OSXClipboard.mm b/source/Irrlicht/MacOSX/OSXClipboard.mm
index d549911..1925e80 100644
--- a/source/Irrlicht/MacOSX/OSXClipboard.mm
+++ b/source/Irrlicht/MacOSX/OSXClipboard.mm
@@ -13,7 +13,7 @@ void OSXCopyToClipboard(const char *text)
 
 	if ((text != NULL) && (strlen(text) > 0))
 	{
-		str = [NSString stringWithCString:text encoding:NSWindowsCP1252StringEncoding];
+		str = [NSString stringWithUTF8String:text];
 		board = [NSPasteboard generalPasteboard];
 		[board declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:NSApp];
 		[board setString:str forType:NSStringPboardType];
@@ -30,7 +30,7 @@ char* OSXCopyFromClipboard()
 	board = [NSPasteboard generalPasteboard];
 	str = [board stringForType:NSStringPboardType];
 	if (str != nil)
-		result = (char*)[str cStringUsingEncoding:NSWindowsCP1252StringEncoding];
+		result = (char*)[str UTF8String];
 	return (result);
 }
 
