diff --git a/src/ButtonEventManager.cpp b/src/ButtonEventManager.cpp index f10dff48..3558bf5e 100644 --- a/src/ButtonEventManager.cpp +++ b/src/ButtonEventManager.cpp @@ -5,6 +5,15 @@ // Required for constexpr array out-of-class definition (C++14). constexpr ButtonEventManager::Button ButtonEventManager::ALL_BUTTONS[ButtonEventManager::NUM_BUTTONS]; +int ButtonEventManager::buttonToIndex(const Button button) { + for (int i = 0; i < NUM_BUTTONS; i++) { + if (ALL_BUTTONS[i] == button) { + return i; + } + } + return -1; +} + bool ButtonEventManager::hasDoubleAction(const Button button) { using BA = CrossPointSettings::BUTTON_ACTION; switch (button) { @@ -40,6 +49,12 @@ void ButtonEventManager::pushEventFront(const Button button, const PressType typ eventBuf[eventHead] = {button, type}; } +bool ButtonEventManager::isShortPending(const Button button) const { + const int idx = buttonToIndex(button); + if (idx < 0) return false; + return buttons[idx].state == State::ReleasedOnce; +} + bool ButtonEventManager::consumeEvent(ButtonEvent& out) { if (eventHead == eventTail) return false; out = eventBuf[eventHead]; diff --git a/src/ButtonEventManager.h b/src/ButtonEventManager.h index 7d39e506..1cccecb5 100644 --- a/src/ButtonEventManager.h +++ b/src/ButtonEventManager.h @@ -53,6 +53,10 @@ class ButtonEventManager { // This is used when the configured action is BTN_DEFAULT. void pushEventFront(Button button, PressType type); + // Returns true while a button's first release is waiting for the + // double-click decision window to expire (i.e. a Short is pending). + bool isShortPending(Button button) const; + // Returns true if a double-click action is configured for this button. // ButtonEventManager queries CrossPointSettings internally. static bool hasDoubleAction(Button button); @@ -83,4 +87,5 @@ class ButtonEventManager { void pushEvent(Button button, PressType type); void processButton(int idx, Button btn); + static int buttonToIndex(Button button); }; diff --git a/src/activities/reader/XtcReaderChapterSelectionActivity.cpp b/src/activities/reader/XtcReaderChapterSelectionActivity.cpp index 5f78ba9f..cab385db 100644 --- a/src/activities/reader/XtcReaderChapterSelectionActivity.cpp +++ b/src/activities/reader/XtcReaderChapterSelectionActivity.cpp @@ -5,7 +5,6 @@ #include -#include "ButtonEventManager.h" #include "MappedInputManager.h" #include "components/UITheme.h" #include "fontIds.h" @@ -87,19 +86,11 @@ void XtcReaderChapterSelectionActivity::loop() { } buttonNavigator.onNextRelease([this, totalItems] { - if (ButtonEventManager::hasDoubleAction(MappedInputManager::Button::Right) || - ButtonEventManager::hasDoubleAction(MappedInputManager::Button::PageForward)) { - return; - } selectorIndex = ButtonNavigator::nextIndex(selectorIndex, totalItems); requestUpdate(); }); buttonNavigator.onPreviousRelease([this, totalItems] { - if (ButtonEventManager::hasDoubleAction(MappedInputManager::Button::Left) || - ButtonEventManager::hasDoubleAction(MappedInputManager::Button::PageBack)) { - return; - } selectorIndex = ButtonNavigator::previousIndex(selectorIndex, totalItems); requestUpdate(); }); diff --git a/src/util/ButtonNavigator.cpp b/src/util/ButtonNavigator.cpp index e8e8b499..ab24130d 100644 --- a/src/util/ButtonNavigator.cpp +++ b/src/util/ButtonNavigator.cpp @@ -1,5 +1,7 @@ #include "ButtonNavigator.h" +#include "ButtonEventManager.h" + const MappedInputManager* ButtonNavigator::mappedInput = nullptr; void ButtonNavigator::onNext(const Callback& callback) { @@ -41,7 +43,13 @@ void ButtonNavigator::onPress(const Buttons& buttons, const Callback& callback) void ButtonNavigator::onRelease(const Buttons& buttons, const Callback& callback) { const bool wasReleased = std::any_of(buttons.begin(), buttons.end(), [](const MappedInputManager::Button button) { - return mappedInput != nullptr && mappedInput->wasReleased(button); + if (mappedInput == nullptr || !mappedInput->wasReleased(button)) { + return false; + } + + // If a button Short is still pending while we wait for a possible double, + // avoid firing release-based navigation first. + return !globalButtonEvents().isShortPending(button); }); if (wasReleased) {