See if we can't fix the ever-growing window bug.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/20120

Fixes https://gitlab.com/kicad/code/kicad/-/issues/18543

Fixes https://gitlab.com/kicad/code/kicad/-/issues/10609

(cherry picked from commit 9d074c167915f1c3cd28a187574eba18c682797e)
This commit is contained in:
Jeff Young 2025-07-21 17:22:01 +01:00
parent e5f97dac98
commit 41effa1556
2 changed files with 64 additions and 24 deletions

View File

@ -60,7 +60,9 @@ DIALOG_SHIM::DIALOG_SHIM( wxWindow* aParent, wxWindowID id, const wxString& titl
m_qmodal_loop( nullptr ),
m_qmodal_showing( false ),
m_qmodal_parent_disabler( nullptr ),
m_parentFrame( nullptr )
m_parentFrame( nullptr ),
m_userPositioned( false ),
m_userResized( false )
{
KIWAY_HOLDER* kiwayHolder = nullptr;
m_initialSize = size;
@ -101,6 +103,8 @@ DIALOG_SHIM::DIALOG_SHIM( wxWindow* aParent, wxWindowID id, const wxString& titl
Bind( wxEVT_CLOSE_WINDOW, &DIALOG_SHIM::OnCloseWindow, this );
Bind( wxEVT_BUTTON, &DIALOG_SHIM::OnButton, this );
Bind( wxEVT_SIZE, &DIALOG_SHIM::OnSize, this );
Bind( wxEVT_MOVE, &DIALOG_SHIM::OnMove, this );
#ifdef __WINDOWS__
// On Windows, the app top windows can be brought to the foreground (at least temporarily)
@ -121,29 +125,32 @@ DIALOG_SHIM::~DIALOG_SHIM()
Unbind( wxEVT_CLOSE_WINDOW, &DIALOG_SHIM::OnCloseWindow, this );
Unbind( wxEVT_BUTTON, &DIALOG_SHIM::OnButton, this );
Unbind( wxEVT_PAINT, &DIALOG_SHIM::OnPaint, this );
Unbind( wxEVT_SIZE, &DIALOG_SHIM::OnSize, this );
Unbind( wxEVT_MOVE, &DIALOG_SHIM::OnMove, this );
std::function<void( wxWindowList& )> disconnectFocusHandlers = [&]( wxWindowList& children )
{
for( wxWindow* child : children )
{
if( wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( child ) )
std::function<void( wxWindowList& )> disconnectFocusHandlers =
[&]( wxWindowList& children )
{
textCtrl->Disconnect( wxEVT_SET_FOCUS,
wxFocusEventHandler( DIALOG_SHIM::onChildSetFocus ),
nullptr, this );
}
else if( wxStyledTextCtrl* scintilla = dynamic_cast<wxStyledTextCtrl*>( child ) )
{
scintilla->Disconnect( wxEVT_SET_FOCUS,
wxFocusEventHandler( DIALOG_SHIM::onChildSetFocus ),
nullptr, this );
}
else
{
disconnectFocusHandlers( child->GetChildren() );
}
}
};
for( wxWindow* child : children )
{
if( wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( child ) )
{
textCtrl->Disconnect( wxEVT_SET_FOCUS,
wxFocusEventHandler( DIALOG_SHIM::onChildSetFocus ),
nullptr, this );
}
else if( wxStyledTextCtrl* scintilla = dynamic_cast<wxStyledTextCtrl*>( child ) )
{
scintilla->Disconnect( wxEVT_SET_FOCUS,
wxFocusEventHandler( DIALOG_SHIM::onChildSetFocus ),
nullptr, this );
}
else
{
disconnectFocusHandlers( child->GetChildren() );
}
}
};
disconnectFocusHandlers( GetChildren() );
@ -287,11 +294,24 @@ bool DIALOG_SHIM::Show( bool show )
// shown on another display)
if( wxDisplay::GetFromWindow( this ) == wxNOT_FOUND )
Centre();
m_userPositioned = false;
m_userResized = false;
}
else
{
// Save the dialog's position & size before hiding, using classname as key
class_map[ hash_key ] = wxRect( wxDialog::GetPosition(), wxDialog::GetSize() );
// Save the dialog's position & size before hiding, using classname as key.
// Be careful of rounding errors: only re-save if the user modified the value or
// it has not yet been saved.
wxRect rect = class_map[ hash_key ];
if( m_userPositioned || rect.GetPosition() == wxPoint() )
rect.SetPosition( wxDialog::GetPosition() );
if( m_userResized || rect.GetSize() == wxSize() )
rect.SetSize( wxDialog::GetSize() );
class_map[ hash_key ] = rect;
#ifdef __WXMAC__
if ( m_eventLoop )
@ -333,6 +353,20 @@ void DIALOG_SHIM::resetSize()
}
void DIALOG_SHIM::OnSize( wxSizeEvent& aEvent )
{
m_userResized = true;
aEvent.Skip();
}
void DIALOG_SHIM::OnMove( wxMoveEvent& aEvent )
{
m_userPositioned = true;
aEvent.Skip();
}
bool DIALOG_SHIM::Enable( bool enable )
{
// so we can do logging of this state change:

View File

@ -179,6 +179,9 @@ private:
*/
void OnCloseWindow( wxCloseEvent& aEvent );
void OnSize( wxSizeEvent& aEvent );
void OnMove( wxMoveEvent& aEvent );
/**
* Properly handle the default button events when in the quasimodal mode when not
* calling EndQuasiModal which is possible with any dialog derived from #DIALOG_SHIM.
@ -215,6 +218,9 @@ protected:
// The size asked by the caller, used the first time the dialog is created
wxSize m_initialSize;
bool m_userPositioned;
bool m_userResized;
// Used to support first-esc-cancels-edit logic
std::map<wxWindow*, wxString> m_beforeEditValues;