M5Stack PaperS3 improvements and other bug fixes (#512)
This commit is contained in:
@@ -204,7 +204,11 @@ public:
|
||||
lv_obj_set_width(description_label, LV_PCT(100));
|
||||
lv_label_set_long_mode(description_label, LV_LABEL_LONG_MODE_WRAP);
|
||||
if (!entry.appDescription.empty()) {
|
||||
lv_label_set_text(description_label, entry.appDescription.c_str());
|
||||
std::string description = entry.appDescription;
|
||||
for (size_t pos = 0; (pos = description.find("\\n", pos)) != std::string::npos;) {
|
||||
description.replace(pos, 2, "\n");
|
||||
}
|
||||
lv_label_set_text(description_label, description.c_str());
|
||||
} else {
|
||||
lv_label_set_text(description_label, "This app has no description yet.");
|
||||
}
|
||||
|
||||
@@ -275,6 +275,10 @@ void View::onDirEntryPressed(uint32_t index) {
|
||||
}
|
||||
|
||||
void View::onDirEntryLongPressed(int32_t index) {
|
||||
if (state->getCurrentPath() == "/") {
|
||||
return;
|
||||
}
|
||||
|
||||
dirent dir_entry;
|
||||
if (!resolveDirentFromListIndex(index, dir_entry)) {
|
||||
return;
|
||||
@@ -452,7 +456,7 @@ void View::update(size_t start_index) {
|
||||
|
||||
if (!is_root && last_loaded_index < total_entries) {
|
||||
if (total_entries > current_start_index &&
|
||||
+ (total_entries - current_start_index) > MAX_BATCH) {
|
||||
(total_entries - current_start_index) > MAX_BATCH) {
|
||||
auto* next_btn = lv_list_add_btn(dir_entry_list, LV_SYMBOL_RIGHT, "Next");
|
||||
lv_obj_add_event_cb(next_btn, [](lv_event_t* event) {
|
||||
auto* view = static_cast<View*>(lv_event_get_user_data(event));
|
||||
@@ -549,7 +553,7 @@ void View::onResult(LaunchId launchId, Result result, std::unique_ptr<Bundle> bu
|
||||
} else if (file::isFile(filepath)) {
|
||||
auto lock = file::getLock(filepath);
|
||||
lock->lock();
|
||||
if (remove(filepath.c_str()) <= 0) {
|
||||
if (remove(filepath.c_str()) != 0) {
|
||||
LOGGER.warn("Failed to delete {}", filepath);
|
||||
}
|
||||
lock->unlock();
|
||||
|
||||
@@ -48,18 +48,8 @@ class LauncherApp final : public App {
|
||||
lv_obj_set_style_text_font(button_image, lvgl_get_launcher_icon_font(), LV_STATE_DEFAULT);
|
||||
lv_image_set_src(button_image, imageFile);
|
||||
lv_obj_set_style_text_color(button_image, lv_theme_get_color_primary(button_image), LV_STATE_DEFAULT);
|
||||
|
||||
// Recolor handling:
|
||||
// For color builds use theme primary color
|
||||
// For 1-bit/monochrome builds force a visible color (black)
|
||||
#if LV_COLOR_DEPTH == 1
|
||||
// Try forcing black recolor on monochrome builds
|
||||
lv_obj_set_style_image_recolor(button_image, lv_color_black(), LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_image_recolor_opa(button_image, LV_OPA_COVER, LV_STATE_DEFAULT);
|
||||
#else
|
||||
lv_obj_set_style_image_recolor(button_image, lv_theme_get_color_primary(parent), LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_image_recolor_opa(button_image, LV_OPA_COVER, LV_STATE_DEFAULT);
|
||||
#endif
|
||||
|
||||
// Ensure it's square (Material Symbols are slightly wider than tall)
|
||||
lv_obj_set_size(button_image, button_size, button_size);
|
||||
@@ -157,7 +147,7 @@ public:
|
||||
createAppButton(buttons_wrapper, ui_density, LVGL_ICON_LAUNCHER_SETTINGS, "Settings", margin, is_landscape_display);
|
||||
|
||||
if (shouldShowPowerButton()) {
|
||||
auto* power_button = lv_btn_create(parent);
|
||||
auto* power_button = lv_button_create(parent);
|
||||
lv_obj_set_style_pad_all(power_button, 8, 0);
|
||||
lv_obj_align(power_button, LV_ALIGN_BOTTOM_MID, 0, -10);
|
||||
lv_obj_add_event_cb(power_button, onPowerOffPressed, LV_EVENT_SHORT_CLICKED, nullptr);
|
||||
|
||||
@@ -192,8 +192,8 @@ lv_obj_t* statusbar_create(lv_obj_t* parent) {
|
||||
auto* image = lv_image_create(obj);
|
||||
lv_obj_set_size(image, icon_size, icon_size); // regular padding doesn't work
|
||||
lv_obj_set_style_text_font(image, lvgl_get_statusbar_icon_font(), LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_text_color(image, lv_color_white(), LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_pad_all(image, 0, LV_STATE_DEFAULT);
|
||||
obj_set_style_bg_blacken(image);
|
||||
statusbar->icons[i] = image;
|
||||
|
||||
update_icon(image, &(statusbar_data.icons[i]));
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <Tactility/app/App.h>
|
||||
#include <Tactility/hal/sdcard/SdCardDevice.h>
|
||||
#include <Tactility/service/wifi/Wifi.h>
|
||||
#include <esp_wifi_default.h>
|
||||
#include <Tactility/network/HttpdReq.h>
|
||||
#include <Tactility/network/Url.h>
|
||||
#include <Tactility/Paths.h>
|
||||
@@ -400,6 +401,9 @@ bool WebServerService::startApMode() {
|
||||
void WebServerService::stopApMode() {
|
||||
if (apWifiInitialized) {
|
||||
esp_err_t err;
|
||||
if (apNetif != nullptr) {
|
||||
esp_wifi_clear_default_wifi_driver_and_handlers(apNetif);
|
||||
}
|
||||
err = esp_wifi_stop();
|
||||
if (err != ESP_OK && err != ESP_ERR_WIFI_NOT_STARTED) {
|
||||
LOGGER.warn("esp_wifi_stop() in cleanup: {}", esp_err_to_name(err));
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <Tactility/service/wifi/WifiGlobals.h>
|
||||
#include <Tactility/service/wifi/WifiSettings.h>
|
||||
|
||||
#include <esp_wifi_default.h>
|
||||
#include <lwip/esp_netif_net_stack.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <atomic>
|
||||
@@ -537,6 +538,7 @@ static void dispatchEnable(std::shared_ptr<Wifi> wifi) {
|
||||
publish_event(wifi, WifiEvent::RadioStateOnPending);
|
||||
|
||||
if (wifi->netif != nullptr) {
|
||||
esp_wifi_clear_default_wifi_driver_and_handlers(wifi->netif);
|
||||
esp_netif_destroy(wifi->netif);
|
||||
}
|
||||
wifi->netif = esp_netif_create_default_wifi_sta();
|
||||
@@ -633,11 +635,21 @@ static void dispatchDisable(std::shared_ptr<Wifi> wifi) {
|
||||
// Free up scan list memory
|
||||
scan_list_free_safely(wifi_singleton);
|
||||
|
||||
// Detach netif from the internal WiFi event handlers before stopping.
|
||||
// Those handlers call esp_netif_action_stop on WIFI_EVENT_STA_STOP, which
|
||||
// queues esp_netif_stop_api to the lwIP thread. esp_netif_destroy later
|
||||
// queues a second one; the first zeroes lwip_netif, and the second then
|
||||
// crashes in netif_ip6_addr_set_parts (null pointer + 0x263 offset).
|
||||
if (wifi->netif != nullptr) {
|
||||
esp_wifi_clear_default_wifi_driver_and_handlers(wifi->netif);
|
||||
}
|
||||
|
||||
// Note: handlers are already detached above, so we cannot safely return to
|
||||
// RadioState::On from here — the netif would be missing its default WiFi
|
||||
// event handlers and subsequent disable attempts would behave incorrectly.
|
||||
// If stop fails, continue the teardown anyway so we end in a clean Off state.
|
||||
if (esp_wifi_stop() != ESP_OK) {
|
||||
LOGGER.error("Failed to stop radio");
|
||||
wifi->setRadioState(RadioState::On);
|
||||
publish_event(wifi, WifiEvent::RadioStateOn);
|
||||
return;
|
||||
LOGGER.error("Failed to stop radio - continuing teardown");
|
||||
}
|
||||
|
||||
if (esp_wifi_set_mode(WIFI_MODE_NULL) != ESP_OK) {
|
||||
|
||||
Reference in New Issue
Block a user