diff --git a/common/eda_draw_frame.cpp b/common/eda_draw_frame.cpp
index 121f4670f3..e32450587e 100644
--- a/common/eda_draw_frame.cpp
+++ b/common/eda_draw_frame.cpp
@@ -424,15 +424,6 @@ void EDA_DRAW_FRAME::OnSize( wxSizeEvent& SizeEv )
 }
 
 
-void EDA_DRAW_FRAME::SetTool( const std::string& actionName )
-{
-    if( !m_toolStack.empty() )
-        m_toolStack.pop_back();
-
-    PushTool( actionName );
-}
-
-
 void EDA_DRAW_FRAME::PushTool( const std::string& actionName )
 {
     m_toolStack.push_back( actionName );
@@ -474,13 +465,6 @@ void EDA_DRAW_FRAME::PopTool()
 }
 
 
-void EDA_DRAW_FRAME::ClearToolStack()
-{
-    m_toolStack.clear();
-    DisplayToolMsg( ACTIONS::selectionTool.GetName() );
-}
-
-
 bool EDA_DRAW_FRAME::IsCurrentTool( const TOOL_ACTION& aAction )
 {
     if( m_toolStack.empty() )
diff --git a/common/tool/common_tools.cpp b/common/tool/common_tools.cpp
index 9c1ec3de61..98196cb983 100644
--- a/common/tool/common_tools.cpp
+++ b/common/tool/common_tools.cpp
@@ -43,6 +43,21 @@ void COMMON_TOOLS::Reset( RESET_REASON aReason )
 }
 
 
+int COMMON_TOOLS::SelectionTool( const TOOL_EVENT& aEvent )
+{
+    // Since selection tools are run permanently underneath the toolStack, this is really
+    // just a cancel of whatever other tools might be running.
+
+    m_toolMgr->ProcessEvent( TOOL_EVENT( TC_COMMAND, TA_CANCEL_TOOL ) );
+
+    // Shouldn't be necessary, but as the Irish would say: "just to be sure to be sure"
+    while( !m_frame->ToolStackIsEmpty() )
+        m_frame->PopTool();
+
+    return 0;
+}
+
+
 // Cursor control
 int COMMON_TOOLS::CursorControl( const TOOL_EVENT& aEvent )
 {
@@ -511,6 +526,8 @@ int COMMON_TOOLS::SwitchCanvas( const TOOL_EVENT& aEvent )
 
 void COMMON_TOOLS::setTransitions()
 {
+    Go( &COMMON_TOOLS::SelectionTool,      ACTIONS::selectionTool.MakeEvent() );
+
     // Cursor control
     Go( &COMMON_TOOLS::CursorControl,      ACTIONS::cursorUp.MakeEvent() );
     Go( &COMMON_TOOLS::CursorControl,      ACTIONS::cursorDown.MakeEvent() );
diff --git a/common/tool/tool_event.cpp b/common/tool/tool_event.cpp
index 762b214410..7ad3d3741f 100644
--- a/common/tool/tool_event.cpp
+++ b/common/tool/tool_event.cpp
@@ -51,6 +51,15 @@ static const std::string flag2string( int aFlag, const FlagString* aExps )
 }
 
 
+void TOOL_EVENT::init()
+{
+    // By default only MESSAGEs and Cancels are passed to multiple recipients
+    m_passEvent = m_category == TC_MESSAGE || TOOL_EVT_UTILS::IsCancelInteractive( *this );
+
+    m_hasPosition = ( m_category == TC_MOUSE || m_category == TC_COMMAND );
+}
+
+
 bool TOOL_EVENT::IsAction( const TOOL_ACTION* aAction ) const
 {
     return Matches( aAction->MakeEvent() );
@@ -176,7 +185,13 @@ bool TOOL_EVENT::IsDblClick( int aButtonMask ) const
 
 bool TOOL_EVT_UTILS::IsCancelInteractive( const TOOL_EVENT& aEvt )
 {
-    return aEvt.IsAction( &ACTIONS::cancelInteractive ) || aEvt.IsCancel();
+    if( aEvt.GetCommandStr() && aEvt.GetCommandStr().get() == ACTIONS::cancelInteractive.GetName() )
+        return true;
+
+    if( aEvt.GetCommandId() && aEvt.GetCommandId().get() == ACTIONS::cancelInteractive.GetId() )
+        return true;
+
+    return aEvt.IsCancel();
 }
 
 
@@ -188,3 +203,15 @@ bool TOOL_EVT_UTILS::IsSelectionEvent( const TOOL_EVENT& aEvt )
 }
 
 
+bool TOOL_EVT_UTILS::IsPointEditor( const TOOL_EVENT& aEvt )
+{
+    if( aEvt.GetCommandStr() && aEvt.GetCommandStr().get().find( "PointEditor" ) >= 0 )
+        return true;
+
+    if( aEvt.GetCommandId() && aEvt.GetCommandId() == ACTIONS::activatePointEditor.GetId() )
+        return true;
+
+    return false;
+}
+
+
diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp
index 194556cb9d..93fd69e994 100644
--- a/common/tool/tool_manager.cpp
+++ b/common/tool/tool_manager.cpp
@@ -763,7 +763,7 @@ TOOL_MANAGER::ID_LIST::iterator TOOL_MANAGER::finishTool( TOOL_STATE* aState )
     if( tool->GetType() == INTERACTIVE )
         static_cast<TOOL_INTERACTIVE*>( tool )->resetTransitions();
 
-    return it;
+    return --it;
 }
 
 
diff --git a/common/tool/zoom_tool.cpp b/common/tool/zoom_tool.cpp
index 2d7737864a..4b4557da7f 100644
--- a/common/tool/zoom_tool.cpp
+++ b/common/tool/zoom_tool.cpp
@@ -51,12 +51,7 @@ int ZOOM_TOOL::Main( const TOOL_EVENT& aEvent )
     while( auto evt = Wait() )
     {
         if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() )
-        {
-            if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
-                m_frame->ClearToolStack();
-
             break;
-        }
 
         else if( evt->IsDrag( BUT_LEFT ) || evt->IsDrag( BUT_RIGHT ) )
         {
@@ -87,7 +82,7 @@ bool ZOOM_TOOL::selectRegion()
 
     while( auto evt = Wait() )
     {
-        if( evt->IsCancel() || evt->IsActivate() )
+        if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() )
         {
             cancelled = true;
             break;
diff --git a/cvpcb/tools/cvpcb_selection_tool.cpp b/cvpcb/tools/cvpcb_selection_tool.cpp
index f97380a3e7..34356d8c0c 100644
--- a/cvpcb/tools/cvpcb_selection_tool.cpp
+++ b/cvpcb/tools/cvpcb_selection_tool.cpp
@@ -105,7 +105,7 @@ int CVPCB_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
     auto& controls = *getViewControls();
     auto previous_settings = controls.GetSettings();
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     KIGFX::PREVIEW::TWO_POINT_GEOMETRY_MANAGER twoPtMgr;
@@ -124,7 +124,7 @@ int CVPCB_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
     {
         const VECTOR2I cursorPos = controls.GetCursorPosition();
 
-        if( evt->IsCancel() || evt->IsActivate() )
+        if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() )
         {
             if( originSet )
             {
@@ -135,7 +135,6 @@ int CVPCB_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
             }
             else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
             {
-                m_frame->ClearToolStack();
                 break;
             }
 
@@ -195,9 +194,8 @@ int CVPCB_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
 
     view.SetVisible( &ruler, false );
     view.Remove( &ruler );
-
     controls.ApplySettings( previous_settings );
-
+    m_frame->PopTool();
     return 0;
 }
 
diff --git a/eeschema/tools/ee_point_editor.cpp b/eeschema/tools/ee_point_editor.cpp
index 467fbadd36..81aac1cc51 100644
--- a/eeschema/tools/ee_point_editor.cpp
+++ b/eeschema/tools/ee_point_editor.cpp
@@ -282,10 +282,6 @@ int EE_POINT_EDITOR::Main( const TOOL_EVENT& aEvent )
     controls->ShowCursor( true );
 
     m_editPoints = EDIT_POINTS_FACTORY::Make( item, m_frame );
-
-    if( !m_editPoints )
-        return 0;
-
     view->Add( m_editPoints.get() );
     setEditedPoint( nullptr );
     bool inDrag = false;
@@ -331,10 +327,6 @@ int EE_POINT_EDITOR::Main( const TOOL_EVENT& aEvent )
                 modified = false;
             }
 
-            // ESC should clear selection along with edit points
-            if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
-                m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
-
             break;
         }
 
