From 9fe4dc5e38e57784c2f65f1b318aa1f78124a3c6 Mon Sep 17 00:00:00 2001 From: Thomas Symalla Date: Sun, 19 Jul 2026 07:29:13 +0200 Subject: [PATCH] feat: Add option to switch behavior for "back to browser / home" in Reader activity (#2366) ## Summary It would be nice to switch back to the file list from an Reader activity via a short back button press. This change adds an Reader option to switch the default behavior, so a short back button press in the Reader activity can now go back to the file list, and a long press on back goes back to the home view. This does a fair bit of refactoring, introducing a new constant for the ms limit. * **What changes are included?** - Changes to the translation - Additional global Reader option - Refactoring of the back button behavior in the Reader activity --- lib/I18n/translations/english.yaml | 1 + lib/I18n/translations/german.yaml | 1 + src/CrossPointSettings.h | 2 ++ src/SettingsList.h | 2 ++ src/activities/reader/EpubReaderActivity.cpp | 17 ++++------ src/activities/reader/ReaderUtils.h | 35 ++++++++++++++++++++ src/activities/reader/TxtReaderActivity.cpp | 12 ++----- src/activities/reader/XtcReaderActivity.cpp | 12 ++----- 8 files changed, 51 insertions(+), 31 deletions(-) diff --git a/lib/I18n/translations/english.yaml b/lib/I18n/translations/english.yaml index a9a88c98..e5900ddc 100644 --- a/lib/I18n/translations/english.yaml +++ b/lib/I18n/translations/english.yaml @@ -343,6 +343,7 @@ STR_EMBEDDED_STYLE: "Embedded Style" STR_FOCUS_READING: "Focus Reading" STR_OPDS_SERVER_URL: "OPDS Server URL" STR_PWR_BTN_FOOTNOTE_BACK: "Quick-return from footnotes" +STR_BACK_SHORT_TO_FILE_BROWSER: "Short Back to File Browser" STR_SET_SLEEP_COVER: "Set Cover" STR_FOOTNOTES: "Footnotes" STR_NO_FOOTNOTES: "No footnotes on this page" diff --git a/lib/I18n/translations/german.yaml b/lib/I18n/translations/german.yaml index b0b499c1..d0c83dc5 100644 --- a/lib/I18n/translations/german.yaml +++ b/lib/I18n/translations/german.yaml @@ -315,6 +315,7 @@ STR_BOOK_S_STYLE: "Buch-Stil" STR_EMBEDDED_STYLE: "Eingebetteter Stil" STR_FOCUS_READING: "Fokus-Lesen" STR_OPDS_SERVER_URL: "OPDS-Server-URL" +STR_BACK_SHORT_TO_FILE_BROWSER: "Kurz zurück drücken zum Datei-Browser" STR_SET_SLEEP_COVER: "Wähle Cover" STR_SCREENSHOT_BUTTON: "Screenshot aufnehmen" STR_FOOTNOTES: "Fußnoten" diff --git a/src/CrossPointSettings.h b/src/CrossPointSettings.h index 855fc863..b6580a64 100644 --- a/src/CrossPointSettings.h +++ b/src/CrossPointSettings.h @@ -271,6 +271,8 @@ class CrossPointSettings { uint8_t removeReadBooksFromRecents = 0; // Move epub to /Read/ folder on SD card when finished (0 = disabled, 1 = enabled) uint8_t moveFinishedToReadFolder = 0; + // Short press Back goes to file browser instead of home (0 = disabled, 1 = enabled) + uint8_t backShortToFileBrowser = 0; // Image rendering mode in EPUB reader uint8_t imageRendering = IMAGES_DISPLAY; // Tilt-based page turning (X3 only — requires QMI8658 IMU) diff --git a/src/SettingsList.h b/src/SettingsList.h index 90fe8f56..e7e97ad4 100644 --- a/src/SettingsList.h +++ b/src/SettingsList.h @@ -181,6 +181,8 @@ inline std::vector getSettingsList(const SdCardFontRegistry* regist "shortPwrBtn", StrId::STR_CAT_CONTROLS), SettingInfo::Toggle(StrId::STR_PWR_BTN_FOOTNOTE_BACK, &CrossPointSettings::pwrBtnFootnoteBack, "pwrBtnFootnoteBack", StrId::STR_CAT_CONTROLS), + SettingInfo::Toggle(StrId::STR_BACK_SHORT_TO_FILE_BROWSER, &CrossPointSettings::backShortToFileBrowser, + "backShortToFileBrowser", StrId::STR_CAT_CONTROLS), // --- System --- SettingInfo::Value( diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index 66c9d9b4..6d8cc417 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -448,20 +448,15 @@ void EpubReaderActivity::loop() { } } - // Long press BACK (1s+) goes to file selection - if (mappedInput.isPressed(MappedInputManager::Button::Back) && mappedInput.getHeldTime() >= ReaderUtils::GO_HOME_MS) { - activityManager.goToFileBrowser(epub ? epub->getPath() : ""); + // Short press Back restores position when viewing a footnote (takes priority over navigation) + if (footnoteDepth > 0 && mappedInput.wasReleased(MappedInputManager::Button::Back) && + mappedInput.getHeldTime() < ReaderUtils::GO_BACK_OR_HOME_MS) { + restoreSavedPosition(); return; } - // Short press BACK goes directly to home (or restores position if viewing footnote) - if (mappedInput.wasReleased(MappedInputManager::Button::Back) && - mappedInput.getHeldTime() < ReaderUtils::GO_HOME_MS) { - if (footnoteDepth > 0) { - restoreSavedPosition(); - return; - } - onGoHome(); + if (ReaderUtils::handleBackNavigation(mappedInput, activityManager, epub ? epub->getPath().c_str() : "", + {this, [](void* ctx) { static_cast(ctx)->onGoHome(); }})) { return; } diff --git a/src/activities/reader/ReaderUtils.h b/src/activities/reader/ReaderUtils.h index 4b37451a..bdec3a14 100644 --- a/src/activities/reader/ReaderUtils.h +++ b/src/activities/reader/ReaderUtils.h @@ -6,10 +6,12 @@ #include #include "MappedInputManager.h" +#include "activities/ActivityManager.h" namespace ReaderUtils { constexpr unsigned long GO_HOME_MS = 1000; +constexpr unsigned long GO_BACK_OR_HOME_MS = GO_HOME_MS; constexpr unsigned long SKIP_HOLD_MS = 700; constexpr unsigned long BOOKMARK_HOLD_MS = 400; constexpr unsigned long BOOKMARK_MESSAGE_DURATION_MS = 2500; @@ -96,4 +98,37 @@ void renderAntiAliased(GfxRenderer& renderer, RenderFn&& renderFn) { renderer.restoreBwBuffer(); } +struct BackNavCallback { + void* ctx; + void (*fn)(void*); +}; + +// Returns true if the back button was consumed (caller should return). +// Long press (>= GO_BACK_OR_HOME_MS): +// - default: go to file browser +// - with backShortToFileBrowser: go home +// Short press (< GO_BACK_OR_HOME_MS): +// - default: go home +// - with backShortToFileBrowser: go to file browser. +inline bool handleBackNavigation(const MappedInputManager& mappedInput, ActivityManager& activityManager, + const char* filePath, BackNavCallback goHome) { + if (mappedInput.isPressed(MappedInputManager::Button::Back) && mappedInput.getHeldTime() >= GO_BACK_OR_HOME_MS) { + if (SETTINGS.backShortToFileBrowser) { + goHome.fn(goHome.ctx); + } else { + activityManager.goToFileBrowser(filePath); + } + return true; + } + if (mappedInput.wasReleased(MappedInputManager::Button::Back) && mappedInput.getHeldTime() < GO_BACK_OR_HOME_MS) { + if (SETTINGS.backShortToFileBrowser) { + activityManager.goToFileBrowser(filePath); + } else { + goHome.fn(goHome.ctx); + } + return true; + } + return false; +} + } // namespace ReaderUtils diff --git a/src/activities/reader/TxtReaderActivity.cpp b/src/activities/reader/TxtReaderActivity.cpp index 0464c614..7911e1ca 100644 --- a/src/activities/reader/TxtReaderActivity.cpp +++ b/src/activities/reader/TxtReaderActivity.cpp @@ -60,16 +60,8 @@ void TxtReaderActivity::onExit() { } void TxtReaderActivity::loop() { - // Long press BACK (1s+) goes to file selection - if (mappedInput.isPressed(MappedInputManager::Button::Back) && mappedInput.getHeldTime() >= ReaderUtils::GO_HOME_MS) { - activityManager.goToFileBrowser(txt ? txt->getPath() : ""); - return; - } - - // Short press BACK goes directly to home - if (mappedInput.wasReleased(MappedInputManager::Button::Back) && - mappedInput.getHeldTime() < ReaderUtils::GO_HOME_MS) { - onGoHome(); + if (ReaderUtils::handleBackNavigation(mappedInput, activityManager, txt ? txt->getPath().c_str() : "", + {this, [](void* ctx) { static_cast(ctx)->onGoHome(); }})) { return; } diff --git a/src/activities/reader/XtcReaderActivity.cpp b/src/activities/reader/XtcReaderActivity.cpp index 1d1923eb..12868253 100644 --- a/src/activities/reader/XtcReaderActivity.cpp +++ b/src/activities/reader/XtcReaderActivity.cpp @@ -101,16 +101,8 @@ void XtcReaderActivity::loop() { openChapterSelection(); } - // Long press BACK (1s+) goes to file selection - if (mappedInput.isPressed(MappedInputManager::Button::Back) && mappedInput.getHeldTime() >= ReaderUtils::GO_HOME_MS) { - activityManager.goToFileBrowser(xtc ? xtc->getPath() : ""); - return; - } - - // Short press BACK goes directly to home - if (mappedInput.wasReleased(MappedInputManager::Button::Back) && - mappedInput.getHeldTime() < ReaderUtils::GO_HOME_MS) { - onGoHome(); + if (ReaderUtils::handleBackNavigation(mappedInput, activityManager, xtc ? xtc->getPath().c_str() : "", + {this, [](void* ctx) { static_cast(ctx)->onGoHome(); }})) { return; }