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

View File

@ -96,7 +96,12 @@ static struct PGM_SINGLE_TOP : public PGM_BASE
KIWAY_PLAYER* frame = (KIWAY_PLAYER*) App().GetTopWindow();
#endif
if( frame )
{
if( wxWindow* blocking_win = frame->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
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 )
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;
}

View File

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

View File

@ -113,6 +113,9 @@ bool BACK_ANNOTATE::FetchNetlistFromPCB( std::string& aNetlist )
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 );
return true;
}

View File

@ -244,6 +244,9 @@ int EE_INSPECTION_TOOL::RunSimulation( const TOOL_EVENT& aEvent )
if( !simFrame )
return -1;
if( wxWindow* blocking_win = simFrame->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
simFrame->Show( true );
// 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,
true );
if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
editor->LoadSymbolFromSchematic( symbol );
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,
true );
if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
editor->LoadSymbol( symbol->GetLibId(), symbol->GetUnit(), symbol->GetConvert() );
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.
return 0;
if( wxWindow* blocking_win = simFrame->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
// Deactivate other tools; particularly important if another PICKER is currently running
Activate();
@ -894,7 +897,12 @@ int SCH_EDITOR_CONTROL::SimTune( const TOOL_EVENT& aEvent )
KIWAY_PLAYER* simFrame = m_frame->Kiway().Player( FRAME_SIMULATOR, false );
if( simFrame )
{
if( wxWindow* blocking_win = simFrame->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
static_cast<SIM_PLOT_FRAME*>( simFrame )->AddTuner( symbol );
}
// We do not really want to keep a symbol selected in schematic,
// so clear the current selection
@ -1992,6 +2000,9 @@ int SCH_EDITOR_CONTROL::EditWithSymbolEditor( const TOOL_EVENT& aEvent )
if( symbolEditor )
{
if( wxWindow* blocking_win = symbolEditor->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
if( aEvent.IsAction( &EE_ACTIONS::editWithLibEdit ) )
symbolEditor->LoadSymbolFromSchematic( symbol );
else if( aEvent.IsAction( &EE_ACTIONS::editLibSymbolWithLibEdit ) )

View File

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

View File

@ -403,6 +403,13 @@ public:
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:
/// Get the [path &] name of the DSO holding the requested FACE_T.
const wxString dso_search_path( FACE_T aFaceId );
@ -437,6 +444,8 @@ private:
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.
// A non empty name means only a PLAYER was run at least one time.
// Empty entries are represented by wxID_NONE.

View File

@ -647,6 +647,10 @@ int BOARD_EDITOR_CONTROL::UpdateSchematicFromPCB( const TOOL_EVENT& aEvent )
if( frame )
{
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 );
}
return 0;