Index: /CKEditor/trunk/CHANGES.html
===================================================================
--- /CKEditor/trunk/CHANGES.html	(revision 4606)
+++ /CKEditor/trunk/CHANGES.html	(revision 4607)
@@ -88,4 +88,5 @@
 		<li><a href="http://dev.fckeditor.net/ticket/4522">#4522</a> : Fixed unable to redo when typing after insert an image with relative url.</li>
 		<li><a href="http://dev.fckeditor.net/ticket/4594">#4594</a> : Fixed context menu goes off-screen when mouse is at right had side of screen.</li>
+		<li><a href="http://dev.fckeditor.net/ticket/4673">#4673</a> : Fixed undo not available straight away if shift key is used to enter first character.</li>
 	</ul>
 	<h3>
Index: /CKEditor/trunk/_source/plugins/undo/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/undo/plugin.js	(revision 4606)
+++ /CKEditor/trunk/_source/plugins/undo/plugin.js	(revision 4607)
@@ -193,4 +193,9 @@
 	}
 
+
+	var editingKeyCodes = { /*Backspace*/ 8:1, /*Delete*/ 46:1 },
+		modifierKeyCodes = { /*Shift*/ 16:1, /*Ctrl*/ 17:1, /*Alt*/ 18:1 },
+		navigationKeyCodes = { 37:1, 38:1, 39:1, 40:1 };  // Arrows: L, T, R, B
+
 	UndoManager.prototype =
 	{
@@ -201,30 +206,24 @@
 		type : function( event )
 		{
-			var keystroke = event && event.data.getKeystroke(),
-
-				// Backspace, Delete
-				modifierCodes = { 8:1, 46:1 },
-				// Keystrokes which will modify the contents.
-				isModifier = keystroke in modifierCodes,
-				wasModifier = this.lastKeystroke in modifierCodes,
-				lastWasSameModifier = isModifier && keystroke == this.lastKeystroke,
-
-				// Arrows: L, T, R, B
-				resetTypingCodes = { 37:1, 38:1, 39:1, 40:1 },
+			var keystroke = event && event.data.getKey(),
+				isModifierKey = keystroke in modifierKeyCodes,
+				isEditingKey = keystroke in editingKeyCodes,
+				wasEditingKey = this.lastKeystroke in editingKeyCodes,
+				sameAsLastEditingKey = isEditingKey && keystroke == this.lastKeystroke,
 				// Keystrokes which navigation through contents.
-				isReset = keystroke in resetTypingCodes,
-				wasReset = this.lastKeystroke in resetTypingCodes,
+				isReset = keystroke in navigationKeyCodes,
+				wasReset = this.lastKeystroke in navigationKeyCodes,
 
 				// Keystrokes which just introduce new contents.
-				isContent = ( !isModifier && !isReset ),
+				isContent = ( !isEditingKey && !isReset ),
 
 				// Create undo snap for every different modifier key.
-				modifierSnapshot = ( isModifier && !lastWasSameModifier ),
+				modifierSnapshot = ( isEditingKey && !sameAsLastEditingKey ),
 				// Create undo snap on the following cases:
-				// 1. Just start to type.
+				// 1. Just start to type .
 				// 2. Typing some content after a modifier.
 				// 3. Typing some content after make a visible selection.
-				startedTyping = !this.typing
-					|| ( isContent && ( wasModifier || wasReset ) );
+				startedTyping = !( isModifierKey || this.typing )
+					|| ( isContent && ( wasEditingKey || wasReset ) );
 
 			if ( startedTyping || modifierSnapshot )
@@ -264,6 +263,10 @@
 
 			this.lastKeystroke = keystroke;
+
+			// Ignore modifier keys. (#4673)
+			if( isModifierKey )
+				return;
 			// Create undo snap after typed too much (over 25 times).
-			if ( isModifier )
+			if ( isEditingKey )
 			{
 				this.typesCount = 0;
