diff --git a/eeschema/block.cpp b/eeschema/block.cpp
index a67b990de5..2a46f5527a 100644
--- a/eeschema/block.cpp
+++ b/eeschema/block.cpp
@@ -126,7 +126,7 @@ void SCH_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
             m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
 
         // If the block wasn't changed, don't update the schematic
-        if( block->GetMoveVector() == wxPoint( 0, 0 ) )
+        if( block->GetMoveVector() == wxPoint( 0, 0 ) && !block->AppendUndo() )
         {
             // This calls the block-abort command routine on cleanup
             m_canvas->EndMouseCapture( GetToolId(), GetGalCanvas()->GetCurrentCursor() );
@@ -384,6 +384,17 @@ void SCH_EDIT_FRAME::copyBlockItems( PICKED_ITEMS_LIST& aItemsList, const wxPoin
 {
     m_blockItems.ClearListAndDeleteItems();   // delete previous saved list, if exists
 
+    wxRect bounds;
+
+    if( aItemsList.GetCount() > 0 )
+        bounds = aItemsList.GetPickedItem( 0 )->GetBoundingBox();
+
+    for( unsigned i = 1; i < aItemsList.GetCount(); ++i )
+        bounds.Union( aItemsList.GetPickedItem( i )->GetBoundingBox() );
+
+    wxPoint center( ( bounds.GetLeft() + bounds.GetRight() ) / 2,
+                    ( bounds.GetTop() + bounds.GetBottom() ) / 2 );
+
     for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
     {
         // Clear m_Flag member of selected items:
@@ -393,7 +404,7 @@ void SCH_EDIT_FRAME::copyBlockItems( PICKED_ITEMS_LIST& aItemsList, const wxPoin
         SCH_ITEM* copy = DuplicateStruct( (SCH_ITEM*) aItemsList.GetPickedItem( ii ) );
         copy->SetParent( NULL );
         copy->SetFlags( copy->GetFlags() | UR_TRANSIENT );
-        copy->Move( aMoveVector );
+        copy->Move( -center );
         ITEM_PICKER item( copy, UR_NEW );
 
         m_blockItems.PushItem( item );
diff --git a/eeschema/libedit/lib_edit_frame.cpp b/eeschema/libedit/lib_edit_frame.cpp
index 74fb4805a4..762fb9822e 100644
--- a/eeschema/libedit/lib_edit_frame.cpp
+++ b/eeschema/libedit/lib_edit_frame.cpp
@@ -861,6 +861,7 @@ void LIB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
         break;
 
     case wxID_PASTE:
+    case ID_POPUP_PASTE_BLOCK:
         HandleBlockBegin( nullptr, BLOCK_PASTE, GetCrossHairPosition() );
         break;
 
diff --git a/eeschema/libedit/libedit_onrightclick.cpp b/eeschema/libedit/libedit_onrightclick.cpp
index 54eef6a567..08cb1211e5 100644
--- a/eeschema/libedit/libedit_onrightclick.cpp
+++ b/eeschema/libedit/libedit_onrightclick.cpp
@@ -103,9 +103,9 @@ bool LIB_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu )
         if( GetToolId() == ID_NO_TOOL_SELECTED )
         {
             msg = AddHotkeyName( _( "&Paste" ), g_Libedit_Hokeys_Descr, HK_EDIT_PASTE );
-            AddMenuItem( PopMenu, wxID_PASTE, msg,
-                        _( "Pastes item(s) from the Clipboard" ),
-                        KiBitmap( paste_xpm ) );
+            AddMenuItem( PopMenu, ID_POPUP_PASTE_BLOCK, msg, _( "Pastes copied item(s)" ),
+                         KiBitmap( paste_xpm ) );
+            PopMenu->AppendSeparator();
         }
 
         return true;
diff --git a/eeschema/sch_base_frame.cpp b/eeschema/sch_base_frame.cpp
index 9d459b0a89..29fe0d918d 100644
--- a/eeschema/sch_base_frame.cpp
+++ b/eeschema/sch_base_frame.cpp
@@ -496,7 +496,7 @@ KIGFX::SCH_RENDER_SETTINGS* SCH_BASE_FRAME::GetRenderSettings()
 
 
 bool SCH_BASE_FRAME::HandleBlockBegin( wxDC* aDC, EDA_KEY aKey, const wxPoint& aPosition,
-       int aExplicitCommand )
+                                       int aExplicitCommand )
 {
     BLOCK_SELECTOR* block = &GetScreen()->m_BlockLocate;
 
@@ -537,10 +537,14 @@ bool SCH_BASE_FRAME::HandleBlockBegin( wxDC* aDC, EDA_KEY aKey, const wxPoint& a
         block->InitData( m_canvas, aPosition );
         InitBlockPasteInfos();
 
-        KIGFX::PREVIEW::SELECTION_AREA* sel = GetCanvas()->GetView()->GetSelectionArea();
-        VECTOR2I offsetToCenter = GetCanvas()->GetGAL()->GetGridPoint(
-                ( sel->GetOrigin() - sel->GetEnd() ) / 2 );
-        block->SetLastCursorPosition( wxPoint( offsetToCenter.x, offsetToCenter.y ) );
+        wxRect bounds( 0, 0, 0, 0 );
+
+        for( unsigned i = 0; i < block->GetCount(); ++i )
+            bounds.Union( block->GetItem( i )->GetBoundingBox() );
+
+        block->SetOrigin( bounds.GetPosition() );
+        block->SetSize( bounds.GetSize() );
+        block->SetLastCursorPosition( wxPoint( 0, 0 ) );
 
         if( block->GetCount() == 0 )      // No data to paste
         {
diff --git a/eeschema/schedit.cpp b/eeschema/schedit.cpp
index 23a0875b12..f6f7ce79c4 100644
--- a/eeschema/schedit.cpp
+++ b/eeschema/schedit.cpp
@@ -144,6 +144,7 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
         break;
 
     case wxID_PASTE:
+    case ID_POPUP_PASTE_BLOCK:
         HandleBlockBegin( nullptr, BLOCK_PASTE, GetCrossHairPosition() );
         break;
 
@@ -850,9 +851,7 @@ void SCH_EDIT_FRAME::OnRotate( wxCommandEvent& aEvent )
     if( block.GetState() != STATE_NO_BLOCK )
     {
         // Compute the rotation center and put it on grid:
-        wxPoint rotationPoint = block.Centre();
-        rotationPoint = GetNearestGridPosition( rotationPoint );
-        SetCrossHairPosition( rotationPoint );
+        wxPoint rotationPoint = GetNearestGridPosition( block.Centre() );
 
         if( block.GetCommand() != BLOCK_DUPLICATE )
         {
diff --git a/include/id.h b/include/id.h
index 39f39bac8e..3b4e509abc 100644
--- a/include/id.h
+++ b/include/id.h
@@ -165,6 +165,7 @@ enum main_id
     ID_POPUP_MOVE_BLOCK_EXACT,
     ID_POPUP_DRAG_BLOCK,
     ID_POPUP_COPY_BLOCK,
+    ID_POPUP_PASTE_BLOCK,
     ID_POPUP_CUT_BLOCK,
     ID_POPUP_DUPLICATE_BLOCK,
     ID_POPUP_ROTATE_BLOCK,