From fe62e18f8e9374956907599aab54c02270c9987f Mon Sep 17 00:00:00 2001 From: mikecarper Date: Tue, 1 Sep 2026 00:23:07 -0700 Subject: [PATCH] Fit setup IP beside compact WiFi QR --- src/helpers/ui/WiFiSetupQrDisplay.h | 9 +++- .../test_display_driver.cpp | 44 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/helpers/ui/WiFiSetupQrDisplay.h b/src/helpers/ui/WiFiSetupQrDisplay.h index e25f975f..c5840145 100644 --- a/src/helpers/ui/WiFiSetupQrDisplay.h +++ b/src/helpers/ui/WiFiSetupQrDisplay.h @@ -8,6 +8,9 @@ namespace ui { // Render a setup-AP join QR at the largest size that still leaves the right // half of compact displays available for a short textual fallback/reference. +// A Version 1 QR, including its four-module quiet zone, is exactly 58 pixels +// at two pixels per module. Keep that exact upper-left footprint on 128x64 +// panels so a normal setup IP has the full 66-pixel text row beside it. // Returns false when the payload or panel geometry cannot be represented. inline bool drawWiFiSetupQr(DisplayDriver& display, const char* ssid, const char* address) { @@ -21,8 +24,12 @@ inline bool drawWiFiSetupQr(DisplayDriver& display, const char* ssid, return false; } - const int qr_size = display.height() < display.width() / 2 + int qr_size = display.height() < display.width() / 2 ? display.height() : display.width() / 2; + static constexpr int compact_qr_size = (21 + 4 * 2) * 2; + if (display.height() == 64 && qr_size >= compact_qr_size) { + qr_size = compact_qr_size; + } if (!display.drawQrCode(payload, 0, 0, qr_size)) return false; const int text_x = qr_size + 4; diff --git a/test/test_display_driver/test_display_driver.cpp b/test/test_display_driver/test_display_driver.cpp index 4628b8d5..5b460799 100644 --- a/test/test_display_driver/test_display_driver.cpp +++ b/test/test_display_driver/test_display_driver.cpp @@ -3,11 +3,22 @@ #include #include #include +#include #include #include #include +ColorVal UIColor::window_bkg = 0; +ColorVal UIColor::title_bkg = 0; +ColorVal UIColor::title_txt = 0; +ColorVal UIColor::primary_txt = 1; +ColorVal UIColor::secondary_txt = 1; +ColorVal UIColor::warning_txt = 1; +ColorVal UIColor::popup_bkg = 0; +ColorVal UIColor::popup_txt = 1; +ColorVal UIColor::corp_blue = 1; + namespace { bool isValidUTF8(const char* text) { @@ -90,6 +101,23 @@ public: void endFrame() override {} }; +class QrTestDisplay : public TestDisplay { +public: + int qr_x = -1; + int qr_y = -1; + int qr_size = -1; + + QrTestDisplay(int width, int height, int glyph_width) + : TestDisplay(width, height, glyph_width) {} + + bool drawQrCode(const char*, int x, int y, int size) override { + qr_x = x; + qr_y = y; + qr_size = size; + return true; + } +}; + } // namespace TEST(DisplayDriver, EllipsizesOnlyAtUTF8CodepointBoundaries) { @@ -105,6 +133,22 @@ TEST(DisplayDriver, QrCodeIsOptionalByDefault) { 27, 55, 105)); } +TEST(DisplayDriver, CompactWiFiQrLeavesRoomForCompleteSetupAddress) { + QrTestDisplay display(128, 64, 6); + ASSERT_TRUE(mesh::ui::drawWiFiSetupQr( + display, "MC-F7F0", "192.168.4.1")); + + EXPECT_EQ(0, display.qr_x); + EXPECT_EQ(0, display.qr_y); + EXPECT_EQ(58, display.qr_size); + ASSERT_FALSE(display.rows.empty()); + const auto& address = display.rows.back(); + EXPECT_EQ("192.168.4.1", address.text); + EXPECT_EQ(48, address.y); + EXPECT_LE(address.x + display.getTextWidth(address.text.c_str()), + display.width()); +} + TEST(WiFiSetupQrPayload, EncodesOpenSetupNetwork) { char payload[64]; EXPECT_TRUE(mesh::ui::buildWiFiSetupQrPayload(