diff --git a/src/components/bar.cpp b/src/components/bar.cpp index 6e7dfbe0..6e0c304b 100644 --- a/src/components/bar.cpp +++ b/src/components/bar.cpp @@ -689,13 +689,20 @@ void bar::handle(const evt::button_press& evt) { m_buttonpress_pos = evt->event_x; const auto deferred_fn = [&](size_t) { - for (auto&& action : m_renderer->actions()) { - if (action.button == m_buttonpress_btn && !action.active && action.test(m_buttonpress_pos)) { + /* + * Iterate over all defined actions in reverse order until matching action is found + * To properly handle nested actions we iterate in reverse because nested actions are added later than their + * surrounding action block + */ + auto actions = m_renderer->actions(); + for (auto action = actions.rbegin(); action != actions.rend(); action++) { + if (action->button == m_buttonpress_btn && !action->active && action->test(m_buttonpress_pos)) { m_log.trace("Found matching input area"); - m_sig.emit(button_press{string{action.command}}); + m_sig.emit(button_press{string{action->command}}); return; } } + for (auto&& action : m_opts.actions) { if (action.button == m_buttonpress_btn && !action.command.empty()) { m_log.trace("Found matching fallback handler"); diff --git a/src/components/renderer.cpp b/src/components/renderer.cpp index 7ee143a0..1fe264e4 100644 --- a/src/components/renderer.cpp +++ b/src/components/renderer.cpp @@ -767,11 +767,16 @@ bool renderer::on(const signals::parser::action_begin& evt) { bool renderer::on(const signals::parser::action_end& evt) { auto btn = evt.cast(); + + /* + * Iterate actions in reverse and find the FIRST active action that matches + */ m_log.trace_x("renderer: action_end(btn=%i)", static_cast(btn)); for (auto action = m_actions.rbegin(); action != m_actions.rend(); action++) { if (action->active && action->align == m_align && action->button == btn) { action->end_x = m_blocks.at(action->align).x; action->active = false; + break; } } return true;