diff --git a/eeschema/tools/ee_selection_tool.cpp b/eeschema/tools/ee_selection_tool.cpp
index 25dd419c9d..083b48987c 100644
--- a/eeschema/tools/ee_selection_tool.cpp
+++ b/eeschema/tools/ee_selection_tool.cpp
@@ -260,15 +260,6 @@ int EE_SELECTION_TOOL::UpdateMenu( const TOOL_EVENT& aEvent )
 }
 
 
-int EE_SELECTION_TOOL::SelectionTool( const TOOL_EVENT& aEvent )
-{
-    // Since the selection tool is always running underneath the toolStack, all we need to
-    // do is clear the stack.
-    m_frame->ClearToolStack();
-    return 0;
-}
-
-
 int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
 {
     const KICAD_T movableItems[] =
@@ -409,7 +400,6 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
         else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
         {
             ClearSelection();
-            m_toolMgr->RunAction( EE_ACTIONS::clearHighlight, true );
         }
 
         else if( evt->Action() == TA_UNDO_REDO_PRE )
@@ -1299,7 +1289,6 @@ void EE_SELECTION_TOOL::setTransitions()
     Go( &EE_SELECTION_TOOL::UpdateMenu,          ACTIONS::updateMenu.MakeEvent() );
 
     Go( &EE_SELECTION_TOOL::Main,                EE_ACTIONS::selectionActivate.MakeEvent() );
-    Go( &EE_SELECTION_TOOL::SelectionTool,       ACTIONS::selectionTool.MakeEvent() );
     Go( &EE_SELECTION_TOOL::SelectNode,          EE_ACTIONS::selectNode.MakeEvent() );
     Go( &EE_SELECTION_TOOL::SelectConnection,    EE_ACTIONS::selectConnection.MakeEvent() );
     Go( &EE_SELECTION_TOOL::ClearSelection,      EE_ACTIONS::clearSelection.MakeEvent() );
diff --git a/eeschema/tools/ee_selection_tool.h b/eeschema/tools/ee_selection_tool.h
index f08fa31cba..e3739819c4 100644
--- a/eeschema/tools/ee_selection_tool.h
+++ b/eeschema/tools/ee_selection_tool.h
@@ -74,11 +74,6 @@ public:
      */
     int Main( const TOOL_EVENT& aEvent );
 
-    /*
-     * Main() is always running, so this just clears the frame's tool stack.
-     */
-    int SelectionTool( const TOOL_EVENT& aEvent );
-
     /**
      * Function GetSelection()
      *
diff --git a/eeschema/tools/lib_drawing_tools.cpp b/eeschema/tools/lib_drawing_tools.cpp
index 2b6fc69835..e4b7a4caad 100644
--- a/eeschema/tools/lib_drawing_tools.cpp
+++ b/eeschema/tools/lib_drawing_tools.cpp
@@ -76,7 +76,7 @@ int LIB_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
     m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
     getViewControls()->ShowCursor( true );
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     // Prime the pump
@@ -97,13 +97,9 @@ int LIB_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
                 delete item;
                 item = nullptr;
             }
-            else
+            else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
             {
-                if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
-                {
-                    m_frame->ClearToolStack();
-                    break;
-                }
+                break;
             }
 
             if( evt->IsActivate() )
@@ -210,6 +206,7 @@ int LIB_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
         getViewControls()->CaptureCursor( item != nullptr );
     }
 
+    m_frame->PopTool();
     return 0;
 }
 
@@ -225,7 +222,7 @@ int LIB_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
     m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
     getViewControls()->ShowCursor( true );
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     LIB_PART* part = m_frame->GetCurPart();
@@ -242,24 +239,20 @@ int LIB_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
 
         if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() )
         {
-            m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
-            m_view->ClearPreview();
-
             if( item )
             {
+                m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
+                m_view->ClearPreview();
                 delete item;
                 item = nullptr;
             }
-            else
+            else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
             {
-                if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
-                {
-                    m_frame->ClearToolStack();
-                    break;
-                }
+                break;
             }
 
-            if( evt->IsActivate() )
+            // Continue on if it's just the point editor; otherwise give way to new tool
+            if( evt->IsActivate() && !TOOL_EVT_UTILS::IsPointEditor( *evt ) )
                 break;
         }
 
@@ -341,6 +334,7 @@ int LIB_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
         getViewControls()->CaptureCursor( item != nullptr );
     }
 
+    m_frame->PopTool();
     return 0;
 }
 
@@ -350,7 +344,7 @@ int LIB_DRAWING_TOOLS::PlaceAnchor( const TOOL_EVENT& aEvent )
     getViewControls()->ShowCursor( true );
     getViewControls()->SetSnapping( true );
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     // Main loop: keep receiving events
@@ -386,7 +380,7 @@ int LIB_DRAWING_TOOLS::PlaceAnchor( const TOOL_EVENT& aEvent )
         }
     }
 
-    m_frame->ClearToolStack();
+    m_frame->PopTool();
     return 0;
 }
 
diff --git a/eeschema/tools/lib_edit_tool.cpp b/eeschema/tools/lib_edit_tool.cpp
index 7829b04656..e8ae85d1fb 100644
--- a/eeschema/tools/lib_edit_tool.cpp
+++ b/eeschema/tools/lib_edit_tool.cpp
@@ -282,7 +282,7 @@ int LIB_EDIT_TOOL::DeleteItemCursor( const TOOL_EVENT& aEvent )
 {
     m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     EE_PICKER_TOOL* picker = m_toolMgr->GetTool<EE_PICKER_TOOL>();
@@ -327,14 +327,12 @@ int LIB_EDIT_TOOL::DeleteItemCursor( const TOOL_EVENT& aEvent )
     {
         if( m_pickerItem )
             m_toolMgr->GetTool<EE_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem );
-
-        if( aFinalState == EE_PICKER_TOOL::EVT_CANCEL )
-            m_frame->ClearToolStack();
     } );
 
     picker->Activate();
     Wait();
 
+    m_frame->PopTool();
     return 0;
 }
 
diff --git a/eeschema/tools/sch_drawing_tools.cpp b/eeschema/tools/sch_drawing_tools.cpp
index 8b3a335027..27a76fc39f 100644
--- a/eeschema/tools/sch_drawing_tools.cpp
+++ b/eeschema/tools/sch_drawing_tools.cpp
@@ -99,7 +99,7 @@ int SCH_DRAWING_TOOLS::PlaceComponent(  const TOOL_EVENT& aEvent  )
         m_selectionTool->AddItemToSel( component );
     }
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     // Prime the pump
@@ -125,13 +125,9 @@ int SCH_DRAWING_TOOLS::PlaceComponent(  const TOOL_EVENT& aEvent  )
                 delete component;
                 component = nullptr;
             }
-            else
+            else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
             {
-                if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
-                {
-                    m_frame->ClearToolStack();
-                    break;
-                }
+                break;
             }
 
             if( evt->IsActivate() )
@@ -212,6 +208,7 @@ int SCH_DRAWING_TOOLS::PlaceComponent(  const TOOL_EVENT& aEvent  )
         getViewControls()->CaptureCursor( component != nullptr );
     }
 
+    m_frame->PopTool();
     return 0;
 }
 
@@ -220,13 +217,7 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
 {
     SCH_BITMAP* image = aEvent.Parameter<SCH_BITMAP*>();
     bool        immediateMode = image;
-
-    if( immediateMode )
-        m_frame->PushTool( aEvent.GetCommandStr().get() );
-    else
-        m_frame->SetTool( aEvent.GetCommandStr().get() );
-
-    VECTOR2I cursorPos = getViewControls()->GetCursorPosition();
+    VECTOR2I    cursorPos = getViewControls()->GetCursorPosition();
 
     m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
     getViewControls()->ShowCursor( true );
@@ -239,6 +230,7 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
         m_view->AddToPreview( image->Clone() );
     }
 
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     // Prime the pump
@@ -264,13 +256,9 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
                 if( immediateMode )
                     break;
             }
-            else
+            else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
             {
-                if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
-                {
-                    m_frame->ClearToolStack();
-                    break;
-                }
+                break;
             }
 
             if( evt->IsActivate() )
@@ -348,9 +336,7 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
         getViewControls()->CaptureCursor( image != nullptr );
     }
 
-    if( immediateMode )
-        m_frame->PopTool();
-
+    m_frame->PopTool();
     return 0;
 }
 
@@ -383,7 +369,7 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent )
     getViewControls()->ShowCursor( true );
     getViewControls()->SetSnapping( true );
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     // Prime the pump
@@ -397,9 +383,6 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent )
 
         if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() )
         {
-            if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
-                m_frame->ClearToolStack();
-
             break;
         }
         else if( evt->IsClick( BUT_LEFT ) )
@@ -445,6 +428,7 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent )
         }
     }
 
+    m_frame->PopTool();
     return 0;
 }
 
@@ -458,7 +442,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
     m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
     getViewControls()->ShowCursor( true );
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     // Prime the pump
@@ -479,13 +463,9 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
                 delete item;
                 item = nullptr;
             }
-            else
+            else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
             {
-                if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
-                {
-                    m_frame->ClearToolStack();
-                    break;
-                }
+                break;
             }
 
             if( evt->IsActivate() )
@@ -616,6 +596,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
         getViewControls()->CaptureCursor( item != nullptr );
     }
 
+    m_frame->PopTool();
     return 0;
 }
 
@@ -627,8 +608,7 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
     m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
     getViewControls()->ShowCursor( true );
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
-
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     // Prime the pump
@@ -650,13 +630,9 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
                 delete sheet;
                 sheet = nullptr;
             }
-            else
+            else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
             {
-                if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
-                {
-                    m_frame->ClearToolStack();
-                    break;
-                }
+                break;
             }
 
             if( evt->IsActivate() )
@@ -717,6 +693,7 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
         getViewControls()->CaptureCursor( sheet != nullptr);
     }
 
+    m_frame->PopTool();
     return 0;
 }
 
diff --git a/eeschema/tools/sch_edit_tool.cpp b/eeschema/tools/sch_edit_tool.cpp
index 55cab74fa9..772b5d87bb 100644
--- a/eeschema/tools/sch_edit_tool.cpp
+++ b/eeschema/tools/sch_edit_tool.cpp
@@ -999,9 +999,6 @@ int SCH_EDIT_TOOL::DeleteItemCursor( const TOOL_EVENT& aEvent )
     {
         if( m_pickerItem )
             m_toolMgr->GetTool<EE_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem );
-
-        if( aFinalState == EE_PICKER_TOOL::EVT_CANCEL )
-            m_frame->ClearToolStack();
     } );
 
     picker->Activate();
diff --git a/eeschema/tools/sch_editor_control.cpp b/eeschema/tools/sch_editor_control.cpp
index 17fe3475a6..bf7fd4bc6c 100644
--- a/eeschema/tools/sch_editor_control.cpp
+++ b/eeschema/tools/sch_editor_control.cpp
@@ -1170,6 +1170,7 @@ void SCH_EDITOR_CONTROL::setTransitions()
     Go( &SCH_EDITOR_CONTROL::HighlightNetCursor,    EE_ACTIONS::highlightNetCursor.MakeEvent() );
     Go( &SCH_EDITOR_CONTROL::UpdateNetHighlighting, EVENTS::SelectedItemsModified );
     Go( &SCH_EDITOR_CONTROL::UpdateNetHighlighting, EE_ACTIONS::updateNetHighlighting.MakeEvent() );
+    Go( &SCH_EDITOR_CONTROL::ClearHighlight,        ACTIONS::cancelInteractive.MakeEvent() );
 
     Go( &SCH_EDITOR_CONTROL::Undo,                  ACTIONS::undo.MakeEvent() );
     Go( &SCH_EDITOR_CONTROL::Redo,                  ACTIONS::redo.MakeEvent() );
diff --git a/eeschema/tools/sch_line_wire_bus_tool.cpp b/eeschema/tools/sch_line_wire_bus_tool.cpp
index 848eaac073..74521c7eaa 100644
--- a/eeschema/tools/sch_line_wire_bus_tool.cpp
+++ b/eeschema/tools/sch_line_wire_bus_tool.cpp
@@ -257,14 +257,18 @@ int SCH_LINE_WIRE_BUS_TOOL::DrawSegments( const TOOL_EVENT& aEvent )
     if( aEvent.HasPosition() )
         getViewControls()->WarpCursor( getViewControls()->GetCursorPosition(), true );
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
 
     if( aEvent.HasPosition() )
     {
         VECTOR2D cursorPos = getViewControls()->GetCursorPosition( !aEvent.Modifier( MD_ALT ) );
         segment = startSegments( layer, cursorPos );
     }
-    return doDrawSegments( layer, segment );
+
+    doDrawSegments( layer, segment );
+
+    m_frame->PopTool();
+    return 0;
 }
 
 
@@ -477,7 +481,6 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( int aType, SCH_LINE* aSegment )
             }
             else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
             {
-                m_frame->ClearToolStack();
                 break;
             }
 
diff --git a/gerbview/tools/gerbview_selection_tool.cpp b/gerbview/tools/gerbview_selection_tool.cpp
index 0b66fe7cad..fcead36210 100644
--- a/gerbview/tools/gerbview_selection_tool.cpp
+++ b/gerbview/tools/gerbview_selection_tool.cpp
@@ -352,7 +352,7 @@ bool GERBVIEW_SELECTION_TOOL::selectMultiple()
 
     while( TOOL_EVENT* evt = Wait() )
     {
-        if( evt->IsCancel() )
+        if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
         {
             cancelled = true;
             break;
@@ -754,7 +754,7 @@ int GERBVIEW_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
     auto& controls = *getViewControls();
     auto previous_settings = controls.GetSettings();
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     KIGFX::PREVIEW::TWO_POINT_GEOMETRY_MANAGER twoPtMgr;
@@ -773,7 +773,7 @@ int GERBVIEW_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
     {
         const VECTOR2I cursorPos = controls.GetCursorPosition();
 
-        if( evt->IsCancel() || evt->IsActivate() )
+        if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() )
         {
             if( originSet )
             {
@@ -784,7 +784,6 @@ int GERBVIEW_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
             }
             else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
             {
-                m_frame->ClearToolStack();
                 break;
             }
 
@@ -844,9 +843,8 @@ int GERBVIEW_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
 
     view.SetVisible( &ruler, false );
     view.Remove( &ruler );
-
     controls.ApplySettings( previous_settings );
-
+    m_frame->PopTool();
     return 0;
 }
 
diff --git a/include/eda_draw_frame.h b/include/eda_draw_frame.h
index 7b7bfc0d63..d157c03c1d 100644
--- a/include/eda_draw_frame.h
+++ b/include/eda_draw_frame.h
@@ -307,14 +307,8 @@ public:
      * a single TOOL_BASE derived class to implement several user "tools", such as rectangle
      * and circle, or wire and bus.  So each user-level tool is actually a TOOL_ACTION.
      */
-    virtual void SetTool( const std::string& actionName );
     virtual void PushTool( const std::string& actionName );
     virtual void PopTool();
-    /**
-     * The selection tool runs underneath the tool stack, so clearing the stack is equivalent
-     * to selecting the selection tool.
-     */
-    virtual void ClearToolStack();
 
     bool ToolStackIsEmpty() { return m_toolStack.empty(); }
 
diff --git a/include/tool/common_tools.h b/include/tool/common_tools.h
index a6217d096e..a7593ad5db 100644
--- a/include/tool/common_tools.h
+++ b/include/tool/common_tools.h
@@ -48,6 +48,8 @@ public:
     /// @copydoc TOOL_BASE::Reset()
     void Reset( RESET_REASON aReason ) override;
 
+    int SelectionTool( const TOOL_EVENT& aEvent );
+
     // View controls
     int ZoomRedraw( const TOOL_EVENT& aEvent );
     int ZoomInOut( const TOOL_EVENT& aEvent );
diff --git a/include/tool/tool_event.h b/include/tool/tool_event.h
index d886e0953c..b3b8ac05f9 100644
--- a/include/tool/tool_event.h
+++ b/include/tool/tool_event.h
@@ -185,10 +185,7 @@ public:
         m_modifiers( 0 ),
         m_param( aParameter )
     {
-        m_hasPosition = ( aCategory == TC_MOUSE || aCategory == TC_COMMAND );
-
-        // By default only MESSAGEs are passed to multiple recipients
-        m_passEvent = ( aCategory == TC_MESSAGE );
+        init();
     }
 
     TOOL_EVENT( TOOL_EVENT_CATEGORY aCategory, TOOL_ACTIONS aAction, int aExtraParam,
@@ -219,10 +216,7 @@ public:
             m_modifiers = aExtraParam & MD_MODIFIER_MASK;
         }
 
-        // By default only MESSAGEs are passed to multiple recipients
-        m_passEvent = ( aCategory == TC_MESSAGE );
-
-        m_hasPosition = ( aCategory == TC_MOUSE || aCategory == TC_COMMAND );
+        init();
     }
 
     TOOL_EVENT( TOOL_EVENT_CATEGORY aCategory, TOOL_ACTIONS aAction,
@@ -239,10 +233,7 @@ public:
         if( aCategory == TC_COMMAND || aCategory == TC_MESSAGE )
             m_commandStr = aExtraParam;
 
-        // By default only MESSAGEs are passed to multiple recipients
-        m_passEvent = ( aCategory == TC_MESSAGE );
-
-        m_hasPosition = ( aCategory == TC_MOUSE || aCategory == TC_COMMAND );
+        init();
     }
 
     ///> Returns the category (eg. mouse/keyboard/action) of an event..
