From af24a495ee81edaf59bba27482223ae3e1af7804 Mon Sep 17 00:00:00 2001 From: Bota Date: Tue, 22 Sep 2026 00:50:27 +0200 Subject: [PATCH 1/2] ui: fix centred messages on displays taller than 240 pixels make_show_message_activity() asserts that the padding used to centre a multi-line message is below 100, a limit scaled by hand for displays up to about 240 pixels high. On the 280 pixel Waveshare Touch LCD 2 a two or three line message with no title bar needs more than that, so it aborts - and the "Internal error" screen shown by jade_abort() is one of those messages. The padding is stored as a uint8_t, so check against that instead. --- main/ui/dialogs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/ui/dialogs.c b/main/ui/dialogs.c index 7fe1b2f71..2e6efd5cf 100644 --- a/main/ui/dialogs.c +++ b/main/ui/dialogs.c @@ -332,7 +332,7 @@ gui_activity_t* make_show_message_activity(const char* message[], const size_t m const size_t msgextent = message_size * h; toppad = msgextent < yextent ? (yextent - msgextent) / 2 : 0; // top padding to centre message JADE_LOGD("ypct, yextent, msgextent, toppad: %u, %u, %u, %u", ypct, yextent, msgextent, toppad); - JADE_ASSERT(toppad < 100); // sanity check + JADE_ASSERT(toppad <= UINT8_MAX); // stored as a uint8_t padding switch (message_size) { case 2: From 1d94ac8961e9eac25c35889e857fc947f5de9c78 Mon Sep 17 00:00:00 2001 From: Bota Date: Tue, 22 Sep 2026 00:50:41 +0200 Subject: [PATCH 2/2] abort: only try to show the error message once If showing the "Internal error" message fails an assertion, jade_abort() is called again and tries to show the same message again, which fails in the same way, so the device stays on whatever was on screen. Only try once, so a second failure goes straight on to the real abort. --- main/jade_abort.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/main/jade_abort.c b/main/jade_abort.c index 6a6300940..caeecc355 100644 --- a/main/jade_abort.c +++ b/main/jade_abort.c @@ -13,11 +13,16 @@ extern void __real_abort(void); void jade_abort(const char* file, const int line_n) { + // Only try to show the error message once - if showing it fails and aborts + // again, go straight on to the real abort rather than looping forever + static bool message_attempted = false; + // Clear senstitive data keychain_clear(); sensitive_clear_stack(); - if (gui_initialized() && !gui_is_gui_task()) { + if (!message_attempted && gui_initialized() && !gui_is_gui_task()) { + message_attempted = true; char details[128]; const int ret = snprintf(details, sizeof(details), "%s:%d", file, line_n); const char* message[3] = { "Internal error", "", "Restarting" };