From 118e04e34078c65b34afeefc854a4bb034f2ffde Mon Sep 17 00:00:00 2001 From: Evan Reichard Date: Sun, 2 Aug 2026 11:20:48 -0400 Subject: [PATCH] fix(settings): paint the scan and keyboard notices before the work that blocks on_tick runs before draw in the same pass, so a screen built for a blocking call was never painted until the call returned -- on a panel ui.screen() had already cleared. Scanning looked like a hang on a blank screen. The notice is now painted by the tap itself and centered on both axes. --- Makefile | 2 +- sdcard/apps/settings/main.lua | 12 +++++++-- test/settings_busy.lua | 49 +++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 test/settings_busy.lua diff --git a/Makefile b/Makefile index d5ce0ce..9dbbc60 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ LUA ?= lua CXX ?= c++ CXXFLAGS ?= -std=c++11 -Wall -Wextra BUILD_DIR := .pio/build/esp32-32e -LUA_TESTS := test/ui_layout.lua test/ui_theme.lua test/settings_calibration.lua test/statusbar_dirty.lua +LUA_TESTS := test/ui_layout.lua test/ui_theme.lua test/settings_calibration.lua test/statusbar_dirty.lua test/settings_busy.lua .PHONY: test test-lua test-cpp test-stubs stubs build upload monitor clean diff --git a/sdcard/apps/settings/main.lua b/sdcard/apps/settings/main.lua index 02b83a7..7d69453 100644 --- a/sdcard/apps/settings/main.lua +++ b/sdcard/apps/settings/main.lua @@ -155,10 +155,18 @@ function buildMenu() themed(items) end +-- Painted here rather than left to draw(): the work these announce blocks the loop, and +-- on_tick runs before draw in the same pass, so the panel would sit on the background +-- ui.screen() cleared it to until the blocking call returned. +local function busy(text) + themed{w = "fill", h = "fill", justify = "center", align = "center", ui.label(text)} + screen:draw() +end + local function requestScan() mode = "scanning" scanRequested = true - themed{pad = 12, gap = 8, ui.text("wifi"), ui.text("scanning...")} + busy("scanning networks...") end local function forgetNetwork() @@ -219,7 +227,7 @@ local function chooseNetwork(network) end keyboardRequested = true mode = "password" - themed{pad = 12, ui.text("opening keyboard...")} + busy("opening keyboard...") end local function selectNetwork(button) diff --git a/test/settings_busy.lua b/test/settings_busy.lua new file mode 100644 index 0000000..5d07401 --- /dev/null +++ b/test/settings_busy.lua @@ -0,0 +1,49 @@ +-- Run: lua test/settings_busy.lua +-- The scan and keyboard screens announce themselves before work that blocks the loop for +-- seconds. on_tick runs before draw in the same pass, so anything left for draw() to paint +-- appears only after the blocking call returns -- on a panel ui.screen() has already +-- cleared. These assert the announcement is painted by the tap itself. +package.path = "sdcard/lib/?.lua;test/?.lua;" .. package.path + +local device = require("fake_device").install() + +dofile("sdcard/apps/settings/main.lua") + +local function tapRow(prefix) + device.painted = {} + draw() + for _, item in ipairs(device.painted) do + if item.label:sub(1, #prefix) == prefix then + device.painted = {} + on_touch_down(item.x + 2, item.y + 2) + on_touch_up(item.x + 2, item.y + 2) + return + end + end + error("no row labelled '" .. prefix .. "'") +end + +local function paintedLabel(prefix) + for _, item in ipairs(device.painted) do + if item.label:sub(1, #prefix) == prefix then return item end + end + return nil +end + +init() +tapRow("wifi") +tapRow("scan networks") + +-- Painted by the tap, with no draw() in between. +local busy = paintedLabel("scanning") +assert(busy, "the scan screen paints its notice before scanning") + +local width = #busy.label * device.charWidth +local centerX = busy.x + width / 2 +local centerY = busy.y + device.fontHeight / 2 +local panelW, panelH = gui.getWidth(), gui.getHeight() +assert(math.abs(centerX - panelW / 2) <= 1, "centered horizontally, got x " .. busy.x) +-- The bar is above the app's frame, so the app's own height is what it centers in. +assert(math.abs(centerY - panelH / 2) <= 1, "centered vertically, got y " .. busy.y) + +print("ok")