Keep track of blocking windows

Allows the calling KiWAY player to send messages to the blocking window
before signaling a separate call

Fixes https://gitlab.com/kicad/code/kicad/issues/11891

Fixes https://gitlab.com/kicad/code/kicad/issues/11772
This commit is contained in:
Seth Hillbrand 2022-07-12 14:44:53 -07:00
parent 91e4d5e0ea
commit b5bf1da251
12 changed files with 75 additions and 1 deletions

View File

@ -25,6 +25,7 @@
#include <dialog_shim.h> #include <dialog_shim.h>
#include <ignore.h> #include <ignore.h>
#include <kiway_player.h> #include <kiway_player.h>
#include <kiway.h>
#include <pgm_base.h> #include <pgm_base.h>
#include <tool/tool_manager.h> #include <tool/tool_manager.h>
#include <kiplatform/ui.h> #include <kiplatform/ui.h>
@ -122,6 +123,8 @@ DIALOG_SHIM::DIALOG_SHIM( wxWindow* aParent, wxWindowID id, const wxString& titl
if( kiwayHolder ) if( kiwayHolder )
SetKiway( this, &kiwayHolder->Kiway() ); SetKiway( this, &kiwayHolder->Kiway() );
Kiway().SetBlockingDialog( this );
Bind( wxEVT_CLOSE_WINDOW, &DIALOG_SHIM::OnCloseWindow, this ); Bind( wxEVT_CLOSE_WINDOW, &DIALOG_SHIM::OnCloseWindow, this );
Bind( wxEVT_BUTTON, &DIALOG_SHIM::OnButton, this ); Bind( wxEVT_BUTTON, &DIALOG_SHIM::OnButton, this );
@ -143,6 +146,8 @@ DIALOG_SHIM::~DIALOG_SHIM()
if( IsQuasiModal() ) if( IsQuasiModal() )
EndQuasiModal( wxID_CANCEL ); EndQuasiModal( wxID_CANCEL );
Kiway().SetBlockingDialog( nullptr );
if( m_qmodal_parent_disabler ) if( m_qmodal_parent_disabler )
delete m_qmodal_parent_disabler; // usually NULL by now delete m_qmodal_parent_disabler; // usually NULL by now
} }

View File

@ -51,7 +51,7 @@ int KIWAY::m_kiface_version[KIWAY_FACE_COUNT];
KIWAY::KIWAY( PGM_BASE* aProgram, int aCtlBits, wxFrame* aTop ): KIWAY::KIWAY( PGM_BASE* aProgram, int aCtlBits, wxFrame* aTop ):
m_program( aProgram ), m_ctl( aCtlBits ), m_top( nullptr ) m_program( aProgram ), m_ctl( aCtlBits ), m_top( nullptr ), m_blockingDialog( wxID_NONE )
{ {
SetTop( aTop ); // hook player_destroy_handler() into aTop. SetTop( aTop ); // hook player_destroy_handler() into aTop.
@ -614,6 +614,19 @@ void KIWAY::ProjectChanged()
} }
} }
wxWindow* KIWAY::GetBlockingDialog()
{
return wxWindow::FindWindowById( m_blockingDialog );
}
void KIWAY::SetBlockingDialog( wxWindow* aWin )
{
if( !aWin )
m_blockingDialog = wxID_NONE;
else
m_blockingDialog = aWin->GetId();
}
bool KIWAY::ProcessEvent( wxEvent& aEvent ) bool KIWAY::ProcessEvent( wxEvent& aEvent )
{ {

View File

@ -96,7 +96,12 @@ static struct PGM_SINGLE_TOP : public PGM_BASE
KIWAY_PLAYER* frame = (KIWAY_PLAYER*) App().GetTopWindow(); KIWAY_PLAYER* frame = (KIWAY_PLAYER*) App().GetTopWindow();
#endif #endif
if( frame ) if( frame )
{
if( wxWindow* blocking_win = frame->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
frame->OpenProjectFiles( std::vector<wxString>( 1, aFileName ) ); frame->OpenProjectFiles( std::vector<wxString>( 1, aFileName ) );
}
} }
} }

View File

@ -177,6 +177,13 @@ int COMMON_CONTROL::ShowPlayer( const TOOL_EVENT& aEvent )
if( wxWindow::FindFocus() != editor ) if( wxWindow::FindFocus() != editor )
editor->SetFocus(); editor->SetFocus();
// If the player is currently blocked, focus the user attention on the correct window
if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
{
blocking_win->Raise();
blocking_win->SetFocus();
}
return 0; return 0;
} }

View File

@ -167,6 +167,9 @@ int CVPCB_CONTROL::ShowFootprintViewer( const TOOL_EVENT& aEvent )
} }
else else
{ {
if( wxWindow* blocking_win = fpframe->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
if( fpframe->IsIconized() ) if( fpframe->IsIconized() )
fpframe->Iconize( false ); fpframe->Iconize( false );

View File

@ -113,6 +113,9 @@ bool BACK_ANNOTATE::FetchNetlistFromPCB( std::string& aNetlist )
frame->OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) ); frame->OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) );
} }
if( wxWindow* blocking_win = frame->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
m_frame->Kiway().ExpressMail( FRAME_PCB_EDITOR, MAIL_PCB_GET_NETLIST, aNetlist ); m_frame->Kiway().ExpressMail( FRAME_PCB_EDITOR, MAIL_PCB_GET_NETLIST, aNetlist );
return true; return true;
} }

View File

@ -244,6 +244,9 @@ int EE_INSPECTION_TOOL::RunSimulation( const TOOL_EVENT& aEvent )
if( !simFrame ) if( !simFrame )
return -1; return -1;
if( wxWindow* blocking_win = simFrame->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
simFrame->Show( true ); simFrame->Show( true );
// On Windows, Raise() does not bring the window on screen, when iconized // On Windows, Raise() does not bring the window on screen, when iconized

View File

@ -1516,6 +1516,9 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
auto editor = (SYMBOL_EDIT_FRAME*) m_frame->Kiway().Player( FRAME_SCH_SYMBOL_EDITOR, auto editor = (SYMBOL_EDIT_FRAME*) m_frame->Kiway().Player( FRAME_SCH_SYMBOL_EDITOR,
true ); true );
if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
editor->LoadSymbolFromSchematic( symbol ); editor->LoadSymbolFromSchematic( symbol );
editor->Show( true ); editor->Show( true );
@ -1526,6 +1529,9 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
auto editor = (SYMBOL_EDIT_FRAME*) m_frame->Kiway().Player( FRAME_SCH_SYMBOL_EDITOR, auto editor = (SYMBOL_EDIT_FRAME*) m_frame->Kiway().Player( FRAME_SCH_SYMBOL_EDITOR,
true ); true );
if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
editor->LoadSymbol( symbol->GetLibId(), symbol->GetUnit(), symbol->GetConvert() ); editor->LoadSymbol( symbol->GetLibId(), symbol->GetUnit(), symbol->GetConvert() );
editor->Show( true ); editor->Show( true );

View File

@ -747,6 +747,9 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
if( !simFrame ) // Defensive coding; shouldn't happen. if( !simFrame ) // Defensive coding; shouldn't happen.
return 0; return 0;
if( wxWindow* blocking_win = simFrame->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
// Deactivate other tools; particularly important if another PICKER is currently running // Deactivate other tools; particularly important if another PICKER is currently running
Activate(); Activate();
@ -894,7 +897,12 @@ int SCH_EDITOR_CONTROL::SimTune( const TOOL_EVENT& aEvent )
KIWAY_PLAYER* simFrame = m_frame->Kiway().Player( FRAME_SIMULATOR, false ); KIWAY_PLAYER* simFrame = m_frame->Kiway().Player( FRAME_SIMULATOR, false );
if( simFrame ) if( simFrame )
{
if( wxWindow* blocking_win = simFrame->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
static_cast<SIM_PLOT_FRAME*>( simFrame )->AddTuner( symbol ); static_cast<SIM_PLOT_FRAME*>( simFrame )->AddTuner( symbol );
}
// We do not really want to keep a symbol selected in schematic, // We do not really want to keep a symbol selected in schematic,
// so clear the current selection // so clear the current selection
@ -1992,6 +2000,9 @@ int SCH_EDITOR_CONTROL::EditWithSymbolEditor( const TOOL_EVENT& aEvent )
if( symbolEditor ) if( symbolEditor )
{ {
if( wxWindow* blocking_win = symbolEditor->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
if( aEvent.IsAction( &EE_ACTIONS::editWithLibEdit ) ) if( aEvent.IsAction( &EE_ACTIONS::editWithLibEdit ) )
symbolEditor->LoadSymbolFromSchematic( symbol ); symbolEditor->LoadSymbolFromSchematic( symbol );
else if( aEvent.IsAction( &EE_ACTIONS::editLibSymbolWithLibEdit ) ) else if( aEvent.IsAction( &EE_ACTIONS::editLibSymbolWithLibEdit ) )

View File

@ -610,6 +610,11 @@ int SYMBOL_EDITOR_CONTROL::AddSymbolToSchematic( const TOOL_EVENT& aEvent )
return 0; return 0;
} }
wxWindow* blocking_dialog = schframe->Kiway().GetBlockingDialog();
if( blocking_dialog )
blocking_dialog->Close( true );
wxCHECK( libSymbol->GetLibId().IsValid(), 0 ); wxCHECK( libSymbol->GetLibId().IsValid(), 0 );
SCH_SYMBOL* symbol = new SCH_SYMBOL( *libSymbol, libId, &schframe->GetCurrentSheet(), SCH_SYMBOL* symbol = new SCH_SYMBOL( *libSymbol, libId, &schframe->GetCurrentSheet(),

View File

@ -403,6 +403,13 @@ public:
bool ProcessEvent( wxEvent& aEvent ) override; bool ProcessEvent( wxEvent& aEvent ) override;
/**
* Gets the window pointer to the blocking dialog (to send it signals)
* @return Pointer to blocking dialog window or null if none
*/
wxWindow* GetBlockingDialog();
void SetBlockingDialog( wxWindow* aWin );
private: private:
/// Get the [path &] name of the DSO holding the requested FACE_T. /// Get the [path &] name of the DSO holding the requested FACE_T.
const wxString dso_search_path( FACE_T aFaceId ); const wxString dso_search_path( FACE_T aFaceId );
@ -437,6 +444,8 @@ private:
wxFrame* m_top; // Usually m_top is the Project manager wxFrame* m_top; // Usually m_top is the Project manager
wxWindowID m_blockingDialog;
// An array to store the window ID of PLAYER frames which were run. // An array to store the window ID of PLAYER frames which were run.
// A non empty name means only a PLAYER was run at least one time. // A non empty name means only a PLAYER was run at least one time.
// Empty entries are represented by wxID_NONE. // Empty entries are represented by wxID_NONE.

View File

@ -647,6 +647,10 @@ int BOARD_EDITOR_CONTROL::UpdateSchematicFromPCB( const TOOL_EVENT& aEvent )
if( frame ) if( frame )
{ {
std::string payload; std::string payload;
if( wxWindow* blocking_win = frame->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
m_frame->Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_UPDATE, payload, m_frame ); m_frame->Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_UPDATE, payload, m_frame );
} }
return 0; return 0;