@@ -431,6 +422,8 @@ public:
 private:
     friend class TOOL_DISPATCHER;
 
+    void init();
+
     void setMouseDragOrigin( const VECTOR2D& aP )
     {
         m_mouseDragOrigin = aP;
@@ -648,18 +641,17 @@ inline const TOOL_EVENT_LIST operator||( const TOOL_EVENT& aEvent,
 /**
  * Namespace TOOL_EVT_UTILS
  *
- * Utility functions for dealing with various tool events. These are
- * free functions, so they interface with any classes exclusively via
- * the public interfaces, so they don't need to be subsumed into the
- * "helped" classes.
+ * Utility functions for dealing with various tool events. These are free functions, so they
+ * interface with any classes exclusively via the public interfaces, so they don't need to be
+ * subsumed into the "helped" classes.
  */
 namespace TOOL_EVT_UTILS
 {
     /**
      * Function IsCancelInteractive()
      *
-     * Indicates the event should restart/end an ongoing interactive tool's
-     * event loop (eg esc key, click cancel, start different tool)
+     * Indicates the event should restart/end an ongoing interactive tool's event loop (eg esc
+     * key, click cancel, start different tool).
      */
     bool IsCancelInteractive( const TOOL_EVENT& aEvt );
 
@@ -670,6 +662,13 @@ namespace TOOL_EVT_UTILS
      */
     bool IsSelectionEvent( const TOOL_EVENT& aEvt );
 
+    /**
+     * Function IsPointEditor
+     *
+     * Indicates if the event is from one of the point editors.  Usually used to allow the
+     * point editor to activate itself without de-activating the current drawing tool.
+     */
+    bool IsPointEditor( const TOOL_EVENT& aEvt );
 }
 
 
diff --git a/pagelayout_editor/tools/pl_drawing_tools.cpp b/pagelayout_editor/tools/pl_drawing_tools.cpp
index 5d71cf7456..1600a830de 100644
--- a/pagelayout_editor/tools/pl_drawing_tools.cpp
+++ b/pagelayout_editor/tools/pl_drawing_tools.cpp
@@ -80,7 +80,7 @@ int PL_DRAWING_TOOLS::PlaceItem( const TOOL_EVENT& aEvent )
     m_toolMgr->RunAction( PL_ACTIONS::clearSelection, true );
     getViewControls()->ShowCursor( true );
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     // Prime the pump
@@ -103,13 +103,9 @@ int PL_DRAWING_TOOLS::PlaceItem( const TOOL_EVENT& aEvent )
                 // There's nothing to roll-back, but we still need to pop the undo stack
                 m_frame->RollbackFromUndo();
             }
-            else
+            else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
             {
-                if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
-                {
-                    m_frame->ClearToolStack();
-                    break;
-                }
+                break;
             }
 
             if( evt->IsActivate() )
@@ -166,6 +162,7 @@ int PL_DRAWING_TOOLS::PlaceItem( const TOOL_EVENT& aEvent )
         getViewControls()->CaptureCursor( item != nullptr );
     }
 
+    m_frame->PopTool();
     return 0;
 }
 
@@ -182,7 +179,7 @@ int PL_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
     m_toolMgr->RunAction( PL_ACTIONS::clearSelection, true );
     getViewControls()->ShowCursor( true );
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     // Prime the pump
@@ -203,16 +200,12 @@ int PL_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
                 item = nullptr;
                 m_frame->RollbackFromUndo();
             }
-            else
+            else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
             {
-                if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
-                {
-                    m_frame->ClearToolStack();
-                    break;
-                }
+                break;
             }
 
-            if( evt->IsActivate() )
+            if( evt->IsActivate() && !TOOL_EVT_UTILS::IsPointEditor( *evt ) )
                 break;
         }
 
@@ -264,6 +257,7 @@ int PL_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
         getViewControls()->CaptureCursor( item != nullptr );
     }
 
+    m_frame->PopTool();
     return 0;
 }
 
diff --git a/pagelayout_editor/tools/pl_edit_tool.cpp b/pagelayout_editor/tools/pl_edit_tool.cpp
index 21c46d2950..ce4f4564b1 100644
--- a/pagelayout_editor/tools/pl_edit_tool.cpp
+++ b/pagelayout_editor/tools/pl_edit_tool.cpp
@@ -290,10 +290,11 @@ bool PL_EDIT_TOOL::updateModificationPoint( PL_SELECTION& aSelection )
 
 int PL_EDIT_TOOL::ImportWorksheetContent( const TOOL_EVENT& aEvent )
 {
+    m_toolMgr->RunAction( ACTIONS::cancelInteractive, true );
+
     wxCommandEvent evt( wxEVT_NULL, ID_APPEND_DESCR_FILE );
     m_frame->Files_io( evt );
 
-    m_frame->ClearToolStack();
     return 0;
 }
 
@@ -354,7 +355,7 @@ static bool deleteItem( PL_EDITOR_FRAME* aFrame, const VECTOR2D& aPosition )
 
 int PL_EDIT_TOOL::DeleteItemCursor( const TOOL_EVENT& aEvent )
 {
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     PL_PICKER_TOOL* picker = m_toolMgr->GetTool<PL_PICKER_TOOL>();
@@ -409,14 +410,12 @@ int PL_EDIT_TOOL::DeleteItemCursor( const TOOL_EVENT& aEvent )
     {
         if( m_pickerItem )
             m_toolMgr->GetTool<PL_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem );
-
-        if( aFinalState == PL_PICKER_TOOL::EVT_CANCEL )
-            m_frame->ClearToolStack();
     } );
 
     picker->Activate();
     Wait();
 
+    m_frame->PopTool();
     return 0;
 }
 
diff --git a/pagelayout_editor/tools/pl_point_editor.cpp b/pagelayout_editor/tools/pl_point_editor.cpp
index 2b1799e9f4..96ebd4e3ff 100644
--- a/pagelayout_editor/tools/pl_point_editor.cpp
+++ b/pagelayout_editor/tools/pl_point_editor.cpp
@@ -217,10 +217,6 @@ int PL_POINT_EDITOR::Main( const TOOL_EVENT& aEvent )
                 modified = false;
             }
 
-            // ESC should clear selection along with edit points
-            if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
-                m_toolMgr->RunAction( PL_ACTIONS::clearSelection, true );
-
             break;
         }
 
diff --git a/pagelayout_editor/tools/pl_selection_tool.cpp b/pagelayout_editor/tools/pl_selection_tool.cpp
index 5b98a237a2..af0436f613 100644
--- a/pagelayout_editor/tools/pl_selection_tool.cpp
+++ b/pagelayout_editor/tools/pl_selection_tool.cpp
@@ -177,7 +177,7 @@ int PL_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
             }
         }
 
-        else if( evt->IsAction( &ACTIONS::cancelInteractive ) || evt->IsCancel() )
+        else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
         {
             ClearSelection();
         }
diff --git a/pcbnew/router/length_tuner_tool.cpp b/pcbnew/router/length_tuner_tool.cpp
index 2f9d44dd87..53ed9629c6 100644
--- a/pcbnew/router/length_tuner_tool.cpp
+++ b/pcbnew/router/length_tuner_tool.cpp
@@ -261,7 +261,7 @@ int LENGTH_TUNER_TOOL::MainLoop( const TOOL_EVENT& aEvent )
     // Deselect all items
     m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
 
-    frame()->SetTool( aEvent.GetCommandStr().get() );
+    frame()->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     m_router->SetMode( aEvent.Parameter<PNS::ROUTER_MODE>() );
@@ -302,6 +302,7 @@ int LENGTH_TUNER_TOOL::MainLoop( const TOOL_EVENT& aEvent )
     m_savedSettings = m_router->Settings();
     m_savedSizes = m_router->Sizes();
 
+    frame()->PopTool();
     return 0;
 }
 
diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp
index 869c394472..3fd160e827 100644
--- a/pcbnew/router/router_tool.cpp
+++ b/pcbnew/router/router_tool.cpp
@@ -861,7 +861,7 @@ int ROUTER_TOOL::MainLoop( const TOOL_EVENT& aEvent )
     // Deselect all items
     m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
 
-    frame->SetTool( aEvent.GetCommandStr().get() );
+    frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     m_router->SetMode( mode );
@@ -883,9 +883,6 @@ int ROUTER_TOOL::MainLoop( const TOOL_EVENT& aEvent )
     {
         if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() )
         {
-            if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
-                frame->ClearToolStack();
-
             break; // Finish
         }
         else if( evt->Action() == TA_UNDO_REDO_PRE )
@@ -944,6 +941,7 @@ int ROUTER_TOOL::MainLoop( const TOOL_EVENT& aEvent )
     m_savedSettings = m_router->Settings();
     m_savedSizes = m_router->Sizes();
 
+    frame->PopTool();
     return 0;
 }
 
@@ -1131,7 +1129,7 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
 
     while( TOOL_EVENT* evt = Wait() )
     {
-        if( evt->IsCancel() )
+        if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
         {
             break;
         }
diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp
index e3bdab23f8..c4593e5e06 100644
--- a/pcbnew/tools/drawing_tool.cpp
+++ b/pcbnew/tools/drawing_tool.cpp
@@ -148,7 +148,7 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
     if( aEvent.HasPosition() )
         startingPoint = getViewControls()->GetCursorPosition( !aEvent.Modifier( MD_ALT ) );
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     while( drawSegment( S_SEGMENT, line, startingPoint ) )
@@ -174,6 +174,7 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
         line->SetFlags( IS_NEW );
     }
 
+    m_frame->PopTool();
     return 0;
 }
 
@@ -194,7 +195,7 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
     if( aEvent.HasPosition() )
         startingPoint = getViewControls()->GetCursorPosition( !aEvent.Modifier( MD_ALT ) );
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     while( drawSegment( S_CIRCLE, circle, startingPoint ) )
@@ -209,6 +210,8 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
 
             commit.Add( circle );
             commit.Push( _( "Draw a circle" ) );
+
+            m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, circle );
         }
 
         circle = m_editModules ? new EDGE_MODULE( module ) : new DRAWSEGMENT;
@@ -216,6 +219,7 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
         startingPoint = NULLOPT;
     }
 
+    m_frame->PopTool();
     return 0;
 }
 
@@ -233,7 +237,7 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
 
     arc->SetFlags( IS_NEW );
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     while( drawArc( arc, immediateMode ) )
@@ -248,6 +252,8 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
 
             commit.Add( arc );
             commit.Push( _( "Draw an arc" ) );
+
+            m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, arc );
         }
 
         arc = m_editModules ? new EDGE_MODULE( module ) : new DRAWSEGMENT;
@@ -255,6 +261,7 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
         immediateMode = false;
     }
 
+    m_frame->PopTool();
     return 0;
 }
 
@@ -268,14 +275,13 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
     const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings();
     BOARD_COMMIT commit( m_frame );
 
-    m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
     m_controls->ShowCursor( true );
     m_controls->SetSnapping( true );
     // do not capture or auto-pan until we start placing some text
 
     SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::TEXT );
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     bool reselect = false;
@@ -308,13 +314,9 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
                 m_controls->CaptureCursor( false );
                 m_controls->ShowCursor( true );
             }
-            else
+            else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
             {
-                if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
-                {
-                    m_frame->ClearToolStack();
-                    break;
-                }
+                break;
             }
 
             if( evt->IsActivate() )
@@ -415,6 +417,8 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
                 commit.Add( text );
                 commit.Push( _( "Place a text" ) );
 
+                m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, text );
+
                 m_controls->CaptureCursor( false );
                 m_controls->SetAutoPan( false );
                 m_controls->ShowCursor( true );
@@ -438,6 +442,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
     }
 
     frame()->SetMsgPanel( board() );
+    m_frame->PopTool();
     return 0;
 }
 
@@ -465,13 +470,12 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
 
     m_view->Add( &preview );
 
-    m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
     m_controls->ShowCursor( true );
     m_controls->SetSnapping( true );
 
     SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::DIMENSION );
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     enum DIMENSION_STEPS
@@ -509,13 +513,9 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
                 delete dimension;
                 step = SET_ORIGIN;
             }
-            else
+            else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
             {
-                if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
-                {
-                    m_frame->ClearToolStack();
-                    break;
-                }
+                break;
             }
 
             if( evt->IsActivate() )
@@ -548,6 +548,8 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
             {
             case SET_ORIGIN:
             {
+                m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
+
                 PCB_LAYER_ID layer = getDrawingLayer();
                 const BOARD_DESIGN_SETTINGS& boardSettings = m_board->GetDesignSettings();
 
@@ -597,6 +599,8 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
 
                     commit.Add( dimension );
                     commit.Push( _( "Draw a dimension" ) );
+
+                    m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, dimension );
                 }
             }
             break;
@@ -650,6 +654,7 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
 
     m_view->Remove( &preview );
     frame()->SetMsgPanel( board() );
+    m_frame->PopTool();
     return 0;
 }
 
@@ -676,7 +681,7 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
         return 0;
     }
 
-    m_frame->ClearToolStack();
+    m_toolMgr->RunAction( ACTIONS::cancelInteractive, true );
 
     // Add a VIEW_GROUP that serves as a preview for the new item
     PCBNEW_SELECTION preview;
@@ -855,7 +860,6 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic, OPT<VECTOR2D
     PCBNEW_SELECTION preview;
     m_view->Add( &preview );
 
-    m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
     m_controls->ShowCursor( true );
 
     bool     direction45 = false;    // 45 degrees only mode
@@ -877,7 +881,10 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic, OPT<VECTOR2D
         m_controls->ForceCursorPosition( true, cursorPos );
 
         // 45 degree angle constraint enabled with an option and toggled with Ctrl
-        const bool limit45 = ( frame()->Settings().m_Use45DegreeGraphicSegments != !!( evt->Modifier( MD_CTRL ) ) );
+        bool limit45 = frame()->Settings().m_Use45DegreeGraphicSegments;
+
+        if( evt->Modifier( MD_CTRL ) )
+            limit45 = !limit45;
 
         if( direction45 != limit45 && started && aShape == S_SEGMENT )
         {
@@ -913,10 +920,6 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic, OPT<VECTOR2D
                 if( !isLocalOriginSet )
                     m_frame->GetScreen()->m_LocalOrigin = VECTOR2D( 0, 0 );
             }
-            else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
-            {
-                m_frame->ClearToolStack();
-            }
 
             break;
         }
@@ -936,6 +939,8 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic, OPT<VECTOR2D
         {
             if( !started )
             {
+                m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
+
                 if( aStartingPoint )
                 {
                     cursorPos = aStartingPoint.get();
@@ -978,17 +983,15 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic, OPT<VECTOR2D
                     //  we finish the segment as they are likely closing a path
                     if( snapItem && aGraphic->GetLength() > 0.0 )
                     {
-                        DRAWSEGMENT* l = m_editModules ? new EDGE_MODULE( mod ) : new DRAWSEGMENT;
-                        l->SetFlags( IS_NEW );
-
-                        *l = *aGraphic;
-                        commit.Add( l );
+                        commit.Add( aGraphic );
+                        commit.Push( _( "Draw a line segment" ) );
+                        m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, aGraphic );
+                    }
+                    else
+                    {
+                        delete aGraphic;
                     }
 
-                    if( !commit.Empty() )
-                        commit.Push( _( "Draw a line" ) );
-
-                    delete aGraphic;
                     aGraphic = nullptr;
                 }
 
@@ -1071,8 +1074,6 @@ static void updateArcFromConstructionMgr( const KIGFX::PREVIEW::ARC_GEOM_MANAGER
 
 bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic, bool aImmediateMode )
 {
-    m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
-
     m_lineWidth = getSegmentWidth( getDrawingLayer() );
 
     // Arc geometric construction manager
@@ -1112,6 +1113,8 @@ bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic, bool aImmediateMode )
         {
             if( !firstPoint )
             {
+                m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
+
                 m_controls->SetAutoPan( true );
                 m_controls->CaptureCursor( true );
 
@@ -1148,10 +1151,6 @@ bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic, bool aImmediateMode )
                 delete aGraphic;
                 aGraphic = nullptr;
             }
-            else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
-            {
-                m_frame->ClearToolStack();
-            }
 
             break;
         }
@@ -1268,10 +1267,7 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
     ZONE_CONTAINER* sourceZone = nullptr;
 
     if( !getSourceZoneForAction( zoneMode, sourceZone ) )
-    {
-        m_frame->ClearToolStack();
         return 0;
-    }
 
     ZONE_CREATE_HELPER::PARAMS params;
 
@@ -1292,7 +1288,7 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
     // hands the calculated points over to the zone creator tool
     POLYGON_GEOM_MANAGER polyGeomMgr( zoneTool );
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();    // register for events
 
     m_controls->ShowCursor( true );
@@ -1333,12 +1329,11 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
             }
             else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
             {
-                m_frame->ClearToolStack();
                 break;
             }
 
             // pre-empted by another tool, give up
-            if( evt->IsActivate() )
+            if( evt->IsActivate() && !TOOL_EVT_UTILS::IsPointEditor( *evt ) )
                 break;
         }
         else if( evt->IsAction( &PCB_ACTIONS::layerChanged ) )
@@ -1419,8 +1414,8 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
         }
     }    // end while
 
-    m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
     m_controls->ForceCursorPosition( false );
+    m_frame->PopTool();
     return 0;
 }
 
@@ -1702,11 +1697,12 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
     VIA_PLACER placer( frame() );
 
     SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::VIA );
-    frame()->SetTool( aEvent.GetCommandStr().get() );
+    frame()->PushTool( aEvent.GetCommandStr().get() );
 
     doInteractiveItemPlacement( &placer, _( "Place via" ),
                                 IPO_REPEAT | IPO_SINGLE_CLICK | IPO_ROTATE | IPO_FLIP );
 
+    frame()->PopTool();
     return 0;
 }
 
diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp
index 5ae9641165..f8a89571de 100644
--- a/pcbnew/tools/edit_tool.cpp
+++ b/pcbnew/tools/edit_tool.cpp
@@ -411,7 +411,7 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
             m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false );
         }
 
-        else if( evt->IsCancel() || evt->IsActivate() )
+        else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() )
         {
             restore_state = true; // Canceling the tool means that items have to be restored
             break;                // Finish
@@ -1107,7 +1107,7 @@ int EDIT_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
     auto& view = *getView();
     auto& controls = *getViewControls();
 
-    frame()->SetTool( aEvent.GetCommandStr().get() );
+    frame()->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     EDA_UNITS_T units = frame()->GetUserUnits();
@@ -1146,7 +1146,6 @@ int EDIT_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
             }
             else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
             {
-                frame()->ClearToolStack();
                 break;
             }
 
@@ -1204,7 +1203,7 @@ int EDIT_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
 
     view.SetVisible( &ruler, false );
     view.Remove( &ruler );
-
+    frame()->PopTool();
     return 0;
 }
 
diff --git a/pcbnew/tools/footprint_editor_tools.cpp b/pcbnew/tools/footprint_editor_tools.cpp
index 6308022512..5f5c66a311 100644
--- a/pcbnew/tools/footprint_editor_tools.cpp
+++ b/pcbnew/tools/footprint_editor_tools.cpp
@@ -313,11 +313,12 @@ int MODULE_EDITOR_TOOLS::PlacePad( const TOOL_EVENT& aEvent )
 
     PAD_PLACER placer;
 
-    frame()->SetTool( aEvent.GetCommandStr().get() );
+    frame()->PushTool( aEvent.GetCommandStr().get() );
 
     doInteractiveItemPlacement( &placer,  _( "Place pad" ),
                                 IPO_REPEAT | IPO_SINGLE_CLICK | IPO_ROTATE | IPO_FLIP );
 
