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 )
|
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
|
// iterate over all registered tools
|
||||||
for( auto it = m_activeTools.begin(); it != m_activeTools.end(); ++it )
|
for( auto it = m_activeTools.begin(); it != m_activeTools.end(); ++it )
|
||||||
{
|
{
|
||||||
TOOL_STATE* st = m_toolIdIndex[*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)
|
// the tool state handler is waiting for events (i.e. called Wait() method)
|
||||||
if( st->pendingWait )
|
if( st->pendingWait )
|
||||||
{
|
{
|
||||||
if( st->waitEvents.Matches( aEvent ) )
|
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 );
|
m_passEvent = ( aEvent.Category() == TC_MESSAGE );
|
||||||
|
|
||||||
// got matching event? clear wait list and wake up the coroutine
|
// 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 )
|
if( finished )
|
||||||
break; // only the first tool gets the event
|
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
|
// Run update handlers on the created copy
|
||||||
menu->UpdateAll();
|
menu->UpdateAll();
|
||||||
|
m_menuOwner = toolId;
|
||||||
m_menuActive = true;
|
m_menuActive = true;
|
||||||
|
|
||||||
auto frame = dynamic_cast<wxFrame*>( m_editFrame );
|
auto frame = dynamic_cast<wxFrame*>( m_editFrame );
|
||||||
|
@ -677,8 +680,6 @@ void TOOL_MANAGER::dispatchContextMenu( const TOOL_EVENT& aEvent )
|
||||||
frame->PopupMenu( menu.get() );
|
frame->PopupMenu( menu.get() );
|
||||||
}
|
}
|
||||||
|
|
||||||
m_menuActive = false;
|
|
||||||
|
|
||||||
// Warp the cursor as long as the menu wasn't clicked out of
|
// Warp the cursor as long as the menu wasn't clicked out of
|
||||||
if( menu->GetSelected() >= 0 )
|
if( menu->GetSelected() >= 0 )
|
||||||
m_viewControls->WarpCursor( cursor, true, false );
|
m_viewControls->WarpCursor( cursor, true, false );
|
||||||
|
@ -695,6 +696,9 @@ void TOOL_MANAGER::dispatchContextMenu( const TOOL_EVENT& aEvent )
|
||||||
evt.SetParameter( m );
|
evt.SetParameter( m );
|
||||||
dispatchInternal( evt );
|
dispatchInternal( evt );
|
||||||
|
|
||||||
|
m_menuActive = false;
|
||||||
|
m_menuOwner = -1;
|
||||||
|
|
||||||
// Restore the cursor settings if the tool is still active
|
// Restore the cursor settings if the tool is still active
|
||||||
if( activeTool == GetCurrentToolId() )
|
if( activeTool == GetCurrentToolId() )
|
||||||
{
|
{
|
||||||
|
|
|
@ -307,6 +307,11 @@ public:
|
||||||
return m_actions & ( TA_UNDO_REDO_PRE | TA_UNDO_REDO_POST );
|
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.)
|
///> Returns information about key modifiers state (Ctrl, Alt, etc.)
|
||||||
int Modifier( int aMask = MD_MODIFIER_MASK ) const
|
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.
|
/// Flag saying if the currently processed event should be passed to other tools.
|
||||||
bool m_passEvent;
|
bool m_passEvent;
|
||||||
|
|
||||||
/// Flag indicating whether a context menu is currently displayed
|
/// Flag indicating whether a context menu is currently displayed.
|
||||||
bool m_menuActive;
|
bool m_menuActive;
|
||||||
|
|
||||||
|
/// Tool currently displaying a popup menu. It is negative when there is no menu displayed.
|
||||||
|
TOOL_ID m_menuOwner;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue