Forward context menu events to the tool that created the menu
It fixes the case when a tool sets up a menu and starts its event loop waiting exclusively for menu events. If none arrived, the tool was stuck in the loop forever. Fixes: lp:1744915 * https://bugs.launchpad.net/kicad/+bug/1744915
This commit is contained in:
parent
3aafa2b574
commit
b8ecc95d9c
|
@ -510,20 +510,24 @@ OPT<TOOL_EVENT> TOOL_MANAGER::ScheduleWait( TOOL_BASE* aTool,
|
|||
|
||||
void TOOL_MANAGER::dispatchInternal( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
// Save current settings before overwriting with the dispatched tool
|
||||
auto vc_settings = m_viewControls->GetSettings();
|
||||
|
||||
// iterate over all registered tools
|
||||
for( auto it = m_activeTools.begin(); it != m_activeTools.end(); ++it )
|
||||
{
|
||||
TOOL_STATE* st = m_toolIdIndex[*it];
|
||||
|
||||
// forward context menu events to the tool that created the menu
|
||||
if( aEvent.IsMenu() )
|
||||
{
|
||||
if( *it != m_menuOwner )
|
||||
continue;
|
||||
}
|
||||
|
||||
// the tool state handler is waiting for events (i.e. called Wait() method)
|
||||
if( st->pendingWait )
|
||||
{
|
||||
if( st->waitEvents.Matches( aEvent ) )
|
||||
{
|
||||
// By default, only messages are passed further
|
||||
// By default only messages are passed further
|
||||
m_passEvent = ( aEvent.Category() == TC_MESSAGE );
|
||||
|
||||
// got matching event? clear wait list and wake up the coroutine
|
||||
|
@ -594,8 +598,6 @@ void TOOL_MANAGER::dispatchInternal( const TOOL_EVENT& aEvent )
|
|||
if( finished )
|
||||
break; // only the first tool gets the event
|
||||
}
|
||||
|
||||
m_viewControls->ApplySettings( vc_settings );
|
||||
}
|
||||
|
||||
|
||||
|
@ -668,6 +670,7 @@ void TOOL_MANAGER::dispatchContextMenu( const TOOL_EVENT& aEvent )
|
|||
|
||||
// Run update handlers on the created copy
|
||||
menu->UpdateAll();
|
||||
m_menuOwner = toolId;
|
||||
m_menuActive = true;
|
||||
|
||||
auto frame = dynamic_cast<wxFrame*>( m_editFrame );
|
||||
|
@ -677,8 +680,6 @@ void TOOL_MANAGER::dispatchContextMenu( const TOOL_EVENT& aEvent )
|
|||
frame->PopupMenu( menu.get() );
|
||||
}
|
||||
|
||||
m_menuActive = false;
|
||||
|
||||
// Warp the cursor as long as the menu wasn't clicked out of
|
||||
if( menu->GetSelected() >= 0 )
|
||||
m_viewControls->WarpCursor( cursor, true, false );
|
||||
|
@ -695,6 +696,9 @@ void TOOL_MANAGER::dispatchContextMenu( const TOOL_EVENT& aEvent )
|
|||
evt.SetParameter( m );
|
||||
dispatchInternal( evt );
|
||||
|
||||
m_menuActive = false;
|
||||
m_menuOwner = -1;
|
||||
|
||||
// Restore the cursor settings if the tool is still active
|
||||
if( activeTool == GetCurrentToolId() )
|
||||
{
|
||||
|
|
|
@ -307,6 +307,11 @@ public:
|
|||
return m_actions & ( TA_UNDO_REDO_PRE | TA_UNDO_REDO_POST );
|
||||
}
|
||||
|
||||
bool IsMenu() const
|
||||
{
|
||||
return m_actions & TA_CONTEXT_MENU;
|
||||
}
|
||||
|
||||
///> Returns information about key modifiers state (Ctrl, Alt, etc.)
|
||||
int Modifier( int aMask = MD_MODIFIER_MASK ) const
|
||||
{
|
||||
|
|
|
@ -515,8 +515,11 @@ private:
|
|||
/// Flag saying if the currently processed event should be passed to other tools.
|
||||
bool m_passEvent;
|
||||
|
||||
/// Flag indicating whether a context menu is currently displayed
|
||||
/// Flag indicating whether a context menu is currently displayed.
|
||||
bool m_menuActive;
|
||||
|
||||
/// Tool currently displaying a popup menu. It is negative when there is no menu displayed.
|
||||
TOOL_ID m_menuOwner;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue