From 17d53bd77f4881eb2325fb3e9cd52097cfd1371f Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Fri, 6 Mar 2026 11:16:51 -0800 Subject: [PATCH] Cycle through options on single-click for toggle flyout groups When clicking flyout buttons for non-tool groups (crosshair style, units, line modes), advance to the next option in the group instead of re-dispatching the already-active action. Tool-type flyout groups retain existing behavior of selecting the displayed tool. Fixes https://gitlab.com/kicad/code/kicad/-/issues/23349 --- common/tool/action_toolbar.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/common/tool/action_toolbar.cpp b/common/tool/action_toolbar.cpp index 91ce4136c3..9cfca39dc4 100644 --- a/common/tool/action_toolbar.cpp +++ b/common/tool/action_toolbar.cpp @@ -730,6 +730,7 @@ void ACTION_TOOLBAR::onToolEvent( wxAuiToolBarEvent& aEvent ) { const auto actionIt = m_toolActions.find( id ); const auto cancelIt = m_toolCancellable.find( id ); + const auto groupIt = m_actionGroups.find( id ); // Determine if the tool is actually cancellable bool isCancellable = ( cancelIt != m_toolCancellable.end() ) ? cancelIt->second : false; @@ -742,6 +743,32 @@ void ACTION_TOOLBAR::onToolEvent( wxAuiToolBarEvent& aEvent ) m_toolManager->CancelTool(); handled = true; } + else if( groupIt != m_actionGroups.end() && m_toolKinds[id] ) + { + // For toggle-type groups (units, crosshair, line modes), cycle to the next action + ACTION_GROUP* group = groupIt->second.get(); + const std::vector& actions = group->GetActions(); + const TOOL_ACTION* current = actionIt->second; + + const TOOL_ACTION* next = actions[0]; + + for( size_t i = 0; i < actions.size(); ++i ) + { + if( actions[i]->GetId() == current->GetId() ) + { + next = actions[( i + 1 ) % actions.size()]; + break; + } + } + + evt = next->MakeEvent(); + evt->SetHasPosition( false ); + m_toolManager->ProcessEvent( *evt ); + m_toolManager->GetToolHolder()->RefreshCanvas(); + + doSelectAction( group, *next ); + handled = true; + } else if( actionIt != m_toolActions.end() ) { // Dispatch a tool event