+    frame()->PopTool();
     return 0;
 }
 
diff --git a/pcbnew/tools/microwave_tool.cpp b/pcbnew/tools/microwave_tool.cpp
index ea5e809ba6..a6904423bd 100644
--- a/pcbnew/tools/microwave_tool.cpp
+++ b/pcbnew/tools/microwave_tool.cpp
@@ -117,11 +117,12 @@ int MICROWAVE_TOOL::addMicrowaveFootprint( const TOOL_EVENT& aEvent )
 
     MICROWAVE_PLACER placer( creator );
 
-    frame.SetTool( aEvent.GetCommandStr().get() );
+    frame.PushTool( aEvent.GetCommandStr().get() );
 
     doInteractiveItemPlacement( &placer,  _( "Place microwave feature" ),
                                 IPO_REPEAT | IPO_SINGLE_CLICK | IPO_ROTATE | IPO_FLIP | IPO_PROPERTIES );
 
+    frame.PopTool();
     return 0;
 }
 
@@ -186,7 +187,7 @@ int MICROWAVE_TOOL::drawMicrowaveInductor( const TOOL_EVENT& aEvent )
     KIGFX::VIEW_CONTROLS& controls = *getViewControls();
     auto& frame = *getEditFrame<PCB_EDIT_FRAME>();
 
-    frame.SetTool( aEvent.GetCommandStr().get() );
+    frame.PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     TWO_POINT_GEOMETRY_MANAGER tpGeomMgr;
@@ -225,7 +226,6 @@ int MICROWAVE_TOOL::drawMicrowaveInductor( const TOOL_EVENT& aEvent )
             }
             else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
             {
-                frame.ClearToolStack();
                 break;
             }
 
@@ -282,7 +282,7 @@ int MICROWAVE_TOOL::drawMicrowaveInductor( const TOOL_EVENT& aEvent )
     controls.CaptureCursor( false );
     controls.SetAutoPan( false );
     view.Remove( &previewRect );
-
+    frame.PopTool();
     return 0;
 }
 
diff --git a/pcbnew/tools/pad_tool.cpp b/pcbnew/tools/pad_tool.cpp
index 71700bee3d..ea622c8c0b 100644
--- a/pcbnew/tools/pad_tool.cpp
+++ b/pcbnew/tools/pad_tool.cpp
@@ -469,21 +469,19 @@ int PAD_TOOL::EnumeratePads( const TOOL_EVENT& aEvent )
             break;
         }
 
-        // This is a cancel-current-action (ie: <esc>).
-        // Note that this must go before IsCancelInteractive() as it also checks IsCancel().
-        else if( evt->IsCancel() )
-        {
-            // Clear current selection list to avoid selection of deleted items
-            m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
-
-            commit.Revert();
-            break;
-        }
-
-        // Now that cancel-current-action has been handled, check for cancel-tool.
         else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() )
         {
-            commit.Push( _( "Renumber pads" ) );
+            // This is a cancel-current-action (ie: <esc>).
+            if( evt->IsCancel() )
+            {
+                m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
+                commit.Revert();
+            }
+            else
+            {
+                commit.Push( _( "Renumber pads" ) );
+            }
+
             break;
         }
 
diff --git a/pcbnew/tools/pcb_editor_control.cpp b/pcbnew/tools/pcb_editor_control.cpp
index 76870b8af4..24c927925f 100644
--- a/pcbnew/tools/pcb_editor_control.cpp
+++ b/pcbnew/tools/pcb_editor_control.cpp
@@ -518,7 +518,7 @@ int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent )
     controls->ShowCursor( true );
     controls->SetSnapping( true );
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     VECTOR2I cursorPos = controls->GetCursorPosition();
@@ -551,13 +551,9 @@ int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent )
                 commit.Revert();
                 module = NULL;
             }
-            else
+            else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
             {
-                if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
-                {
-                    m_frame->ClearToolStack();
-                    break;
-                }
+                break;
             }
 
             if( evt->IsActivate() )  // now finish unconditionally
@@ -626,7 +622,6 @@ int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent )
     }
 
     m_frame->PopTool();
-
     return 0;
 }
 
@@ -716,7 +711,7 @@ int PCB_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent )
     m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
     controls->SetSnapping( true );
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     // Main loop: keep receiving events
@@ -728,9 +723,6 @@ int PCB_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent )
 
         if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() )
         {
-            if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
-                m_frame->ClearToolStack();
-
             break;
         }
 
@@ -780,9 +772,9 @@ int PCB_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent )
     }
 
     delete target;
-
-    controls->SetSnapping( false );
     view->Remove( &preview );
+    controls->SetSnapping( false );
+    m_frame->PopTool();
     return 0;
 }
 
@@ -966,7 +958,7 @@ void PCB_EDITOR_CONTROL::DoSetDrillOrigin( KIGFX::VIEW* aView, PCB_BASE_FRAME* a
 
 int PCB_EDITOR_CONTROL::DrillOrigin( const TOOL_EVENT& aEvent )
 {
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     PCBNEW_PICKER_TOOL* picker = m_toolMgr->GetTool<PCBNEW_PICKER_TOOL>();
@@ -982,7 +974,7 @@ int PCB_EDITOR_CONTROL::DrillOrigin( const TOOL_EVENT& aEvent )
     picker->Activate();
     Wait();
 
-    m_frame->ClearToolStack();
+    m_frame->PopTool();
     return 0;
 }
 
@@ -1153,7 +1145,7 @@ int PCB_EDITOR_CONTROL::HighlightNetCursor( const TOOL_EVENT& aEvent )
         highlightNet( getViewControls()->GetMousePosition(), use_selection );
     }
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     PCBNEW_PICKER_TOOL* picker = m_toolMgr->GetTool<PCBNEW_PICKER_TOOL>();
@@ -1164,16 +1156,11 @@ int PCB_EDITOR_CONTROL::HighlightNetCursor( const TOOL_EVENT& aEvent )
             return true;
         } );
 
-    picker->SetFinalizeHandler( [&]( const int& aFinalState )
-        {
-            if( aFinalState == PCBNEW_PICKER_TOOL::EVT_CANCEL )
-                m_frame->ClearToolStack();
-        } );
-
     picker->SetLayerSet( LSET::AllCuMask() );
     picker->Activate();
     Wait();
 
+    m_frame->PopTool();
     return 0;
 }
 
@@ -1227,7 +1214,7 @@ static bool showLocalRatsnest( TOOL_MANAGER* aToolMgr, BOARD* aBoard, bool aShow
 
 int PCB_EDITOR_CONTROL::LocalRatsnestTool( const TOOL_EVENT& aEvent )
 {
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     auto picker = m_toolMgr->GetTool<PCBNEW_PICKER_TOOL>();
@@ -1249,14 +1236,12 @@ int PCB_EDITOR_CONTROL::LocalRatsnestTool( const TOOL_EVENT& aEvent )
                         pad->SetLocalRatsnestVisible( opt->m_ShowGlobalRatsnest );
                 }
             }
-
-            if( aCondition == PCBNEW_PICKER_TOOL::EVT_CANCEL )
-                m_frame->ClearToolStack();
         } );
 
     picker->Activate();
     Wait();
 
+    m_frame->PopTool();
     return 0;
 }
 
@@ -1404,6 +1389,7 @@ void PCB_EDITOR_CONTROL::setTransitions()
     Go( &PCB_EDITOR_CONTROL::ClearHighlight,         PCB_ACTIONS::clearHighlight.MakeEvent() );
     Go( &PCB_EDITOR_CONTROL::HighlightNetCursor,     PCB_ACTIONS::highlightNetTool.MakeEvent() );
     Go( &PCB_EDITOR_CONTROL::HighlightNetCursor,     PCB_ACTIONS::highlightNetSelection.MakeEvent() );
