Skip to content

TTGO-T-Display usermod fixup#5479

Draft
willmmiles wants to merge 25 commits into
wled:mainfrom
willmmiles:ttgo-t-display-usermod-fixup
Draft

TTGO-T-Display usermod fixup#5479
willmmiles wants to merge 25 commits into
wled:mainfrom
willmmiles:ttgo-t-display-usermod-fixup

Conversation

@willmmiles

@willmmiles willmmiles commented Apr 5, 2026

Copy link
Copy Markdown
Member

Import all the latest fixes for this usermod, and upgrade it to v2. Also includes the ability to specify the display setup header as a custom property in platformio_override.ini.

Replaces #4600.

Summary by CodeRabbit

  • New Features

    • Added a new TTGO T-Display build workflow with a preconfigured PlatformIO environment.
    • Display setup is now selected automatically, with easier customization for other boards.
  • Documentation

    • Updated setup instructions for building and flashing the TTGO T-Display usermod.
    • Added clearer guidance on what appears on the screen, power-saving behavior, and config options.
  • Bug Fixes

    • Improved display compatibility and startup handling for TFT-based builds.
    • Added safer behavior when display-related pins conflict or the display is disabled.

spiff72 and others added 15 commits April 5, 2026 13:48
details, and force an older version of dependent library TFT_eSPI.
Revised WLED_RELEASE_NAME to "WLED_T-Display"
Removed Serial.begin statement from userSetup
This allows a v1 usermod to be linked as a library, too.  Of course,
only one such usermod can be included, or a linker error will result.
Avoids any collisions with other source files.
Convert to a library-based usermod, allowing easy inclusion with the
custom_usermods feature.  The BTNPIN override and display model
selection are handled via a build python script, so it is no longer
necessary modify the TFT_eSPI library install.
Allow specifying the display setup file as an environment parameter.
Files are looked for anywhere in the include path of WLED itself, and
the direct dependencies of the TTGO-T-Display module (ie. TFT_eSPI).
Adds better support for newer CPUs.
Check if the path is fully qualified before searching; this allows using
files outside of the WLED folder.
@coderabbitai

coderabbitai Bot commented Apr 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Adds a reusable TFT_eSPI_compat PlatformIO library that resolves display setup headers at build time and provides a SPIFFS stub. Refactors the TTGO-T-Display usermod into a class-based Usermod using this library, adds new build configuration files, and rewrites documentation for both.

Changes

TFT_eSPI_compat build library

Layer / File(s) Summary
Library manifest and compile shims
lib/TFT_eSPI_compat/library.json, lib/TFT_eSPI_compat/shims/SPIFFS.h, lib/TFT_eSPI_compat/shims/User_Setup.h
New library manifest pinning TFT_eSPI and wiring configure.py as extraScript; SPIFFS.h shim provides a null-backed fs::FS stub; User_Setup.h includes tft_setup.h to trigger dependency scanning.
Build-time display setup resolution
lib/TFT_eSPI_compat/configure.py
Appends shim include paths, resolves custom_display_setup/TFT_DISPLAY_SETUP_DEFAULT to a file, writes display_setup.resolved.json only when changed, and generates tft_setup.h including the resolved header or failing the build.
Compatibility wrapper documentation
lib/TFT_eSPI_compat/README.md
Documents dependency setup, custom_display_setup configuration, extraScript defaults, and the underlying build mechanism.

TTGO-T-Display usermod refactor

Layer / File(s) Summary
Weak legacy usermod hooks
wled00/usermod.cpp
Marks userSetup, userConnected, userLoop as weak so class-based usermods can override them.
TTGO_T_DisplayMod class implementation
usermods/TTGO-T-Display/usermod.cpp
Converts the usermod to TTGO_T_DisplayMod : public Usermod with setup()/loop(), pin allocation, redraw throttling, auto power-off, BusManager::currentMilliamps() display, and addToJsonInfo/addToConfig/readFromConfig overrides with REGISTER_USERMOD.
PlatformIO build wiring for TTGO
usermods/TTGO-T-Display/library.json, usermods/TTGO-T-Display/set_build_flags.py, usermods/TTGO-T-Display/platformio_override.ini
Adds library manifest depending on TFT_eSPI_compat, a build script setting TFT_DISPLAY_SETUP_DEFAULT, and a WLED_T-Display PlatformIO environment with pins and custom_usermods.
TTGO usermod documentation
usermods/TTGO-T-Display/README.md
Rewrites setup instructions around platformio_override.ini, documents runtime display behavior, "using with other boards" via custom_display_setup, pin-conflict handling, and cfg.json configuration.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • wled/WLED#5403: Adds the custom usermod registration/loading machinery that the new REGISTER_USERMOD-based TTGO usermod depends on.
  • wled/WLED#5644: Both PRs adopt custom_usermods in platformio_override.ini-style configuration for wiring usermods.

