Help: Fn+h lists the keys of the screen you're on, and no screen names its keys any more (#69)
CI / build (pull_request) Successful in 7m22s
Site / build (pull_request) Successful in 14s

Fn+h on any screen, text fields included, and ? outside Text Entry, open a
panel over the content area: the screen's own keys, then the ones that work
everywhere. Every App declares its keys for the state it is in (pages,
viewers, dialogs and text fields answer for themselves); the App manager
opens the panel and takes every key while it is open.

About 30 hint lines are gone, from every App. What stays on a screen is
state. The first-start Setup keeps its hints and teaches the key; a device
set up before gets one Toast, once. The guide and the FAQ open with it.
`key help` over the consoles.

476 host tests (8 new). Checked on the device with key help and screenshots:
the Launcher, all nine Apps and several of their states. 8.5 KB of flash and
40 bytes of static RAM. Decisions Q196 to Q203 in docs/milestones/U1.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
2026-10-07 01:29:51 +02:00
co-authored by Claude Opus 5.5
parent 1c6ae0e04f
commit 7fe8b3d22a
62 changed files with 855 additions and 81 deletions
+23 -6
View File
@@ -73,6 +73,26 @@ void SystemApp::onExit() { // nothing is kept while it's closed (Q120)
load_[0] = load_[1] = -1;
}
void SystemApp::help(std::vector<KeyHelp>& out) const {
out.push_back({"Tab", "the next view"});
out.push_back({"Aa Tab", "the view before"});
if (view_ == View::Tasks) {
out.push_back({"; .", "scroll"});
out.push_back({"s", "sort: cpu, stack, name"});
}
if (view_ == View::System) out.push_back({"; .", "scroll"});
}
const char* SystemApp::helpTitle() const {
switch (view_) {
case View::Tasks: return "System: tasks";
case View::Memory: return "System: memory";
case View::Network: return "System: network";
case View::System: return "System: system";
default: return "System: overview";
}
}
bool SystemApp::onKey(const KeyEvent& e) {
if (e.key == Key::Tab) {
int n = static_cast<int>(View::Count), v = static_cast<int>(view_);
@@ -219,7 +239,6 @@ void SystemApp::drawOverview(Canvas& c) {
}
}
}
footer(c, "Tab: tasks, memory, network, system");
}
void SystemApp::drawTasks(Canvas& c) {
@@ -249,8 +268,7 @@ void SystemApp::drawTasks(Canvas& c) {
c.drawString(std::to_string(r.stackFree).c_str(), area.w - 4, y);
}
c.setTextDatum(top_left);
std::string keys = std::string("s: by ") + (sort_ == TaskSort::Share ? "stack" : sort_ == TaskSort::Stack ? "name" : "cpu") +
" " + std::to_string(rows_.size()) + " tasks Tab: memory";
std::string keys = std::to_string(rows_.size()) + " tasks, by " + (sort_ == TaskSort::Share ? "cpu" : sort_ == TaskSort::Stack ? "stack" : "name");
footer(c, keys.c_str());
}
@@ -288,7 +306,7 @@ void SystemApp::drawMemory(Canvas& c) {
int x0 = gx + 1 + static_cast<int>((i - 1) * (gw - 2) / kHistory), x1 = gx + 1 + static_cast<int>(i * (gw - 2) / kHistory);
c.drawLine(x0, yOf(heapHistory_.at(i - 1)), x1, yOf(heapHistory_.at(i)), theme::kAccent);
}
footer(c, "KB free, 2 min, with the floors Tab: network");
footer(c, "KB free, 2 min, with the floors");
}
void SystemApp::drawNetwork(Canvas& c) {
@@ -331,7 +349,7 @@ void SystemApp::drawNetwork(Canvas& c) {
y += theme::kLineHeight;
}
c.setTextDatum(top_left);
footer(c, "bytes since boot Tab: system");
footer(c, "bytes since boot");
}
void SystemApp::drawSystem(Canvas& c) {
@@ -355,7 +373,6 @@ void SystemApp::drawSystem(Canvas& c) {
wrappedLines_ = static_cast<int>(wrapped.size());
systemTop_ = std::clamp(systemTop_, 0, std::max(0, wrappedLines_ - 8));
widgets::textLines(c, wrapped, systemTop_, {area.x + 2, area.y + 2, area.w - 2, area.h - 12});
footer(c, "Tab: overview");
}
} // namespace roro