Properly bind event handlers to a sink

Lambdas are stored as opaque functors, so wxWidgets cannot see what they
capture.  Since we don't know what the event sink is, we don't know to
detach the handler when the sink is destroyed.  Then, events can execute
after the swatch is destroyed

Changing the lambdas to a member function explicitly binds the event to
a sink and wxWidgets can track it and detach the handler when the swatch
hits a dtor

Fixes https://gitlab.com/kicad/code/kicad/-/issues/22689
This commit is contained in:
Seth Hillbrand
2026-01-13 15:06:50 -08:00
parent 57197dbd98
commit 36655e0499
2 changed files with 16 additions and 20 deletions
+10 -20
View File
@@ -220,11 +220,7 @@ void COLOR_SWATCH::setupEvents( bool aTriggerWithSingleClick )
{
if( dynamic_cast<DIALOG_SHIM*>( wxGetTopLevelParent( this ) ) )
{
m_swatch->Bind( wxEVT_LEFT_DOWN,
[this] ( wxMouseEvent& aEvt )
{
GetNewSwatchColor();
} );
m_swatch->Bind( wxEVT_LEFT_DOWN, &COLOR_SWATCH::onMouseEvent, this );
}
else
{
@@ -232,27 +228,15 @@ void COLOR_SWATCH::setupEvents( bool aTriggerWithSingleClick )
m_swatch->Bind( wxEVT_LEFT_DOWN, &COLOR_SWATCH::rePostEvent, this );
// bind the events that trigger the dialog
m_swatch->Bind( wxEVT_LEFT_DCLICK,
[this] ( wxMouseEvent& aEvt )
{
GetNewSwatchColor();
} );
m_swatch->Bind( wxEVT_LEFT_DCLICK, &COLOR_SWATCH::onMouseEvent, this );
if( aTriggerWithSingleClick )
{
m_swatch->Bind( wxEVT_LEFT_UP,
[this] ( wxMouseEvent& aEvt )
{
GetNewSwatchColor();
} );
m_swatch->Bind( wxEVT_LEFT_UP, &COLOR_SWATCH::onMouseEvent, this );
}
}
m_swatch->Bind( wxEVT_MIDDLE_DOWN,
[this] ( wxMouseEvent& aEvt )
{
GetNewSwatchColor();
} );
m_swatch->Bind( wxEVT_MIDDLE_DOWN, &COLOR_SWATCH::onMouseEvent, this );
m_swatch->Bind( wxEVT_RIGHT_DOWN, &COLOR_SWATCH::rePostEvent, this );
}
@@ -264,6 +248,12 @@ void COLOR_SWATCH::rePostEvent( wxEvent& aEvent )
}
void COLOR_SWATCH::onMouseEvent( wxEvent& )
{
GetNewSwatchColor();
}
static void sendSwatchChangeEvent( COLOR_SWATCH& aSender )
{
wxCommandEvent changeEvt( COLOR_SWATCH_CHANGED, aSender.GetId() );
+6
View File
@@ -142,6 +142,12 @@ private:
*/
void rePostEvent( wxEvent& aEvent );
/**
* Handle mouse events on the swatch, and trigger the color picker dialog if appropriate.
* Binds to the event sink so it is properly freed when the swatch is destroyed.
*/
void onMouseEvent( wxEvent& aEvent );
KIGFX::COLOR4D m_color;
KIGFX::COLOR4D m_background;
KIGFX::COLOR4D m_default;