Suggested labels: hardware, in progress, documentation

Suggested reviewers: DedeHai, softhack007

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is related to the PR but too generic to convey the main change or distinguish it from other TTGO-T-Display updates. Use a specific title such as "Add TTGO-T-Display PlatformIO override and TFT_eSPI compatibility shim".
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@willmmiles willmmiles self-assigned this Apr 5, 2026
@willmmiles willmmiles added keep This issue will never become stale/closed automatically usermod usermod related labels Apr 5, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
usermods/TTGO-T-Display/usermod.cpp (1)

96-144: ⚠️ Potential issue | 🟠 Major

AP mode never settles on ESP32.

The change detector uses String(apSSID) when apActive is true, but the cached value is updated with WiFi.SSID() on ESP32. In AP mode those values differ, so needRedraw stays true forever and the idle backlight timeout never kicks in.

Suggested fix
   `#if` defined(ESP8266)
   knownSsid = apActive ? WiFi.softAPSSID() : WiFi.SSID();
   `#else`
-  knownSsid = WiFi.SSID();
+  knownSsid = apActive ? String(apSSID) : WiFi.SSID();
   `#endif`
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@usermods/TTGO-T-Display/usermod.cpp` around lines 96 - 144, The SSID change
check in loop() uses String(apSSID) when apActive while knownSsid is later set
via WiFi.SSID()/WiFi.softAPSSID(), causing AP mode to never settle; fix by
making the initial SSID comparison use the same API as the update path (use
WiFi.softAPSSID() when apActive and WiFi.SSID() otherwise) so ((apActive) ?
WiFi.softAPSSID() : WiFi.SSID()) is used in the change detector (and ensure the
knownSsid assignment in the update block matches that same conditional across
ESP8266/ESP32).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@usermods/TTGO-T-Display/library.json`:
- Line 2: The manifest has a typo in the JSON key "name:" which violates
PlatformIO's schema; open the library.json and rename the property key "name:"
to "name" (keep the existing value "TTGO-T-Display") so the package metadata
conforms to PlatformIO's expected schema and is correctly recognized by
functions that read library.json.

In `@usermods/TTGO-T-Display/platformio_override.ini`:
- Around line 36-37: The platformio_override.ini currently enables both usermods
via the custom_usermods setting ("audioreactive TTGO-T-Display"), which
unintentionally adds the audioreactive module and its deps to the default TTGO
environment; update the custom_usermods value in platformio_override.ini to
include only the TTGO-T-Display usermod (or remove the combined entry and
document how to enable audioreactive separately), ensuring the symbol
"custom_usermods" no longer references "audioreactive" so only the intended
"TTGO-T-Display" usermod is enabled by default.

In `@usermods/TTGO-T-Display/README.md`:
- Around line 43-52: The README mixes two integration models: it still instructs
copying usermod.cpp into wled00 (old flow) even though this repo uses the
override-based workflow; update the README to remove the instruction to copy
usermod.cpp into wled00 and instead show where the custom_display_setup is
configured in platformio_override.ini (point to the custom_display_setup entry
and explain copying platformio_override.ini into the project root). Also add a
note that this usermod lives under usermods/TTGO-T-Display and follows the
library-based approach, and include that the usermod has a dedicated
library.json to manage dependencies (so users don’t attempt manual file copies).

In `@usermods/TTGO-T-Display/set_build_flags.py`:
- Around line 41-43: The forced-include flag is being passed as a single
whitespace-containing string in add_display_setup
(tgt_env.Append(CCFLAGS=f"-include {display_setup_path}")), which SCons will
split and thus break when display_setup_path contains spaces; change the CCFLAGS
Append to pass the flag and the path as separate argv entries (e.g., provide a
list/sequence containing the "-include" token and display_setup_path) so SCons
treats them as two distinct arguments and handles paths with spaces correctly.

---

Outside diff comments:
In `@usermods/TTGO-T-Display/usermod.cpp`:
- Around line 96-144: The SSID change check in loop() uses String(apSSID) when
apActive while knownSsid is later set via WiFi.SSID()/WiFi.softAPSSID(), causing
AP mode to never settle; fix by making the initial SSID comparison use the same
API as the update path (use WiFi.softAPSSID() when apActive and WiFi.SSID()
otherwise) so ((apActive) ? WiFi.softAPSSID() : WiFi.SSID()) is used in the
change detector (and ensure the knownSsid assignment in the update block matches
that same conditional across ESP8266/ESP32).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1bec40c3-8c17-4246-8390-93bb0c5dacc5

📥 Commits

Reviewing files that changed from the base of the PR and between c819814 and c0dbe63.

📒 Files selected for processing (6)
  • usermods/TTGO-T-Display/README.md
  • usermods/TTGO-T-Display/library.json
  • usermods/TTGO-T-Display/platformio_override.ini
  • usermods/TTGO-T-Display/set_build_flags.py
  • usermods/TTGO-T-Display/usermod.cpp
  • wled00/usermod.cpp

Comment thread usermods/TTGO-T-Display/library.json Outdated
Comment thread usermods/TTGO-T-Display/platformio_override.ini Outdated
Comment thread usermods/TTGO-T-Display/README.md Outdated
Comment on lines +41 to +43
def add_display_setup(tgt_env):
tgt_env.Append(CPPDEFINES=[("USER_SETUP_LOADED", "1")])
tgt_env.Append(CCFLAGS=f"-include {display_setup_path}")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, locate and examine the file
find . -name "set_build_flags.py" -path "*/usermods/*" 2>/dev/null

Repository: wled/WLED

Length of output: 97


🏁 Script executed:

# Check if the file exists and read the relevant section
if [ -f "./usermods/TTGO-T-Display/set_build_flags.py" ]; then
  echo "=== File found, reading lines 35-50 ===";
  sed -n '35,50p' "./usermods/TTGO-T-Display/set_build_flags.py" | cat -n;
else
  echo "File not found at expected path. Searching for any set_build_flags.py...";
  find . -name "set_build_flags.py" 2>/dev/null;
fi

Repository: wled/WLED

Length of output: 884


🌐 Web query:

PlatformIO SCons CCFLAGS string vs array argument handling spaces

💡 Result:

In PlatformIO’s SCons environment, env["CCFLAGS"] is a SCons CLVar (command-line variable). That affects how strings vs lists are handled:

  • If you pass a string (e.g. env.Append(CCFLAGS='-DNAME="A B" -O2')), SCons will run its Split() logic and split on whitespace into multiple arguments (with some quote-aware behavior). As a side effect, “extra” spaces in string inputs get stripped. (scons.org)
  • If you pass a list/array (e.g. env.Append(CCFLAGS=['-DNAME="A B"', '-O2'])), each list element is treated as one argument, so an element that contains spaces is preserved as a single flag. SCons explicitly recommends this when you need spaces preserved. (scons.org)

Rule of thumb:

  • Use a string for normal flags where spaces just separate flags.
  • Use a list when any single flag contains spaces (or you want to guarantee “one item = one argument”). (scons.org)

Citations:


Pass the forced include as separate argv entries.

CCFLAGS=f"-include {display_setup_path}" breaks as soon as custom_display_setup resolves to a path containing spaces. SCons splits string arguments on whitespace, so paths with spaces (common on Windows) will be split into multiple arguments, breaking the -include flag and undermining the new full-path workflow.

Suggested fix
 def add_display_setup(tgt_env):
     tgt_env.Append(CPPDEFINES=[("USER_SETUP_LOADED", "1")])
