From 370bdef8d0171f41a2bbbe555196bd1873549f20 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sun, 11 Jun 2023 20:30:52 +0100 Subject: [PATCH] Clear the playerFrame lookup cache when closing frames. WindowIds aren't actually guaranteed to be unique, and we don't perform a dynamic_cast on the result of FindWindowById() because of linker issues.... This is an attempt to fix KICAD-39. Fixes https://gitlab.com/kicad/code/kicad/-/issues/14928 (cherry picked from commit d6aefc458ce39a431558c5a45de957d5efc42e69) --- common/kiway.cpp | 10 +++++++--- common/kiway_player.cpp | 2 ++ include/kiway.h | 10 +++++----- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/common/kiway.cpp b/common/kiway.cpp index 793f87b5ff..6e4c2fa004 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -495,7 +495,7 @@ bool KIWAY::PlayerClose( FRAME_T aFrameType, bool doForce ) return false; } - KIWAY_PLAYER* frame = GetPlayerFrame( aFrameType ); + KIWAY_PLAYER* frame = GetPlayerFrame( aFrameType ); if( frame == nullptr ) // Already closed return true; @@ -523,14 +523,18 @@ bool KIWAY::PlayersClose( bool doForce ) bool ret = true; for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i ) - { ret = ret && PlayerClose( FRAME_T( i ), doForce ); - } return ret; } +void KIWAY::PlayerDidClose( FRAME_T aFrameType ) +{ + m_playerFrameId[aFrameType] = wxID_NONE; +} + + void KIWAY::ExpressMail( FRAME_T aDestination, MAIL_T aCommand, std::string& aPayload, wxWindow* aSource ) { diff --git a/common/kiway_player.cpp b/common/kiway_player.cpp index 3e0737ecff..065349b736 100644 --- a/common/kiway_player.cpp +++ b/common/kiway_player.cpp @@ -169,6 +169,8 @@ bool KIWAY_PLAYER::ShowModal( wxString* aResult, wxWindow* aResultantFocusWindow bool KIWAY_PLAYER::Destroy() { + Kiway().PlayerDidClose( GetFrameType() ); + return EDA_BASE_FRAME::Destroy(); } diff --git a/include/kiway.h b/include/kiway.h index 28e02d588e..9a1dcd28e9 100644 --- a/include/kiway.h +++ b/include/kiway.h @@ -358,6 +358,11 @@ public: */ virtual bool PlayersClose( bool doForce ); + /** + * Notifies a Kiway that a player has been closed. + */ + void PlayerDidClose( FRAME_T aFrameType ); + /** * Send @a aPayload to @a aDestination from @a aSource. * @@ -434,11 +439,6 @@ private: /// Get the [path &] name of the DSO holding the requested FACE_T. const wxString dso_search_path( FACE_T aFaceId ); -#if 0 - /// hooked into m_top in SetTop(), marks child frame as closed. - void player_destroy_handler( wxWindowDestroyEvent& event ); -#endif - bool set_kiface( FACE_T aFaceType, KIFACE* aKiface ) { if( (unsigned) aFaceType < (unsigned) KIWAY_FACE_COUNT )