diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index e19a35bbc5b6f3542506785e811cd917b70ad567..c6663836fd75e184d8e37fae73be1bcd911d9835 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -208,13 +208,44 @@ var FileList={
 				if (FileList.checkName(name, newname, false)) {
 					newname = name;
 				} else {
-					$.get(OC.filePath('files','ajax','rename.php'), { dir : $('#dir').val(), newname: newname, file: name },function(result) {
-						if (!result || result.status == 'error') {
-							OC.dialogs.alert(result.data.message, 'Error moving file');
-							newname = name;
+					// save background image, because it's replaced by a spinner while async request
+					var oldBackgroundImage = td.css('background-image');
+					// mark as loading
+					td.css('background-image', 'url('+ OC.imagePath('core', 'loading.gif') + ')');
+					$.ajax({
+						url: OC.filePath('files','ajax','rename.php'),
+						data: {
+							dir : $('#dir').val(),
+							newname: newname,
+							file: name
+						},
+						success: function(result) {
+							if (!result || result.status === 'error') {
+								OC.Notification.show(result.data.message);
+								newname = name;
+								// revert changes
+								tr.attr('data-file', newname);
+								var path = td.children('a.name').attr('href');
+								td.children('a.name').attr('href', path.replace(encodeURIComponent(name), encodeURIComponent(newname)));
+								if (newname.indexOf('.') > 0 && tr.data('type') !== 'dir') {
+									var basename=newname.substr(0,newname.lastIndexOf('.'));
+								} else {
+									var basename=newname;
+								}
+								td.find('a.name span.nametext').text(basename);
+								if (newname.indexOf('.') > 0 && tr.data('type') !== 'dir') {
+									if (td.find('a.name span.extension').length === 0 ) {
+										td.find('a.name span.nametext').append('<span class="extension"></span>');
+									}
+									td.find('a.name span.extension').text(newname.substr(newname.lastIndexOf('.')));
+								}
+								tr.find('.fileactions').effect('highlight', {}, 5000);
+								tr.effect('highlight', {}, 5000);
+							}
+							// remove loading mark and recover old image
+							td.css('background-image', oldBackgroundImage);
 						}
 					});
-
 				}
 			}
 			tr.data('renaming',false);
diff --git a/apps/files/lib/app.php b/apps/files/lib/app.php
index c2a4b9c2675dcc3bfe2f510916b7abb322ad5b72..f7052ef80b0eadccb22c20c5b4c6a1d971cd6ba1 100644
--- a/apps/files/lib/app.php
+++ b/apps/files/lib/app.php
@@ -70,7 +70,7 @@ class App {
 		} else {
 			// rename failed
 			$result['data'] = array(
-				'message'	=> $this->l10n->t('Unable to rename file')
+				'message'	=> $this->l10n->t('%s could not be renamed', array($oldname))
 			);
 		}
 		return $result;
diff --git a/apps/files/tests/ajax_rename.php b/apps/files/tests/ajax_rename.php
index 23e5761ddda44869855bc22a7f13b59caa29ab95..2b90a11743d164053d17770a463fddde561a2f88 100644
--- a/apps/files/tests/ajax_rename.php
+++ b/apps/files/tests/ajax_rename.php
@@ -50,7 +50,7 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase {
 		$result = $this->files->rename($dir, $oldname, $newname);
 		$expected = array(
 			'success'	=> false,
-			'data'		=> array('message' => 'Unable to rename file')
+			'data'		=> array('message' => '%s could not be renamed')
 		);
 
 		$this->assertEquals($expected, $result);
diff --git a/core/js/js.js b/core/js/js.js
index 3cb4d3dd151582915626c2363dc106b4a7de1fc3..55db625a3399657c5db1aa88b2dde44ae88d09cf 100644
--- a/core/js/js.js
+++ b/core/js/js.js
@@ -349,10 +349,10 @@ OC.Notification={
 	},
 	show: function(text) {
 		if(($('#notification').filter('span.undo').length == 1) || OC.Notification.isHidden()){
-			$('#notification').html(text);
+			$('#notification').text(text);
 			$('#notification').fadeIn().css("display","inline");
 		}else{
-			OC.Notification.queuedNotifications.push($(text).html());
+			OC.Notification.queuedNotifications.push($('<div/>').text(text).html());
 		}
 	},
 	isHidden: function() {