-    tgt_env.Append(CCFLAGS=f"-include {display_setup_path}")
+    tgt_env.Append(CCFLAGS=["-include", display_setup_path])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@usermods/TTGO-T-Display/set_build_flags.py` around lines 41 - 43, The
forced-include flag is being passed as a single whitespace-containing string in
add_display_setup (tgt_env.Append(CCFLAGS=f"-include {display_setup_path}")),
which SCons will split and thus break when display_setup_path contains spaces;
change the CCFLAGS Append to pass the flag and the path as separate argv entries
(e.g., provide a list/sequence containing the "-include" token and
display_setup_path) so SCons treats them as two distinct arguments and handles
paths with spaces correctly.

@softhack007

Copy link
Copy Markdown
Member

In file included from .pio/libdeps/usermods_esp32/TFT_eSPI/TFT_eSPI.h:101,
from usermods/TTGO-T-Display/usermod.cpp:22:
.pio/libdeps/usermods_esp32/TFT_eSPI/Processors/TFT_eSPI_ESP32.h:139:12: fatal error: SPIFFS.h: No such file or directory

I think the reason for the build failure is crazy simple: tasmota has removed SPIFFS 😢 , so the display driver lib fails to compile (even when SPIFFs is not used, the lib needs SPIFFS.h)

You can still build this usermod with the original arduino-esp32 framework from espressif.

WLED/platformio.ini

Lines 305 to 308 in bf948fa

;; espressif platform (optional - needs 300KB extra flash)
;;; arduino-esp32 2.0.17 + esp-idf 4.4.7
;; platform = espressif32@ ~6.13.0
;; platform_packages =

btw, same build failure in another usermods that use TFT_eSPI

@willmmiles

Copy link
Copy Markdown
Member Author

Re 18d4a41: Arg, I had unpushed commits in this branch, now I have to play rebase games. :( Would you mind not doing this in the future?

I think the reason for the build failure is crazy simple: tasmota has removed SPIFFS 😢 , so the display driver lib fails to compile (even when SPIFFs is not used, the lib needs SPIFFS.h)

Yes, I know. There are better workarounds via the custom script. (This branch is labeled draft for a reason!)

@softhack007

Copy link
Copy Markdown
Member

Re 18d4a41: Arg, I had unpushed commits in this branch, now I have to play rebase games. :( Would you mind not doing this in the future?

@willmmiles sorry and your're right - I should have thought for a moment about the "why DRAFT?" thing 😅

Good to know that you see a way via custom script, i was a bit over-nervous maybe when I found out that tasmota simply does not have "SPIFFS.h", so all our TFT_eSPI based usermods will suffer from the same problem.

@willmmiles

Copy link
Copy Markdown
Member Author

@willmmiles sorry and your're right - I should have thought for a moment about the "why DRAFT?" thing 😅

Good to know that you see a way via custom script, i was a bit over-nervous maybe when I found out that tasmota simply does not have "SPIFFS.h", so all our TFT_eSPI based usermods will suffer from the same problem.

Yes. It's complicated by the fact that the TFT_eSPI library seemed to be unmaintained for a year or so there. I think it's faced stiff competition with Espressif's well optimized esp_lcd library. When V5 lands.... ;)

I've shimmed it in my WIP build with lib_ldf_mode=deep+ to dig up an external SPIFFS.h (I've got a project due Friday that needed a quick fix) but that's also a terrible solution long-term. I could fork the lib - might be easier than shimming in place. I'm also looking at factoring out a framework-y "TFT_eSPI usermod" that can share the common bits for this library (pin management, build shims, etc.) for all of the local use cases.

@softhack007 softhack007 added this to the 16.1 milestone Jun 9, 2026
Ensure pins are registered together to avoid partial success.
Add a shim layer for TFT_espi that works around the missing SPIFFS.h
dependency.  Integrate some logic for accepting display definitions via
a PlatformIO custom property as an alternative to a dozen command line
switches; this improves cache viability, too.
@willmmiles

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
lib/TFT_eSPI_compat/configure.py (1)

76-83: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Optional: avoid computing os.path.join(...) twice per candidate.

The generator evaluates os.path.join(str(p), display_setup) in both the predicate and the value expression. A small comprehension over precomputed candidates reads cleaner and halves the joins.

♻️ Suggested refactor
-            setup_path = next(
-                (
-                    os.path.join(str(p), display_setup)
-                    for p in search_paths
-                    if os.path.isfile(os.path.join(str(p), display_setup))
-                ),
-                None,
-            )
+            candidates = (os.path.join(str(p), display_setup) for p in search_paths)
+            setup_path = next((c for c in candidates if os.path.isfile(c)), None)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/TFT_eSPI_compat/configure.py` around lines 76 - 83, The setup path search
in configure.py recomputes os.path.join(str(p), display_setup) twice for each
candidate, so refactor the generator around next() to precompute each joined
path once and reuse it for both the file check and the returned value. Update
the logic near the setup_path assignment to iterate over prebuilt candidate
paths from search_paths, keeping the same behavior while avoiding duplicate
joins.
usermods/TTGO-T-Display/usermod.cpp (1)

121-121: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove leftover dead code introduced in the refactor.

// tft.setRotation(3); is a commented-out duplicate of line 102 within the newly-written setup(). Per coding guidelines, dead/unused code should be removed or justified with a comment.

🧹 Proposed cleanup
-
-    // tft.setRotation(3);
     ready = true;

As per coding guidelines, "Remove dead/unused code or justify it with comments" for **/{wled00,usermods}/**/*.{cpp,h,js,css}.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@usermods/TTGO-T-Display/usermod.cpp` at line 121, Remove the leftover dead
code in setup() for the TTGO-T-Display usermod: the commented-out
tft.setRotation(3) duplicate should be deleted or replaced with a clear
justification comment. Check the setup() logic in usermod.cpp and ensure only
the active rotation call remains, with no unused refactor remnants.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@usermods/TTGO-T-Display/usermod.cpp`:
- Around line 130-138: The config re-enable path in readFromConfig updates
enabled but leaves needRedraw unchanged, so loop exits the !enabled branch and
then skips the redraw/backlight-on logic. Update the enabled transition handling
in readFromConfig (and any shared state update path used by the UI) to set
needRedraw when the usermod changes from disabled to enabled, so loop forces the
display/backlight to turn back on immediately. Use the existing enabled,
needRedraw, and displayTurnedOff flags in usermod.cpp to keep the re-enable
behavior consistent with the disable path.

