Skip to content

Conversation

@Shadowtrance
Copy link
Contributor

@Shadowtrance Shadowtrance commented Jan 30, 2026

Files app fix
alert dialog and selection dialog fixes
symbol export

Docs are also done for the website.

Summary by CodeRabbit

  • New Features

    • Support for Guition JC3248W535C: integrated display and touch drivers, LVGL support, and SD card support
    • Public device configuration and registration entry exposed for external tooling
  • Improvements

    • App lifecycle: view deinitialization on hide to avoid stale callbacks
    • Dialog APIs now return launch IDs for improved caller control
  • Chores

    • CI build matrix and firmware config updated to include the new device platform

✏️ Tip: You can customize this high-level summary in your review settings.

Files app fix
alert dialog and selection dialog fixes
symbol export
@coderabbitai
Copy link

coderabbitai bot commented Jan 30, 2026

📝 Walkthrough

Walkthrough

Adds support for a new ESP32‑S3 device "Guition JC3248W535C": firmware build matrix entry, Kconfig option, device tree, and device.properties. Adds AXS15231B display and touch drivers with LVGL and esp_lcd integration, device configuration, display/touch/SD card factory functions, and a no-op C registration function. Firmware idf_component.yml adds espressif/esp_lcd_axs15231b. Tactility changes: View::deinit added and FilesApp::onHide calls it; several C dialog APIs now return AppLaunchId; exports lv_group_set_editing symbol.

🚥 Pre-merge checks | ✅ 1 | ❌ 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 PR title 'Guition JC3248W535C' is a device name but lacks specificity about the main changes. While a device is being added, the title doesn't convey what is actually being done (adding support, implementing drivers, etc.), making it unclear to reviewers scanning history. Consider using a more descriptive title like 'Add Guition JC3248W535C device support' or 'Implement Guition JC3248W535C display and touch drivers' to better communicate the main objective.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🧹 Nitpick comments (1)
Firmware/idf_component.yml (1)

32-32: Consider adding target rules for consistency.

Other display-specific drivers in this file use conditional rules (e.g., esp_lcd_ili9341 restricts to esp32, esp32s3). Since esp_lcd_axs15231b appears to be used only by the JC3248W535C (esp32s3), you could add a similar rule to avoid pulling this dependency for unrelated targets.

♻️ Optional: Add target restriction
-  espressif/esp_lcd_axs15231b: "2.0.2"
+  espressif/esp_lcd_axs15231b:
+    version: "2.0.2"
+    rules:
+      - if: "target == esp32s3"

Comment on lines +475 to +476
void View::deinit(const AppContext& appContext) {
lv_obj_remove_event_cb(dir_entry_list, dirEntryListScrollBeginCallback);
Copy link

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:

find . -type f -name "View.cpp" | head -5

Repository: TactilityProject/Tactility

Length of output: 240


🏁 Script executed:

git ls-files | grep -E "(View\.(cpp|h)|lvgl)" | head -20

Repository: TactilityProject/Tactility

Length of output: 1174


🏁 Script executed:

find . -type f -name "*.cpp" -o -name "*.h" | grep -i view | head -10

Repository: TactilityProject/Tactility

Length of output: 562


🏁 Script executed:

find ./Tactility/Source/app/files -type f | head -20

Repository: TactilityProject/Tactility

Length of output: 236


🏁 Script executed:

wc -l ./Tactility/Source/app/files/View.cpp

Repository: TactilityProject/Tactility

Length of output: 111


🏁 Script executed:

sed -n '470,490p' ./Tactility/Source/app/files/View.cpp

Repository: TactilityProject/Tactility

Length of output: 246


🏁 Script executed:

sed -n '1,100p' ./Tactility/Source/app/files/View.cpp

Repository: TactilityProject/Tactility

Length of output: 3316


🏁 Script executed:

cat -n ./Tactility/Source/app/files/View.cpp | sed -n '150,250p'

Repository: TactilityProject/Tactility

Length of output: 4228


🏁 Script executed:

cat -n ./Tactility/Source/app/files/View.cpp | sed -n '250,350p'

Repository: TactilityProject/Tactility

Length of output: 4818


🏁 Script executed:

cat -n ./Tactility/Source/app/files/View.cpp | sed -n '350,450p'

Repository: TactilityProject/Tactility

Length of output: 4513


🏁 Script executed:

cat -n ./Tactility/Source/app/files/View.cpp | sed -n '450,479p'

Repository: TactilityProject/Tactility

Length of output: 1154


🏁 Script executed:

cat -n ./Tactility/Private/Tactility/app/files/View.h | head -80

Repository: TactilityProject/Tactility

Length of output: 1710


🏁 Script executed:

rg "lv_obj_remove_event_cb|deinit" --type-list | head -20

Repository: TactilityProject/Tactility

Length of output: 459


🏁 Script executed:

rg "lv_obj_remove_event_cb" -A 2 -B 2

Repository: TactilityProject/Tactility

Length of output: 749


🏁 Script executed:

rg "getSyncLock" -A 2 -B 2 | head -60

Repository: TactilityProject/Tactility

Length of output: 3989


🏁 Script executed:

rg "void.*deinit" -A 5 | head -60

Repository: TactilityProject/Tactility

Length of output: 3847


🏁 Script executed:

find . -type f -name "*.cpp" -o -name "*.h" | xargs rg "lv_obj_add_event_cb|lv_obj_remove_event_cb" | head -30

Repository: TactilityProject/Tactility

Length of output: 4386


🏁 Script executed:

rg "lv_obj_remove_event_cb" -B 5 -A 5

Repository: TactilityProject/Tactility

Length of output: 1357


🏁 Script executed:

find . -type f \( -name "*.cpp" -o -name "*.h" \) -exec grep -l "deinit" {} \; | grep -i view | head -10

Repository: TactilityProject/Tactility

Length of output: 154


🏁 Script executed:

cat ./Tactility/Private/Tactility/app/files/View.h

Repository: TactilityProject/Tactility

Length of output: 1360


🏁 Script executed:

cat -n ./Tactility/Source/app/files/FilesApp.cpp

Repository: TactilityProject/Tactility

Length of output: 1641


🏁 Script executed:

rg "View::" ./Tactility/Source/app/files/ -A 3 -B 3

Repository: TactilityProject/Tactility

Length of output: 8084


🏁 Script executed:

find . -type f -name "*.h" | xargs grep -l "LvglSync\|getSyncLock" | head -5

Repository: TactilityProject/Tactility

Length of output: 115


🏁 Script executed:

cat ./Tactility/Include/Tactility/lvgl/LvglSync.h 2>/dev/null || cat ./Tactility/Private/Tactility/lvgl/LvglSync.h 2>/dev/null || find . -name "LvglSync.h"

Repository: TactilityProject/Tactility

Length of output: 1010


🏁 Script executed:

rg "lv_obj_add_flag|lv_obj_remove_flag" -B 2 -A 2 | head -50

Repository: TactilityProject/Tactility

Length of output: 3130


🏁 Script executed:

rg "LOG_MESSAGE_MUTEX_LOCK_FAILED_FMT" -B 2 -A 2

Repository: TactilityProject/Tactility

Length of output: 7531


🏁 Script executed:

find . -type f -name "*.h" | xargs grep -l "class App" | grep -i app | head -5

Repository: TactilityProject/Tactility

Length of output: 297


🏁 Script executed:

rg "onShow|onHide" --type-list | head -1 || rg "onShow.*{" -A 5 -B 5 | head -40

Repository: TactilityProject/Tactility

Length of output: 459


🏁 Script executed:

cat ./Tactility/Include/Tactility/app/App.h

Repository: TactilityProject/Tactility

Length of output: 3528


Add LVGL lock + null guard in deinit to match the pattern used in other methods.

lv_obj_remove_event_cb is called without the LVGL sync lock, inconsistent with update(), onNavigate(), and onDirEntryListScrollBegin() which all acquire the lock before any LVGL operations. Additionally, there is no null guard for dir_entry_list. While the app lifecycle ensures init is called before deinit, adding defensive checks prevents crashes if the code is refactored.

🛠️ Proposed fix
 void View::deinit(const AppContext& appContext) {
-    lv_obj_remove_event_cb(dir_entry_list, dirEntryListScrollBeginCallback);
+    if (dir_entry_list == nullptr) {
+        return;
+    }
+    auto scoped_lockable = lvgl::getSyncLock()->asScopedLock();
+    if (scoped_lockable.lock(lvgl::defaultLockTime)) {
+        lv_obj_remove_event_cb(dir_entry_list, dirEntryListScrollBeginCallback);
+    } else {
+        LOGGER.error(LOG_MESSAGE_MUTEX_LOCK_FAILED_FMT, "lvgl");
+    }
 }

Comment on lines +6 to 10
AppLaunchId tt_app_alertdialog_start(const char* title, const char* message, const char* buttonLabels[], uint32_t buttonLabelCount) {
std::vector<std::string> list;
for (int i = 0; i < buttonLabelCount; i++) {
list.emplace_back(buttonLabels[i]);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Validate buttonLabels when buttonLabelCount > 0 and avoid signed/unsigned loop mismatch.

Line 9 dereferences buttonLabels[i] without guarding; if a caller passes a non‑zero count with a null array (or null elements), this will crash. Also, Line 8 mixes int with uint32_t. A small guard and unsigned loop index removes both risks.

✅ Suggested fix
 AppLaunchId tt_app_alertdialog_start(const char* title, const char* message, const char* buttonLabels[], uint32_t buttonLabelCount) {
     std::vector<std::string> list;
-    for (int i = 0; i < buttonLabelCount; i++) {
-        list.emplace_back(buttonLabels[i]);
-    }
+    if (buttonLabelCount > 0 && buttonLabels == nullptr) {
+        return AppLaunchId{};
+    }
+    for (uint32_t i = 0; i < buttonLabelCount; ++i) {
+        const char* label = buttonLabels[i];
+        list.emplace_back(label ? label : "");
+    }
     return tt::app::alertdialog::start(title, message, list);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
AppLaunchId tt_app_alertdialog_start(const char* title, const char* message, const char* buttonLabels[], uint32_t buttonLabelCount) {
std::vector<std::string> list;
for (int i = 0; i < buttonLabelCount; i++) {
list.emplace_back(buttonLabels[i]);
}
AppLaunchId tt_app_alertdialog_start(const char* title, const char* message, const char* buttonLabels[], uint32_t buttonLabelCount) {
std::vector<std::string> list;
if (buttonLabelCount > 0 && buttonLabels == nullptr) {
return AppLaunchId{};
}
for (uint32_t i = 0; i < buttonLabelCount; ++i) {
const char* label = buttonLabels[i];
list.emplace_back(label ? label : "");
}
return tt::app::alertdialog::start(title, message, list);
}

Comment on lines +6 to 10
AppLaunchId tt_app_selectiondialog_start(const char* title, int argc, const char* argv[]) {
std::vector<std::string> list;
for (int i = 0; i < argc; i++) {
list.emplace_back(argv[i]);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Guard argv when argc > 0 to prevent null dereference.

Line 9 unconditionally dereferences argv[i]. If a caller passes a non‑zero count with a null array (or null elements), this crashes. Please add a defensive guard consistent with your C API error handling.

✅ Suggested fix
 AppLaunchId tt_app_selectiondialog_start(const char* title, int argc, const char* argv[]) {
     std::vector<std::string> list;
+    if (argc > 0 && argv == nullptr) {
+        return AppLaunchId{};
+    }
     for (int i = 0; i < argc; i++) {
-        list.emplace_back(argv[i]);
+        const char* item = argv[i];
+        list.emplace_back(item ? item : "");
     }
     return tt::app::selectiondialog::start(title, list);
 }

Copy link

@coderabbitai coderabbitai bot left a comment

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 (1)
Devices/guition-jc3248w535c/Source/Axs15231b/Axs15231bDisplay.cpp (1)

69-86: Consider making allocationErrorLogged an instance member.

The static bool allocationErrorLogged is shared across all instances of Axs15231bDisplay. While unlikely in practice (typically one display), if multiple instances existed, the flag would suppress error logs for subsequent instances even if they experience allocation failures independently.

💡 Suggested refactor

Move to class member in the header:

bool tempBufAllocationErrorLogged = false;

Then in the callback:

-        static bool allocationErrorLogged = false;
         if (self->tempBuf == nullptr) {
             self->tempBuf = (uint16_t *)heap_caps_malloc(...);
             if (self->tempBuf == nullptr) {
-                if (!allocationErrorLogged) {
+                if (!self->tempBufAllocationErrorLogged) {
                     LOGGER.error("Failed to allocate rotation buffer, drawing unrotated");
-                    allocationErrorLogged = true;
+                    self->tempBufAllocationErrorLogged = true;
                 }

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant