feat: implement MCP drawing as screensaver instead of standalone app

- Add ScreensaverType::McpScreen to DisplaySettings enum, toString/fromString
- Add 'MCP Screen' option to the Display settings screensaver dropdown
- New McpScreensaver (Screensaver subclass): creates full-screen lv_canvas on
  the overlay, allocates framebuffer in SPIRAM, registers canvas pointer in
  McpSystemState, shows 'Waiting for LLM...' until first draw command arrives
- Wire McpScreensaver into DisplayIdle::activateScreensaver() switch
- McpSystem::ensureOverrideScreen() now calls displayidle::findService()->
  startScreensaver() instead of launching McpOverrideApp — canvas appears
  automatically on any LLM draw command
- Remove McpOverrideApp (replaced by screensaver), deregister from Tactility.cpp
- Remove mcpOverrideEnabled from McpSettings — no longer needed
- Simplify McpSettingsApp: remove Screen Override toggle, update info text to
  direct users to Settings -> Display -> Screensaver -> MCP Screen
This commit is contained in:
Adolfo Reyna
2026-06-27 09:17:50 -04:00
parent 41004a3c6f
commit cd921e1aa9
11 changed files with 160 additions and 59 deletions
+14 -11
View File
@@ -6,6 +6,7 @@
#include <Tactility/file/File.h>
#include <Tactility/app/App.h>
#include <Tactility/Logger.h>
#include <Tactility/service/displayidle/DisplayIdleService.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
@@ -76,19 +77,21 @@ static bool display_ready(McpSystemState& state) {
static bool ensureOverrideScreen() {
auto& state = getState();
auto mcpSettings = settings::mcp::loadOrGetDefault();
if (!mcpSettings.mcpOverrideEnabled) {
return false;
}
if (state.drawArea == nullptr) {
LOGGER.info("MCP Screen Override triggered: starting McpOverrideApp");
tt::app::start("one.tactility.mcpscreen");
// Wait up to 500ms for UI to initialize
for (int i = 0; i < 10; ++i) {
vTaskDelay(pdMS_TO_TICKS(50));
if (state.drawArea != nullptr) {
break;
// Activate the MCP Screen screensaver via DisplayIdle
auto idleService = service::displayidle::findService();
if (idleService) {
LOGGER.info("MCP draw triggered: starting MCP screensaver");
idleService->startScreensaver();
// Wait up to 500ms for the canvas to be registered
for (int i = 0; i < 10; ++i) {
vTaskDelay(pdMS_TO_TICKS(50));
if (state.drawArea != nullptr) {
break;
}
}
} else {
LOGGER.warn("DisplayIdle service not found; cannot activate MCP screensaver");
}
}
return state.drawArea != nullptr;