fix(host): prepare the panel on every app entry, not just at boot

Navigation went straight to the runtime, so a launched app inherited the
previous one's rotation, fullscreen state and viewport, and logged nothing.
Boot and navigation now share prepareForApp/settleNewApp.

Documents the new architecture: the shared platform in lib/esp32-lua-api,
providers in src/host, and the /.lua card layout.
This commit is contained in:
2026-08-03 18:40:10 -04:00
parent 7510bb38a5
commit 484745445f
4 changed files with 41 additions and 36 deletions
+16 -20
View File
@@ -103,33 +103,34 @@ void LuaHost::setFullscreen(bool on) {
nextBarMs = 0; // leaving fullscreen left the bar's rows painted by the app
}
bool LuaHost::begin() { return startApp("Home", ""); }
bool LuaHost::begin() {
prepareForApp();
if (!runtime.startApp("Home")) return false;
settleNewApp();
return true;
}
bool LuaHost::startApp(const std::string& path, const std::string& arg) {
void LuaHost::prepareForApp() {
tft.setRotation(settings.rotationIndex()); // the previous app may have rotated the frame
fullscreen = false;
// Applied before the app loads, because init() measures the panel it was given. The height
// is last app's, which is the same module, and loadStatusBar() corrects it if that changes.
// is the last app's, which is the same module, and settleNewApp() corrects it if that changes.
applyViewport();
Serial.printf("[lua] launching %s free=%u largest=%u\n", path.c_str(), ESP.getFreeHeap(), ESP.getMaxAllocHeap());
lastTouched = true; // the tap that launched this app may still be down
ignoreRelease = true; // and its release is not this app's gesture
lastTouched = true; // the tap that launched this app may still be down
ignoreRelease = true; // and its release is not this app's gesture
backArmed = false;
Serial.printf("[lua] launching free=%u largest=%u\n", ESP.getFreeHeap(), ESP.getMaxAllocHeap());
}
if (!runtime.startApp(path, arg)) {
fail(("could not start " + path).c_str());
return false;
}
void LuaHost::settleNewApp() {
hasBack = runtime.canGoBack(); // the runtime keeps the history; the bar only offers the control
loadStatusBar();
applyViewport();
if (barInset() > 0 && !barBroken) drawStatusBar();
const uint32_t now = millis();
nextDrawMs = now;
lastDrawMs = now;
return true;
Serial.printf("[lua] running %s\n", runtime.appPath().c_str());
}
// The bar is a Lua module like any other, loaded per app because the state is too.
@@ -232,17 +233,12 @@ void LuaHost::pollTimers() {
}
void LuaHost::navigate() {
prepareForApp();
if (!runtime.applyPendingNavigation()) {
fail("app failed to start");
return;
}
hasBack = runtime.canGoBack();
loadStatusBar();
applyViewport();
if (barInset() > 0 && !barBroken) drawStatusBar();
const uint32_t now = millis();
nextDrawMs = now;
lastDrawMs = now;
settleNewApp();
}
void LuaHost::loop() {