From 05bca282f7a0dc7543a3b390a21d29f5532e575b Mon Sep 17 00:00:00 2001
From: Jeff Young <jeff@rokeby.ie>
Date: Thu, 17 Mar 2022 15:26:49 +0000
Subject: [PATCH] Re-entrancy blocker for line/wire/bus tool.

Also clear infobar messages after a cancelInteractive.

Fixes https://gitlab.com/kicad/code/kicad/issues/11155
---
 eeschema/tools/sch_drawing_tools.cpp           |  8 ++++++++
 eeschema/tools/sch_line_wire_bus_tool.cpp      | 15 ++++++++++++++-
 eeschema/tools/sch_line_wire_bus_tool.h        |  7 +++----
 eeschema/tools/sch_move_tool.cpp               |  3 +++
 eeschema/tools/symbol_editor_drawing_tools.cpp |  2 ++
 pagelayout_editor/tools/pl_edit_tool.cpp       |  3 +++
 6 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/eeschema/tools/sch_drawing_tools.cpp b/eeschema/tools/sch_drawing_tools.cpp
index a23eda248f..c370034db1 100644
--- a/eeschema/tools/sch_drawing_tools.cpp
+++ b/eeschema/tools/sch_drawing_tools.cpp
@@ -197,6 +197,8 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
 
         if( evt->IsCancelInteractive() )
         {
+            m_frame->GetInfoBar()->Dismiss();
+
             if( symbol )
             {
                 cleanup();
@@ -435,6 +437,8 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
 
         if( evt->IsCancelInteractive() )
         {
+            m_frame->GetInfoBar()->Dismiss();
+
             if( image )
             {
                 cleanup();
@@ -1124,6 +1128,8 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
 
         if( evt->IsCancelInteractive() )
         {
+            m_frame->GetInfoBar()->Dismiss();
+
             if( item )
             {
                 cleanup();
@@ -1535,6 +1541,8 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
 
         if( evt->IsCancelInteractive() )
         {
+            m_frame->GetInfoBar()->Dismiss();
+
             if( sheet )
             {
                 cleanup();
diff --git a/eeschema/tools/sch_line_wire_bus_tool.cpp b/eeschema/tools/sch_line_wire_bus_tool.cpp
index 9aa71a1e57..127bbfe903 100644
--- a/eeschema/tools/sch_line_wire_bus_tool.cpp
+++ b/eeschema/tools/sch_line_wire_bus_tool.cpp
@@ -163,7 +163,8 @@ private:
 
 
 SCH_LINE_WIRE_BUS_TOOL::SCH_LINE_WIRE_BUS_TOOL() :
-    EE_TOOL_BASE<SCH_EDIT_FRAME>( "eeschema.InteractiveDrawingLineWireBus" )
+    EE_TOOL_BASE<SCH_EDIT_FRAME>( "eeschema.InteractiveDrawingLineWireBus" ),
+    m_inDrawingTool( false )
 {
     m_busUnfold = {};
     m_wires.reserve( 16 );
@@ -278,6 +279,11 @@ bool SCH_LINE_WIRE_BUS_TOOL::IsDrawingLineWireOrBus( const SELECTION& aSelection
 
 int SCH_LINE_WIRE_BUS_TOOL::DrawSegments( const TOOL_EVENT& aEvent )
 {
+    if( m_inDrawingTool )
+        return 0;
+
+    REENTRANCY_GUARD guard( &m_inDrawingTool );
+
     DRAW_SEGMENT_EVENT_PARAMS* params = aEvent.Parameter<DRAW_SEGMENT_EVENT_PARAMS*>();
 
     std::string tool = aEvent.GetCommandStr().get();
@@ -300,6 +306,11 @@ int SCH_LINE_WIRE_BUS_TOOL::DrawSegments( const TOOL_EVENT& aEvent )
 
 int SCH_LINE_WIRE_BUS_TOOL::UnfoldBus( const TOOL_EVENT& aEvent )
 {
+    if( m_inDrawingTool )
+        return 0;
+
+    REENTRANCY_GUARD guard( &m_inDrawingTool );
+
     wxString* netPtr = aEvent.Parameter<wxString*>();
     wxString  net;
     SCH_LINE* segment = nullptr;
@@ -591,6 +602,8 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
         //
         if( evt->IsCancelInteractive() )
         {
+            m_frame->GetInfoBar()->Dismiss();
+
             if( segment || m_busUnfold.in_progress )
             {
                 cleanup();
diff --git a/eeschema/tools/sch_line_wire_bus_tool.h b/eeschema/tools/sch_line_wire_bus_tool.h
index 2b35f19787..588d3f6ef7 100644
--- a/eeschema/tools/sch_line_wire_bus_tool.h
+++ b/eeschema/tools/sch_line_wire_bus_tool.h
@@ -134,11 +134,10 @@ private:
     void computeBreakPoint( const std::pair<SCH_LINE*, SCH_LINE*>& aSegments, VECTOR2I& aPosition );
 
 private:
-    /// Data related to bus unfolding tool.
-    BUS_UNFOLDING_T         m_busUnfold;
+    bool                    m_inDrawingTool;   // Reentrancy guard
 
-    /// Storage for the line segments while drawing
-    std::vector<SCH_LINE*>   m_wires;
+    BUS_UNFOLDING_T         m_busUnfold;
+    std::vector<SCH_LINE*>  m_wires;           // Lines being drawn
 };
 
 #endif /* SCH_LINE_WIRE_BUS_TOOL_H */
diff --git a/eeschema/tools/sch_move_tool.cpp b/eeschema/tools/sch_move_tool.cpp
index 4ec91b5348..ddead26039 100644
--- a/eeschema/tools/sch_move_tool.cpp
+++ b/eeschema/tools/sch_move_tool.cpp
@@ -719,6 +719,9 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
         //
         else if( evt->IsCancelInteractive() || evt->IsActivate() )
         {
+            if( evt->IsCancelInteractive() )
+                m_frame->GetInfoBar()->Dismiss();
+
             if( m_moveInProgress )
             {
                 if( evt->IsActivate() )
diff --git a/eeschema/tools/symbol_editor_drawing_tools.cpp b/eeschema/tools/symbol_editor_drawing_tools.cpp
index ee77421e38..15ad0da118 100644
--- a/eeschema/tools/symbol_editor_drawing_tools.cpp
+++ b/eeschema/tools/symbol_editor_drawing_tools.cpp
@@ -137,6 +137,8 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
 
         if( evt->IsCancelInteractive() )
         {
+            m_frame->GetInfoBar()->Dismiss();
+
             if( item )
             {
                 cleanup();
diff --git a/pagelayout_editor/tools/pl_edit_tool.cpp b/pagelayout_editor/tools/pl_edit_tool.cpp
index ffd2fde7f4..6ba0a4b248 100644
--- a/pagelayout_editor/tools/pl_edit_tool.cpp
+++ b/pagelayout_editor/tools/pl_edit_tool.cpp
@@ -204,6 +204,9 @@ int PL_EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
         //
         else if( evt->IsCancelInteractive() || evt->IsActivate() )
         {
+            if( evt->IsCancelInteractive() )
+                m_frame->GetInfoBar()->Dismiss();
+
             if( m_moveInProgress )
             {
                 if( evt->IsActivate() )