+    Go( &PCB_EDITOR_CONTROL::ClearHighlight,         ACTIONS::cancelInteractive.MakeEvent() );
 
     Go( &PCB_EDITOR_CONTROL::LocalRatsnestTool,      PCB_ACTIONS::localRatsnestTool.MakeEvent() );
     Go( &PCB_EDITOR_CONTROL::HideDynamicRatsnest,    PCB_ACTIONS::hideDynamicRatsnest.MakeEvent() );
diff --git a/pcbnew/tools/pcb_tool_base.cpp b/pcbnew/tools/pcb_tool_base.cpp
index dce2938924..aa7e849f89 100644
--- a/pcbnew/tools/pcb_tool_base.cpp
+++ b/pcbnew/tools/pcb_tool_base.cpp
@@ -85,21 +85,15 @@ void PCB_TOOL_BASE::doInteractiveItemPlacement( INTERACTIVE_PLACER_BASE* aPlacer
 
                 preview.Clear();
 
-                if( aOptions & IPO_SINGLE_CLICK )
-                {
-                    frame()->ClearToolStack();
-                    break;
-                }
-
                 controls()->SetAutoPan( false );
                 controls()->CaptureCursor( false );
                 controls()->ShowCursor( true );
-            }
-            else
-            {
-                if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
-                    frame()->ClearToolStack();
 
+                if( aOptions & IPO_SINGLE_CLICK )
+                    break;
+            }
+            else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
+            {
                 break;
             }
 
diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp
index 1395e7752c..395fcd8ba0 100644
--- a/pcbnew/tools/pcbnew_control.cpp
+++ b/pcbnew/tools/pcbnew_control.cpp
@@ -456,7 +456,7 @@ int PCBNEW_CONTROL::GridSetOrigin( const TOOL_EVENT& aEvent )
     }
     else
     {
-        m_frame->SetTool( aEvent.GetCommandStr().get() );
+        m_frame->PushTool( aEvent.GetCommandStr().get() );
         Activate();
 
         PCBNEW_PICKER_TOOL* picker = m_toolMgr->GetTool<PCBNEW_PICKER_TOOL>();
@@ -471,7 +471,7 @@ int PCBNEW_CONTROL::GridSetOrigin( const TOOL_EVENT& aEvent )
         picker->Activate();
         Wait();
 
-        m_frame->ClearToolStack();
+        m_frame->PopTool();
     }
 
     return 0;
@@ -514,7 +514,7 @@ int PCBNEW_CONTROL::DeleteItemCursor( const TOOL_EVENT& aEvent )
 {
     m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
 
-    m_frame->SetTool( aEvent.GetCommandStr().get() );
+    m_frame->PushTool( aEvent.GetCommandStr().get() );
     Activate();
 
     PCBNEW_PICKER_TOOL* picker = m_toolMgr->GetTool<PCBNEW_PICKER_TOOL>();
@@ -575,14 +575,12 @@ int PCBNEW_CONTROL::DeleteItemCursor( const TOOL_EVENT& aEvent )
     {
         if( m_pickerItem )
             m_toolMgr->GetTool<SELECTION_TOOL>()->UnbrightenItem( m_pickerItem );
-
-        if( aFinalState == PCBNEW_PICKER_TOOL::EVT_CANCEL )
-            m_frame->ClearToolStack();
     } );
 
     picker->Activate();
     Wait();
 
+    m_frame->PopTool();
     return 0;
 }
 
diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp
index 98e13efda0..d40ea09fb5 100644
--- a/pcbnew/tools/point_editor.cpp
+++ b/pcbnew/tools/point_editor.cpp
@@ -387,10 +387,6 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
             if( inDrag )      // Restore the last change
                 commit.Revert();
 
-            // ESC should clear selection along with edit points
-            if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
-                m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
-
             break;
         }
 
diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp
index 98e2832c96..042b5d73c9 100644
--- a/pcbnew/tools/selection_tool.cpp
+++ b/pcbnew/tools/selection_tool.cpp
@@ -185,15 +185,6 @@ void SELECTION_TOOL::Reset( RESET_REASON aReason )
 }
 
 
-int SELECTION_TOOL::SelectionTool( const TOOL_EVENT& aEvent )
-{
-    // Since the selection tool is always running underneath the toolStack, all we need to
-    // do is clear the stack.
-    m_frame->ClearToolStack();
-    return 0;
-}
-
-
 int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
 {
     // Main loop: keep receiving events
@@ -291,17 +282,11 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
             }
         }
 
-        else if( evt->Action() == TA_UNDO_REDO_PRE )
+        else if( evt->IsCancel() || evt->Action() == TA_UNDO_REDO_PRE)
         {
             clearSelection();
         }
 
-        else if( evt->IsCancel() )
-        {
-            clearSelection();
-            m_toolMgr->RunAction( PCB_ACTIONS::clearHighlight, true );
-        }
-
         else
             evt->SetPassEvent();
     }
@@ -2219,7 +2204,6 @@ void SELECTION_TOOL::setTransitions()
     Go( &SELECTION_TOOL::UpdateMenu,          ACTIONS::updateMenu.MakeEvent() );
 
     Go( &SELECTION_TOOL::Main,                PCB_ACTIONS::selectionActivate.MakeEvent() );
-    Go( &SELECTION_TOOL::SelectionTool,       ACTIONS::selectionTool.MakeEvent() );
     Go( &SELECTION_TOOL::CursorSelection,     PCB_ACTIONS::selectionCursor.MakeEvent() );
     Go( &SELECTION_TOOL::ClearSelection,      PCB_ACTIONS::selectionClear.MakeEvent() );
 
diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h
index 19006f4d45..fe987d9b97 100644
--- a/pcbnew/tools/selection_tool.h
+++ b/pcbnew/tools/selection_tool.h
@@ -79,8 +79,6 @@ public:
      */
     int Main( const TOOL_EVENT& aEvent );
 
-    int SelectionTool( const TOOL_EVENT& aEvent );
-
     /**
      * Function GetSelection()
      *
diff --git a/pcbnew/tools/zone_create_helper.cpp b/pcbnew/tools/zone_create_helper.cpp
index e9b5afc0cc..1fc024cb1d 100644
--- a/pcbnew/tools/zone_create_helper.cpp
+++ b/pcbnew/tools/zone_create_helper.cpp
@@ -183,8 +183,9 @@ void ZONE_CREATE_HELPER::commitZone( std::unique_ptr<ZONE_CONTAINER> aZone )
                 filler.Fill( { aZone.get() } );
             }
 
-            bCommit.Add( aZone.release() );
+            bCommit.Add( aZone.get() );
             bCommit.Push( _( "Add a zone" ) );
+            m_tool.GetManager()->RunAction( PCB_ACTIONS::selectItem, true, aZone.release() );
             break;
         }
 
@@ -202,6 +203,7 @@ void ZONE_CREATE_HELPER::commitZone( std::unique_ptr<ZONE_CONTAINER> aZone )
                 poly->SetLayer( m_tool.getDrawingLayer() );
                 poly->SetPolyShape ( *aZone->Outline() );
                 bCommit.Add( poly );
+                m_tool.GetManager()->RunAction( PCB_ACTIONS::selectItem, true, poly );
             }
             else
             {
@@ -235,6 +237,8 @@ bool ZONE_CREATE_HELPER::OnFirstPoint( POLYGON_GEOM_MANAGER& aMgr )
     // of the preview
     if( !m_zone )
     {
+        m_tool.GetManager()->RunAction( PCB_ACTIONS::selectionClear, true );
+
         if( m_params.m_sourceZone )
             m_zone = createZoneFromExisting( *m_params.m_sourceZone );
         else