---

Nitpick comments:
In `@lib/TFT_eSPI_compat/configure.py`:
- Around line 76-83: The setup path search in configure.py recomputes
os.path.join(str(p), display_setup) twice for each candidate, so refactor the
generator around next() to precompute each joined path once and reuse it for
both the file check and the returned value. Update the logic near the setup_path
assignment to iterate over prebuilt candidate paths from search_paths, keeping
the same behavior while avoiding duplicate joins.

In `@usermods/TTGO-T-Display/usermod.cpp`:
- Line 121: Remove the leftover dead code in setup() for the TTGO-T-Display
usermod: the commented-out tft.setRotation(3) duplicate should be deleted or
replaced with a clear justification comment. Check the setup() logic in
usermod.cpp and ensure only the active rotation call remains, with no unused
refactor remnants.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d22afe1d-29dd-4ce1-b92f-eb4f0f0580c7

📥 Commits

Reviewing files that changed from the base of the PR and between c0dbe63 and fd2c84f.

📒 Files selected for processing (10)
  • lib/TFT_eSPI_compat/README.md
  • lib/TFT_eSPI_compat/configure.py
  • lib/TFT_eSPI_compat/library.json
  • lib/TFT_eSPI_compat/shims/SPIFFS.h
  • lib/TFT_eSPI_compat/shims/User_Setup.h
  • usermods/TTGO-T-Display/README.md
  • usermods/TTGO-T-Display/library.json
  • usermods/TTGO-T-Display/platformio_override.ini
  • usermods/TTGO-T-Display/set_build_flags.py
  • usermods/TTGO-T-Display/usermod.cpp
✅ Files skipped from review due to trivial changes (2)
  • lib/TFT_eSPI_compat/shims/User_Setup.h
  • lib/TFT_eSPI_compat/library.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • usermods/TTGO-T-Display/library.json

Comment on lines +130 to +138
if (!enabled) {
#if DISPLAY_HAS_BACKLIGHT
if (!displayTurnedOff) {
digitalWrite(TFT_BL, !TFT_BACKLIGHT_ON); // Turn backlight off.
displayTurnedOff = true;
}
#endif
return;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Re-enabling via config doesn't force a redraw/backlight-on.

readFromConfig() updates enabled but never sets needRedraw. When the usermod is disabled then re-enabled through the WLED UI, loop() clears the !enabled early-return but needRedraw remains false (line 159's if (!needRedraw) branch is taken), so the backlight/display stays off until an unrelated tracked value (SSID, IP, brightness, mode, or palette) happens to change. Contrast with the disable path, which turns the backlight off immediately (lines 132-135).

🐛 Proposed fix to force a redraw on re-enable
 bool readFromConfig(JsonObject& root) override
 {
   // default settings values could be set here (or below using the 3-argument getJsonValue()) instead of in the class definition or constructor
   // setting them inside readFromConfig() is slightly more robust, handling the rare but plausible use case of single value being missing after boot (e.g. if the cfg.json was manually edited and a value was removed)
   JsonObject top = root[FPSTR(_name)];
   bool configComplete = !top.isNull();
 
-  configComplete &= getJsonValue(top[FPSTR(_enabled)], enabled);
+  bool wasEnabled = enabled;
+  configComplete &= getJsonValue(top[FPSTR(_enabled)], enabled);
+  if (!wasEnabled && enabled) needRedraw = true; // force refresh/backlight-on when re-enabled
   return configComplete;
 }

Also applies to: 273-282

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@usermods/TTGO-T-Display/usermod.cpp` around lines 130 - 138, The config
re-enable path in readFromConfig updates enabled but leaves needRedraw
unchanged, so loop exits the !enabled branch and then skips the
redraw/backlight-on logic. Update the enabled transition handling in
readFromConfig (and any shared state update path used by the UI) to set
needRedraw when the usermod changes from disabled to enabled, so loop forces the
display/backlight to turn back on immediately. Use the existing enabled,
needRedraw, and displayTurnedOff flags in usermod.cpp to keep the re-enable
behavior consistent with the disable path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

keep This issue will never become stale/closed automatically usermod usermod related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants