Index: /CKEditor/trunk/_source/plugins/smiley/dialogs/smiley.js
===================================================================
--- /CKEditor/trunk/_source/plugins/smiley/dialogs/smiley.js	(revision 3509)
+++ /CKEditor/trunk/_source/plugins/smiley/dialogs/smiley.js	(revision 3510)
@@ -10,4 +10,138 @@
 		columns = config.smiley_columns,
 		i;
+
+	/**
+	 * Simulate "this" of a dialog for non-dialog events.
+	 * @type {CKEDITOR.dialog}
+	 */
+	var dialog;
+	var onClick = function( evt )
+	{
+		var target = evt.data.getTarget(),
+			targetName = target.getName();
+
+		if ( targetName == 'td' )
+			target = target.getChild( [ 0, 0 ] );
+		else if ( targetName == 'a' )
+			target = target.getChild( 0 );
+		else if ( targetName != 'img' )
+			return;
+
+		var src = target.getAttribute( 'cke_src' ),
+			title = target.getAttribute( 'title' );
+
+		var img = editor.document.createElement( 'img',
+			{
+				attributes :
+				{
+					src : src,
+					_cke_saved_src : src,
+					title : title,
+					alt : title
+				}
+			});
+
+		editor.insertElement( img );
+
+		dialog.hide();
+	}
+
+	var onKeydown = CKEDITOR.tools.addFunction( function( ev, element )
+	{
+		ev = new CKEDITOR.dom.event( ev );
+		element = new CKEDITOR.dom.element( element );
+		var relative, nodeToMove;
+
+		var keystroke = ev.getKeystroke();
+		switch ( keystroke )
+		{
+			// RIGHT-ARROW
+			case 39 :
+				// relative is TD
+				if ( ( relative = element.getParent().getNext() ) )
+				{
+					nodeToMove = relative.getChild( 0 );
+					nodeToMove.focus();
+				}
+				ev.preventDefault();
+				break;
+			// LEFT-ARROW
+			case 37 :
+				// relative is TD
+				if ( ( relative = element.getParent().getPrevious() ) )
+				{
+					nodeToMove = relative.getChild( 0 );
+					nodeToMove.focus();
+				}
+				ev.preventDefault();
+				break;
+			// UP-ARROW
+			case 38 :
+				// relative is TR
+				if ( ( relative = element.getParent().getParent().getPrevious() ) )
+				{
+					nodeToMove = relative.getChild( [element.getParent().getIndex(), 0] );
+					nodeToMove.focus();
+				}
+				ev.preventDefault();
+				break;
+			// DOWN-ARROW
+			case 40 :
+				// relative is TR
+				if ( ( relative = element.getParent().getParent().getNext() ) )
+				{
+					nodeToMove = relative.getChild( [element.getParent().getIndex(), 0] );
+					if ( nodeToMove )
+						nodeToMove.focus();
+				}
+				ev.preventDefault();
+				break;
+			// ENTER
+			// SPACE
+			case 13 :
+			case 32 :
+				onClick( { data: ev } );
+				ev.preventDefault();
+				break;
+			// TAB
+			case 9 :
+				// relative is TD
+				if ( ( relative = element.getParent().getNext() ) )
+				{
+					nodeToMove = relative.getChild( 0 );
+					nodeToMove.focus();
+					ev.preventDefault(true);
+				}
+				// relative is TR
+				else if ( ( relative = element.getParent().getParent().getNext() ) )
+				{
+					nodeToMove = relative.getChild( [0, 0] );
+					if ( nodeToMove )
+						nodeToMove.focus();
+					ev.preventDefault(true);
+				}
+				break;
+			// SHIFT + TAB
+			case CKEDITOR.SHIFT + 9 :
+				// relative is TD
+				if ( ( relative = element.getParent().getPrevious() ) )
+				{
+					nodeToMove = relative.getChild( 0 );
+					nodeToMove.focus();
+					ev.preventDefault(true);
+				}
+				// relative is TR
+				else if ( ( relative = element.getParent().getParent().getPrevious() ) )
+				{
+					nodeToMove = relative.getLast().getChild( 0 );
+					nodeToMove.focus();
+					ev.preventDefault(true);
+				}
+				break;
+			default :
+				// Do not stop not handled events.
+				return;
+		}
+	});
 
 	// Build the HTML for the smiley images table.
@@ -26,11 +160,13 @@
 		html.push(
 			'<td class="dark_background hand centered" style="vertical-align: middle;">' +
-				'<img border="0" class="hand" title="', config.smiley_descriptions[i], '"' +
-					' cke_src="', CKEDITOR.tools.htmlEncode( config.smiley_path + images[ i ] ), '"',
-					' src="', CKEDITOR.tools.htmlEncode( config.smiley_path + images[ i ] ), '"',
-					// IE BUG: Below is a workaround to an IE image loading bug to ensure the image sizes are correct.
-					( CKEDITOR.env.ie ? ' onload="this.setAttribute(\'width\', 2); this.removeAttribute(\'width\');" ' : '' ),
-				'>' +
-			'</td>' );
+				'<a class="cke_smile" tabindex="-1" onkeydown="CKEDITOR.tools.callFunction( ', onKeydown, ', event, this );">',
+					'<img class="hand" title="', config.smiley_descriptions[i], '"' +
+						' cke_src="', CKEDITOR.tools.htmlEncode( config.smiley_path + images[ i ] ), '"',
+						' src="', CKEDITOR.tools.htmlEncode( config.smiley_path + images[ i ] ), '"',
+						// IE BUG: Below is a workaround to an IE image loading bug to ensure the image sizes are correct.
+						( CKEDITOR.env.ie ? ' onload="this.setAttribute(\'width\', 2); this.removeAttribute(\'width\');" ' : '' ),
+					'>' +
+				'</a>',
+ 			'</td>' );
 
 		if ( i % columns == columns - 1 )
@@ -51,32 +187,14 @@
 		type : 'html',
 		html : html.join( '' ),
-		onClick : function( evt )
+		onLoad : function( event )
 		{
-			var target = evt.data.getTarget(),
-				targetName = target.getName();
-
-			if ( targetName == 'td' )
-				target = target.getChild(0);
-			else if ( targetName != 'img' )
-				return;
-
-			var src = target.getAttribute( 'cke_src' ),
-				title = target.getAttribute( 'title' );
-
-			var img = editor.document.createElement( 'img',
-				{
-					attributes :
-					{
-						src : src,
-						_cke_saved_src : src,
-						title : title,
-						alt : title
-					}
-				});
-
-			editor.insertElement( img );
-
-			this.getDialog().hide();
+			dialog = event.sender;
 		},
+		focus : function()
+ 		{
+			var firstSmile = this.getElement().getChild( [0, 0, 0, 0] );
+			firstSmile.focus();
+ 		},
+		onClick : onClick,
 		style : 'width: 100%; height: 100%; border-collapse: separate;'
 	};
Index: /CKEditor/trunk/_source/skins/v2/dialog.css
===================================================================
--- /CKEditor/trunk/_source/skins/v2/dialog.css	(revision 3509)
+++ /CKEditor/trunk/_source/skins/v2/dialog.css	(revision 3510)
@@ -628,2 +628,16 @@
 	top: 3px;
 }
+
+.cke_skin_v2 a.cke_smile img
+{
+	/* IE6 does not support transparent borders */
+	border: 2px solid #eaead1;
+}
+
+.cke_skin_v2 a.cke_smile:focus img,
+.cke_skin_v2 a.cke_smile:active img,
+.cke_skin_v2 a.cke_smile:hover img
+{
+	border-color: #C7C78F;
+}
+
