From aefebbf1b0f112a9da4299c08bf1a3a41ecbfe7a Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Thu, 10 Jul 2025 16:49:04 +0100 Subject: [PATCH] Upgrade ShowPlayer re-entrancy guard (KICAD-XAC). (cherry picked from commit 53c90b04692a64390cf329635d05409806097f23) --- common/dialogs/panel_embedded_files.cpp | 6 ++--- common/dialogs/panel_setup_netclasses.cpp | 4 +-- common/widgets/search_pane_tab.cpp | 6 ++--- common/widgets/widget_hotkey_list.cpp | 8 +++--- .../dialog_design_block_properties.cpp | 4 +-- eeschema/dialogs/dialog_erc.cpp | 4 +-- eeschema/net_navigator.cpp | 8 +++--- eeschema/widgets/hierarchy_pane.cpp | 5 ++-- kicad/project_tree_pane.cpp | 25 +++++++++++-------- libs/core/include/core/raii.h | 20 +++++++++++++++ pagelayout_editor/tools/pl_editor_control.cpp | 5 +--- pcbnew/footprint_wizard_frame.cpp | 9 ++----- pcbnew/pcb_layer_box_selector.cpp | 18 ++++++------- pcbnew/zone_manager/dialog_zone_manager.cpp | 3 +-- 14 files changed, 67 insertions(+), 58 deletions(-) diff --git a/common/dialogs/panel_embedded_files.cpp b/common/dialogs/panel_embedded_files.cpp index 55de074d6f..57a0608612 100644 --- a/common/dialogs/panel_embedded_files.cpp +++ b/common/dialogs/panel_embedded_files.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -209,7 +210,8 @@ bool PANEL_EMBEDDED_FILES::TransferDataFromWindow() void PANEL_EMBEDDED_FILES::onFontEmbedClick( wxCommandEvent& event ) { - Freeze(); + WINDOW_FREEZER raiiFreezer( this ); + int row_pos = m_files_grid->GetGridCursorRow(); int col_pos = m_files_grid->GetGridCursorCol(); wxString row_name; @@ -269,8 +271,6 @@ void PANEL_EMBEDDED_FILES::onFontEmbedClick( wxCommandEvent& event ) } } } - - Thaw(); } diff --git a/common/dialogs/panel_setup_netclasses.cpp b/common/dialogs/panel_setup_netclasses.cpp index a238f8cce5..aed76c5217 100644 --- a/common/dialogs/panel_setup_netclasses.cpp +++ b/common/dialogs/panel_setup_netclasses.cpp @@ -116,7 +116,8 @@ PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( wxWindow* aParentWindow, EDA_DRA m_membershipPane->SetBorders( true, false, false, false ); // Prevent Size events from firing before we are ready - Freeze(); + WINDOW_FREEZER raiiFreezer( this ); + m_netclassGrid->BeginBatch(); m_netclassGrid->SetUseNativeColLabels(); m_assignmentGrid->BeginBatch(); @@ -243,7 +244,6 @@ PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( wxWindow* aParentWindow, EDA_DRA m_netclassGrid->EndBatch(); m_assignmentGrid->EndBatch(); - Thaw(); Bind( wxEVT_IDLE, [this]( wxIdleEvent& aEvent ) diff --git a/common/widgets/search_pane_tab.cpp b/common/widgets/search_pane_tab.cpp index de6906160e..9fb87239f4 100644 --- a/common/widgets/search_pane_tab.cpp +++ b/common/widgets/search_pane_tab.cpp @@ -24,6 +24,7 @@ #include #include #include +#include SEARCH_PANE_LISTVIEW::SEARCH_PANE_LISTVIEW( SEARCH_HANDLER* handler, wxWindow* parent, wxWindowID winid, const wxPoint& pos, @@ -203,7 +204,8 @@ std::vector SEARCH_PANE_LISTVIEW::Sort() void SEARCH_PANE_LISTVIEW::RefreshColumnNames() { - Freeze(); + WINDOW_FREEZER raiiFreezer( this ); + DeleteAllColumns(); std::vector> columns = m_handler->GetColumns(); @@ -215,8 +217,6 @@ void SEARCH_PANE_LISTVIEW::RefreshColumnNames() for( int ii = 0; ii < (int) columns.size(); ++ii ) SetColumnWidth( ii, widthUnit * std::get<1>( columns[ ii ] ) ); - - Thaw(); } diff --git a/common/widgets/widget_hotkey_list.cpp b/common/widgets/widget_hotkey_list.cpp index 133dea2a4f..c07be6794f 100644 --- a/common/widgets/widget_hotkey_list.cpp +++ b/common/widgets/widget_hotkey_list.cpp @@ -585,7 +585,7 @@ void WIDGET_HOTKEY_LIST::ApplyFilterString( const wxString& aFilterStr ) void WIDGET_HOTKEY_LIST::ResetAllHotkeys( bool aResetToDefault ) { - Freeze(); + WINDOW_FREEZER raiiFreezer( this ); // Reset all the hotkeys, not just the ones shown // Should not need to check conflicts, as the state we're about @@ -597,8 +597,6 @@ void WIDGET_HOTKEY_LIST::ResetAllHotkeys( bool aResetToDefault ) updateFromClientData(); updateColumnWidths(); - - Thaw(); } @@ -633,7 +631,8 @@ void WIDGET_HOTKEY_LIST::updateColumnWidths() void WIDGET_HOTKEY_LIST::updateShownItems( const wxString& aFilterStr ) { - Freeze(); + WINDOW_FREEZER raiiFreezer( this ); + DeleteAllItems(); HOTKEY_FILTER filter( aFilterStr ); @@ -656,7 +655,6 @@ void WIDGET_HOTKEY_LIST::updateShownItems( const wxString& aFilterStr ) } updateFromClientData(); - Thaw(); } diff --git a/eeschema/dialogs/dialog_design_block_properties.cpp b/eeschema/dialogs/dialog_design_block_properties.cpp index 93fff67735..efeffb2a81 100644 --- a/eeschema/dialogs/dialog_design_block_properties.cpp +++ b/eeschema/dialogs/dialog_design_block_properties.cpp @@ -208,7 +208,7 @@ void DIALOG_DESIGN_BLOCK_PROPERTIES::OnMoveFieldDown( wxCommandEvent& event ) bool DIALOG_DESIGN_BLOCK_PROPERTIES::TransferDataToGrid() { - m_fieldsGrid->Freeze(); + WINDOW_FREEZER raiiFreezer( m_fieldsGrid ); m_fieldsGrid->ClearRows(); m_fieldsGrid->AppendRows( m_fields.size() ); @@ -227,8 +227,6 @@ bool DIALOG_DESIGN_BLOCK_PROPERTIES::TransferDataToGrid() row++; } - m_fieldsGrid->Thaw(); - return true; } diff --git a/eeschema/dialogs/dialog_erc.cpp b/eeschema/dialogs/dialog_erc.cpp index 92dd0d610e..4446bb90de 100644 --- a/eeschema/dialogs/dialog_erc.cpp +++ b/eeschema/dialogs/dialog_erc.cpp @@ -1021,14 +1021,14 @@ void DIALOG_ERC::deleteAllMarkers( bool aIncludeExclusions ) // Clear current selection list to avoid selection of deleted items // Freeze to avoid repainting the dialog, which can cause a RePaint() // of the screen as well - Freeze(); + WINDOW_FREEZER raiiFreezer( this ); + m_parent->GetToolManager()->RunAction( SCH_ACTIONS::clearSelection ); m_markerTreeModel->DeleteItems( false, aIncludeExclusions, false ); SCH_SCREENS screens( m_parent->Schematic().Root() ); screens.DeleteAllMarkers( MARKER_BASE::MARKER_ERC, aIncludeExclusions ); - Thaw(); } diff --git a/eeschema/net_navigator.cpp b/eeschema/net_navigator.cpp index ba24317e59..0b0f90e28a 100644 --- a/eeschema/net_navigator.cpp +++ b/eeschema/net_navigator.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -306,9 +307,8 @@ void SCH_EDIT_FRAME::RefreshNetNavigator( const NET_NAVIGATOR_ITEM_DATA* aSelect bool singleSheetSchematic = m_schematic->Hierarchy().size() == 1; size_t nodeCnt = 0; - m_netNavigator->Freeze(); - - PROF_TIMER timer; + WINDOW_FREEZER raiiFreezer( m_netNavigator ); + PROF_TIMER timer; if( m_highlightedConn.IsEmpty() ) { @@ -376,8 +376,6 @@ void SCH_EDIT_FRAME::RefreshNetNavigator( const NET_NAVIGATOR_ITEM_DATA* aSelect wxLogTrace( traceUiProfile, wxS( "Adding %zu nodes to net navigator took %s." ), nodeCnt, timer.to_string() ); - - m_netNavigator->Thaw(); } diff --git a/eeschema/widgets/hierarchy_pane.cpp b/eeschema/widgets/hierarchy_pane.cpp index ab281f8f93..7a539bb9e7 100644 --- a/eeschema/widgets/hierarchy_pane.cpp +++ b/eeschema/widgets/hierarchy_pane.cpp @@ -24,6 +24,7 @@ */ #include +#include #include #include #include @@ -211,7 +212,7 @@ void HIERARCHY_PANE::UpdateHierarchySelection() void HIERARCHY_PANE::UpdateHierarchyTree( bool aClear ) { - Freeze(); + WINDOW_FREEZER raiiFreezer( this ); bool eventsWereBound = m_events_bound; @@ -303,8 +304,6 @@ void HIERARCHY_PANE::UpdateHierarchyTree( bool aClear ) m_events_bound = true; } - - Thaw(); } diff --git a/kicad/project_tree_pane.cpp b/kicad/project_tree_pane.cpp index 0728b7299c..e8043e9981 100644 --- a/kicad/project_tree_pane.cpp +++ b/kicad/project_tree_pane.cpp @@ -632,8 +632,10 @@ void PROJECT_TREE_PANE::ReCreateTreePrj() if( !m_TreeProject ) m_TreeProject = new PROJECT_TREE( this ); - else - m_TreeProject->DeleteAllItems(); + + WINDOW_FREEZER raiiFreezer( m_TreeProject ); + + m_TreeProject->DeleteAllItems(); if( !pro_dir ) // This is empty from PROJECT_TREE_PANE constructor return; @@ -689,8 +691,8 @@ void PROJECT_TREE_PANE::ReCreateTreePrj() m_TreeProject->SetItemBold( m_root, true ); // The main project file is now a JSON file - PROJECT_TREE_ITEM* data = new PROJECT_TREE_ITEM( TREE_FILE_TYPE::JSON_PROJECT, - fn.GetFullPath(), m_TreeProject ); + PROJECT_TREE_ITEM* data = new PROJECT_TREE_ITEM( TREE_FILE_TYPE::JSON_PROJECT, fn.GetFullPath(), + m_TreeProject ); m_TreeProject->SetItemData( m_root, data ); @@ -731,12 +733,13 @@ void PROJECT_TREE_PANE::ReCreateTreePrj() // Sort filenames by alphabetic order m_TreeProject->SortChildren( m_root ); - CallAfter( [this] () - { - wxLogTrace( traceGit, "PROJECT_TREE_PANE::ReCreateTreePrj: starting timers" ); - m_gitSyncTimer.Start( 100, wxTIMER_ONE_SHOT ); - m_gitStatusTimer.Start( 500, wxTIMER_ONE_SHOT ); - } ); + CallAfter( + [this] () + { + wxLogTrace( traceGit, "PROJECT_TREE_PANE::ReCreateTreePrj: starting timers" ); + m_gitSyncTimer.Start( 100, wxTIMER_ONE_SHOT ); + m_gitStatusTimer.Start( 500, wxTIMER_ONE_SHOT ); + } ); } @@ -1579,6 +1582,8 @@ void PROJECT_TREE_PANE::EmptyTreePrj() // Make sure we don't try to inspect the tree after we've deleted its items. shutdownFileWatcher(); + m_TreeProject->Freeze(); + m_TreeProject->DeleteAllItems(); // Remove the git repository when the project is unloaded diff --git a/libs/core/include/core/raii.h b/libs/core/include/core/raii.h index d4aaedd848..14d8067f1d 100644 --- a/libs/core/include/core/raii.h +++ b/libs/core/include/core/raii.h @@ -82,6 +82,26 @@ protected: }; +// Temporarily freeze a window, and then un-freeze on destruction +class WINDOW_FREEZER +{ +public: + WINDOW_FREEZER( wxWindow* aWindow ) + { + m_window = aWindow; + m_window->Freeze(); + } + + ~WINDOW_FREEZER() + { + m_window->Thaw(); + } + +protected: + wxWindow* m_window; +}; + + /// Temporarily disable a window, and then re-enable on destruction. class WINDOW_DISABLER { diff --git a/pagelayout_editor/tools/pl_editor_control.cpp b/pagelayout_editor/tools/pl_editor_control.cpp index 201986be1b..f980b1a69e 100644 --- a/pagelayout_editor/tools/pl_editor_control.cpp +++ b/pagelayout_editor/tools/pl_editor_control.cpp @@ -149,7 +149,7 @@ int PL_EDITOR_CONTROL::UpdateMessagePanel( const TOOL_EVENT& aEvent ) PL_SELECTION& selection = selTool->GetSelection(); // The Properties frame will be updated. Avoid flicker during update: - m_frame->GetPropertiesFrame()->Freeze(); + WINDOW_FREEZER raiiFreezer( m_frame->GetPropertiesFrame() ); if( selection.GetSize() == 1 ) { @@ -173,9 +173,6 @@ int PL_EDITOR_CONTROL::UpdateMessagePanel( const TOOL_EVENT& aEvent ) m_frame->GetPropertiesFrame()->CopyPrmsFromGeneralToPanel(); - // The Properties frame is updated. Reenable it: - m_frame->GetPropertiesFrame()->Thaw(); - return 0; } diff --git a/pcbnew/footprint_wizard_frame.cpp b/pcbnew/footprint_wizard_frame.cpp index cc17d18593..df2650dba3 100644 --- a/pcbnew/footprint_wizard_frame.cpp +++ b/pcbnew/footprint_wizard_frame.cpp @@ -380,7 +380,7 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateParameterList() if( footprintWizard == nullptr ) return; - m_parameterGrid->Freeze(); + WINDOW_FREEZER raiiFreezer( m_parameterGrid ); m_parameterGrid->ClearGrid(); m_parameterGridPage = m_pageList->GetSelection(); @@ -429,12 +429,9 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateParameterList() wxArrayString options; while( tokenizer.HasMoreTokens() ) - { options.Add( tokenizer.GetNextToken() ); - } - m_parameterGrid->SetCellEditor( i, WIZ_COL_VALUE, - new wxGridCellChoiceEditor( options ) ); + m_parameterGrid->SetCellEditor( i, WIZ_COL_VALUE, new wxGridCellChoiceEditor( options ) ); units = wxT( "" ); } @@ -466,8 +463,6 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateParameterList() } ResizeParamColumns(); - - m_parameterGrid->Thaw(); } void FOOTPRINT_WIZARD_FRAME::ResizeParamColumns() diff --git a/pcbnew/pcb_layer_box_selector.cpp b/pcbnew/pcb_layer_box_selector.cpp index 9a93f4ba00..f1bccff02b 100644 --- a/pcbnew/pcb_layer_box_selector.cpp +++ b/pcbnew/pcb_layer_box_selector.cpp @@ -32,16 +32,16 @@ #include #include #include +#include -PCB_LAYER_BOX_SELECTOR::PCB_LAYER_BOX_SELECTOR( wxWindow* parent, wxWindowID id, - const wxString& value, const wxPoint& pos, - const wxSize& size, int n, const wxString choices[], - int style ) : - LAYER_BOX_SELECTOR( parent, id, pos, size, n, choices ), m_boardFrame( nullptr ), +PCB_LAYER_BOX_SELECTOR::PCB_LAYER_BOX_SELECTOR( wxWindow* parent, wxWindowID id, const wxString& value, + const wxPoint& pos, const wxSize& size, int n, + const wxString choices[], int style ) : + LAYER_BOX_SELECTOR( parent, id, pos, size, n, choices ), + m_boardFrame( nullptr ), m_showNotEnabledBrdlayers( false ), - m_layerPresentation( std::make_unique( - nullptr ) ) // The parent isn't awlays the frame + m_layerPresentation( std::make_unique( nullptr ) ) // The parent isn't always the frame { } @@ -56,7 +56,8 @@ void PCB_LAYER_BOX_SELECTOR::SetBoardFrame( PCB_BASE_FRAME* aFrame ) // Reload the Layers void PCB_LAYER_BOX_SELECTOR::Resync() { - Freeze(); + WINDOW_FREEZER raiiFreezer( this ); + Clear(); const int size = 14; @@ -118,7 +119,6 @@ void PCB_LAYER_BOX_SELECTOR::Resync() SetSelection( wxNOT_FOUND ); Fit(); - Thaw(); } diff --git a/pcbnew/zone_manager/dialog_zone_manager.cpp b/pcbnew/zone_manager/dialog_zone_manager.cpp index e19549d05a..03c50b0206 100644 --- a/pcbnew/zone_manager/dialog_zone_manager.cpp +++ b/pcbnew/zone_manager/dialog_zone_manager.cpp @@ -213,7 +213,7 @@ void DIALOG_ZONE_MANAGER::onDialogResize( wxSizeEvent& event ) void DIALOG_ZONE_MANAGER::OnZoneSelectionChanged( ZONE* zone ) { - Freeze(); + WINDOW_FREEZER raiiFreezer( this ); for( ZONE_SELECTION_CHANGE_NOTIFIER* i : std::list{ m_panelZoneProperties, m_zoneViewer } ) @@ -222,7 +222,6 @@ void DIALOG_ZONE_MANAGER::OnZoneSelectionChanged( ZONE* zone ) } Layout(); - Thaw(); }