From 79f5657fb2dabcc733254e94b1a4a9c6fccbbe0b Mon Sep 17 00:00:00 2001 From: Justin Mitchell Date: Sun, 28 Jun 2026 02:38:53 -0400 Subject: [PATCH] Add configurable default home screen action Themes can now specify an initialAction in home screen config to set the default selected action when entering home normally. Falls back to this theme setting when no explicit action is requested, but explicit firmware navigation still takes precedence. --- docs/theme-creation.md | 8 ++++++++ src/activities/home/HomeActivity.cpp | 16 +++++++++++++--- src/components/themes/SdCardThemeRegistry.cpp | 5 +++++ src/components/themes/ThemeLayout.h | 2 ++ 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/docs/theme-creation.md b/docs/theme-creation.md index 2ed064b9..3ff4c1fb 100644 --- a/docs/theme-creation.md +++ b/docs/theme-creation.md @@ -217,6 +217,14 @@ Home `navigation` modes: - `splitAxis`: front left/right move through launcher actions; side up/down move through recent-book actions. Bottom button hints show Left/Right. - `carousel`: front left/right move through recent-book actions; side up/down move through launcher actions. Use this when left/right should stay inside a cover carousel and up/down should enter or leave the launcher menu. +Home `initialAction` can optionally choose the default selected action when entering home normally: + +```json +"initialAction": "reader:recent" +``` + +Supported values match launcher `action` values. Explicit firmware navigation, such as returning to Settings from a settings submenu, still overrides this default. + ### Layouts vs widgets Layouts only create named rectangles. They do not choose whether a screen is a list, cover grid, carousel, or any other presentation. diff --git a/src/activities/home/HomeActivity.cpp b/src/activities/home/HomeActivity.cpp index af9baa25..d27ada33 100644 --- a/src/activities/home/HomeActivity.cpp +++ b/src/activities/home/HomeActivity.cpp @@ -145,7 +145,9 @@ void HomeActivity::onEnter() { metrics.homeRecentBooksCount); const auto& actions = refreshHomeActions(); + const ThemeHomeScreenSpec* homeSpec = UITheme::getInstance().getHomeScreenSpec(); selectorIndex = 0; + bool hasWantedAction = initialMenuItem != HomeMenuItem::NONE; const auto wantedAction = [this]() { switch (initialMenuItem) { case HomeMenuItem::RECENTS: @@ -162,15 +164,23 @@ void HomeActivity::onEnter() { return ThemeHomeAction::FileBrowser; } }(); - if (initialMenuItem != HomeMenuItem::NONE) { + ThemeHomeAction selectedEntryAction = wantedAction; + if (!hasWantedAction && homeSpec != nullptr && homeSpec->hasInitialAction) { + hasWantedAction = true; + selectedEntryAction = homeSpec->initialAction; + } + if (hasWantedAction) { for (int i = 0; i < static_cast(actions.size()); ++i) { - if (actions[i].action == wantedAction) { + if (actions[i].action == selectedEntryAction) { selectorIndex = i; break; } } } - coverSelectorIndex = recentBooks.empty() ? 0 : std::min(selectorIndex, static_cast(recentBooks.size()) - 1); + coverSelectorIndex = !recentBooks.empty() && selectorIndex < static_cast(actions.size()) && + actions[selectorIndex].action == ThemeHomeAction::RecentBook + ? actions[selectorIndex].value + : 0; // Trigger first update requestUpdate(); diff --git a/src/components/themes/SdCardThemeRegistry.cpp b/src/components/themes/SdCardThemeRegistry.cpp index 1c9a389d..23d0b1d8 100644 --- a/src/components/themes/SdCardThemeRegistry.cpp +++ b/src/components/themes/SdCardThemeRegistry.cpp @@ -688,6 +688,11 @@ void parseHomeScreenSpec(JsonObjectConst obj, ThemeHomeScreenSpec& out) { out.enabled = true; out.navigation = parseHomeNavigationMode(obj["navigation"].as(), out.navigation); + const char* initialAction = obj["initialAction"].as(); + if (initialAction != nullptr) { + out.hasInitialAction = true; + out.initialAction = parseHomeAction(initialAction); + } out.layout = ThemeLayoutNode{}; out.layout.id = "root"; out.layout.sizeType = ThemeLayoutSizeType::Flex; diff --git a/src/components/themes/ThemeLayout.h b/src/components/themes/ThemeLayout.h index edf91c70..b404b260 100644 --- a/src/components/themes/ThemeLayout.h +++ b/src/components/themes/ThemeLayout.h @@ -120,6 +120,8 @@ struct ThemeHomeWidgetSpec { struct ThemeHomeScreenSpec { bool enabled = false; ThemeHomeNavigationMode navigation = ThemeHomeNavigationMode::Linear; + bool hasInitialAction = false; + ThemeHomeAction initialAction = ThemeHomeAction::FileBrowser; ThemeLayoutNode layout; std::vector widgets; };