From e28381841a381bbf87d87c6ba59b283613f38e0c Mon Sep 17 00:00:00 2001 From: Ian McInerney Date: Sun, 11 Feb 2024 23:27:38 +0000 Subject: [PATCH] Don't remember the menu in the tool dispatcher Remembering the menu in the tool dispatcher can lead to stale pointers if we never receive the required menu open or close events. Since wx 3.1.3, we get a valid menu object for all three events, so just forward the event to that menu unconditionally if the menu is one of our ACTION_MENUs. Fixes https://gitlab.com/kicad/code/kicad/-/issues/16844 (Cherry-picked from b588001b95748b1369ce8f72c11fd29519994438) --- common/tool/tool_dispatcher.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index 54851bb0cd..882be5608c 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -538,6 +538,23 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) } else if( type == wxEVT_MENU_OPEN || type == wxEVT_MENU_CLOSE || type == wxEVT_MENU_HIGHLIGHT ) { + wxMenuEvent* tmp = dynamic_cast( &aEvent ); + + // Something is amiss if the event has these types and isn't a menu event, so bail out on + // its processing + if( !tmp ) + { + aEvent.Skip(); + return; + } + + wxMenuEvent& menuEvent = *tmp; + +#if wxCHECK_VERSION( 3, 2, 0 ) + // Forward the event to the menu for processing + if( ACTION_MENU* currentMenu = dynamic_cast( menuEvent.GetMenu() ) ) + currentMenu->OnMenuEvent( menuEvent ); +#else // // wxWidgets has several issues that we have to work around: // @@ -546,16 +563,13 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) // (FWIW, this one is fixed in wxWidgets 3.1.x.) // // 2) wxWidgets doesn't pass the menu pointer for wxEVT_MENU_HIGHLIGHT events. So we - // store the menu pointer from the wxEVT_MENU_OPEN call. + // store the menu pointer from the wxEVT_MENU_OPEN call (fixed in 3.1.3). // // 3) wxWidgets has no way to tell whether a command is from a menu selection or a // hotkey. So we keep track of menu highlighting so we can differentiate. // - static ACTION_MENU* currentMenu; - wxMenuEvent& menuEvent = *dynamic_cast( &aEvent ); - if( type == wxEVT_MENU_OPEN ) { currentMenu = dynamic_cast( menuEvent.GetMenu() ); @@ -575,6 +589,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) currentMenu = nullptr; } +#endif aEvent.Skip(); }