From 251c3e874ad8b2ba13a1c92da8c55b7314e03ef6 Mon Sep 17 00:00:00 2001
From: patrick96
Date: Sat, 23 Sep 2017 16:49:39 +0200
Subject: [PATCH 1/2] fix(renderer): Only close a single action
Before the renderer would close all active matching actions. That way
nested actions would also close their surrounding action block
---
src/components/renderer.cpp | 5 +++++
1 file changed, 5 insertions(+)
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;
From c7cb5ebf94d8824a4a445c8959b02784a24414d7 Mon Sep 17 00:00:00 2001
From: patrick96
Date: Sat, 23 Sep 2017 16:50:57 +0200
Subject: [PATCH 2/2] fix(renderer): Handle nested actions events properly
For nested actions, the inner action should override the outer action.
But because the list of actions was not iterated in reverse the outer
action was matched first.
Fixes #760
---
src/components/bar.cpp | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
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");