diff -Naur cotvnc/Source/EventFilter.h cotvncmod/Source/EventFilter.h
--- cotvnc/Source/EventFilter.h	2005-07-12 22:54:53.000000000 +0200
+++ cotvncmod/Source/EventFilter.h	2008-01-05 15:22:46.000000000 +0100
@@ -153,6 +153,9 @@
 - (void)keyUp: (NSEvent *)theEvent;
 - (void)flagsChanged:(NSEvent *)theEvent;
 
+// Misc?
+- (void)setModifierFlags:(unsigned int)modifierFlags timestamp: (NSTimeInterval)timestamp;
+
 // Synthesized Events
 - (void)clearAllEmulationStates;
 - (void)queueMouseDownEventFromEvent: (NSEvent *)theEvent buttonNumber: (unsigned int)button;
diff -Naur cotvnc/Source/EventFilter.m cotvncmod/Source/EventFilter.m
--- cotvnc/Source/EventFilter.m	2006-01-18 20:20:38.000000000 +0100
+++ cotvncmod/Source/EventFilter.m	2008-01-05 16:31:03.000000000 +0100
@@ -12,7 +12,7 @@
 #import "QueuedEvent.h"
 #import "RFBConnection.h"
 #import "RFBView.h"
-
+#include <unistd.h>
 
 static inline unsigned int
 ButtonNumberToArrayIndex( unsigned int buttonNumber )
@@ -303,12 +303,11 @@
 	}
 }
 
-- (void)flagsChanged:(NSEvent *)theEvent
+- (void)setModifierFlags:(unsigned int)modifierFlags timestamp: (NSTimeInterval)timestamp;
 {
-	unsigned int newState = [theEvent modifierFlags];
+	unsigned int newState = modifierFlags;
     newState = ~(~newState | 0xFFFF);
 	unsigned int changedState = newState ^ _queuedModifiers;
-	NSTimeInterval timestamp = [theEvent timestamp];
 	_queuedModifiers = newState;
 	
 	if ( NSShiftKeyMask & changedState )
@@ -363,6 +362,12 @@
 }
 
 
+- (void)flagsChanged:(NSEvent *)theEvent
+{
+	[self setModifierFlags: [theEvent modifierFlags] timestamp: [theEvent timestamp]];
+}
+
+
 #pragma mark -
 #pragma mark Synthesized Events
 
@@ -453,33 +458,42 @@
 - (void)pasteString: (NSString *)string
 {
 	[self _updateCapsLockStateIfNecessary];
-	int index, strLength = [string length];
+	int index, index2, strLength = [string length];
 	NSTimeInterval now = [[NSDate date] timeIntervalSince1970];
 	
 	[self clearAllEmulationStates];
-	BOOL capsLockWasPressed = (_pressedModifiers & NSAlphaShiftKeyMask) ? YES : NO;
-	
+	unsigned int queuedModifiersSave = _queuedModifiers;
+	[self setModifierFlags: 0 timestamp: now];
+
 	for ( index = 0; index < strLength; ++index )
 	{
 		unichar character = [string characterAtIndex: index];
 		
 		// hack - lets' be polite to the server
-		if ( '\n' == character )
-			character = '\r';
+//		if ( '\n' == character )
+//			character = '\r';
+		unsigned int numRepeat = 1;
+//		if ( '\t' == character )
+//		{
+//			numRepeat = 4;
+//			character = ' ';
+//		}
 		
-		QueuedEvent *event = [QueuedEvent keyDownEventWithCharacter: character
-										 characterIgnoringModifiers: character
-														  timestamp: now];
-		[_pendingEvents addObject: event];
-		event = [QueuedEvent keyUpEventWithCharacter: character
-						  characterIgnoringModifiers: character
-										   timestamp: now];
-		[_pendingEvents addObject: event];
+		for (index2 = 0; index2 < numRepeat; ++index2)
+		{
+			QueuedEvent *event = [QueuedEvent keyDownEventWithCharacter: character
+											 characterIgnoringModifiers: character
+															  timestamp: now];
+			[_pendingEvents addObject: event];
+			event = [QueuedEvent keyUpEventWithCharacter: character
+							  characterIgnoringModifiers: character
+											   timestamp: now];
+			[_pendingEvents addObject: event];
+		}
 	}
 	
-	[self sendAllPendingQueueEntriesNow];
-	if ( capsLockWasPressed )
-		_pressedModifiers |= NSAlphaShiftKeyMask;
+	[self setModifierFlags: queuedModifiersSave timestamp: now];
+	[self sendAnyValidEventsToServerNow];
 }
 
 
@@ -588,16 +602,38 @@
 	// I'll maintain state of the unmodified character because, for example, if you set 
 	// caps lock and then keyrepeat something and unset caps lock while you're doing it, 
 	// the key up character will be for the lowercase letter.
-	if ( NSAlphaShiftKeyMask & _pressedModifiers )
-		character = toupper(characterIgnoringModifiers);
-	else
-		character = characterIgnoringModifiers;
+//	if ( NSAlphaShiftKeyMask & _pressedModifiers )
+//		character = toupper(characterIgnoringModifiers);
+//	else
+//		character = characterIgnoringModifiers;
 	sendKey = character;
 	
+	
 	if ( kQueuedKeyDownEvent == [event type] )
 	{
-		[_pressedKeys addObject: encodedChar];
-		[_connection sendKey: sendKey pressed: YES];
+//		printf("character %c, characterIgnoringModifiers %c\n", character, characterIgnoringModifiers);
+		if (character != characterIgnoringModifiers && (_pressedModifiers & NSAlternateKeyMask | _pressedModifiers & NSControlKeyMask | _pressedModifiers & NSCommandKeyMask))
+		{
+			if	(_pressedModifiers & NSAlternateKeyMask)
+				[_connection sendModifier: NSAlternateKeyMask pressed: NO];
+			if	(_pressedModifiers & NSControlKeyMask)
+				[_connection sendModifier: NSControlKeyMask pressed: NO];
+			if	(_pressedModifiers & NSCommandKeyMask)
+				[_connection sendModifier: NSCommandKeyMask pressed: NO];
+			[_connection sendKey: sendKey pressed: YES];
+			[_connection sendKey: sendKey pressed: NO];
+			if	(_pressedModifiers & NSAlternateKeyMask)
+				[_connection sendModifier: NSAlternateKeyMask pressed: YES];
+			if	(_pressedModifiers & NSControlKeyMask)
+				[_connection sendModifier: NSControlKeyMask pressed: YES];
+			if	(_pressedModifiers & NSCommandKeyMask)
+				[_connection sendModifier: NSCommandKeyMask pressed: YES];
+		}
+		else
+		{
+			[_pressedKeys addObject: encodedChar];
+			[_connection sendKey: sendKey pressed: YES];
+		}
 	}
 	else if ( [_pressedKeys containsObject: encodedChar] )
 	{
@@ -645,9 +681,27 @@
 	NSEnumerator *eventEnumerator = [_pendingEvents objectEnumerator];
 	QueuedEvent *event;
 	
-	while ( event = [eventEnumerator nextObject] )
-		[self _sendEvent: event]; // this sets stuff like _pressedKeyes, _pressedButtons, etc.
-	[self discardAllPendingQueueEntries];
+	size_t nObjects = [_pendingEvents count];
+
+	if (nObjects > 2)
+	{
+		// Ratelimit so keypresses can be sorted by time
+		unsigned int SendRate = 500; // Max key presses per second. Some timer somewhere probably reorders keypresses at millisecond time resolution.
+		unsigned int SleepTime = 1000000 / SendRate;
+		
+		while ( event = [eventEnumerator nextObject] )
+		{
+			[self _sendEvent: event]; // this sets stuff like _pressedKeyes, _pressedButtons, etc.
+			usleep(SleepTime);
+		}		
+		[self discardAllPendingQueueEntries];
+	}
+	else
+	{
+		while ( event = [eventEnumerator nextObject] )
+			[self _sendEvent: event]; // this sets stuff like _pressedKeyes, _pressedButtons, etc.
+		[self discardAllPendingQueueEntries];
+	}
 }
 
 
diff -Naur cotvnc/Source/RFBConnection.m cotvncmod/Source/RFBConnection.m
--- cotvnc/Source/RFBConnection.m	2005-08-14 20:11:44.000000000 +0200
+++ cotvncmod/Source/RFBConnection.m	2008-01-05 16:08:36.000000000 +0100
@@ -626,7 +626,8 @@
 
 - (void)sendModifier:(unsigned int)m pressed: (BOOL)pressed
 {
-/*	NSString *modifierStr =nil;
+	/*
+	NSString *modifierStr =nil;
 	switch (m)
 	{
 		case NSShiftKeyMask:
@@ -640,8 +641,8 @@
 		case NSAlphaShiftKeyMask:
 			modifierStr = @"NSAlphaShiftKeyMask";	break;
 	}
-	NSLog(@"modifier %@ %s", modifierStr, pressed ? "pressed" : "released"); */
-
+	NSLog(@"modifier %@ %s", modifierStr, pressed ? "pressed" : "released");
+*/
     rfbKeyEventMsg msg;
 	
     memset(&msg, 0, sizeof(msg));
@@ -683,9 +684,11 @@
 		kc = c;
     }
 
-/*	unichar _kc = (unichar)kc;
+	/*
+	unichar _kc = (unichar)kc;
 	NSString *keyStr = [NSString stringWithCharacters: &_kc length: 1];
-	NSLog(@"key '%@' %s", keyStr, pressed ? "pressed" : "released"); */
+	NSLog(@"c %d key '%@' %s", c, keyStr, pressed ? "pressed" : "released"); 
+	 */	
 
 	msg.key = htonl(kc);
     [self writeBytes:(unsigned char*)&msg length:sizeof(msg)];
