From 12801409da60d35c56b44a67aa224691c2ad5c6f Mon Sep 17 00:00:00 2001 From: philmoz Date: Fri, 5 Dec 2025 12:17:59 +1100 Subject: [PATCH] fix(color): rotary encoder may not work after editing a telemetry sensor (#6852) --- .../gui/colorlcd/libui/fullscreen_dialog.cpp | 3 +- radio/src/gui/colorlcd/libui/layer.cpp | 22 +++++----- radio/src/gui/colorlcd/libui/layer.h | 3 +- radio/src/gui/colorlcd/libui/modal_window.cpp | 9 +---- radio/src/gui/colorlcd/libui/modal_window.h | 1 - radio/src/gui/colorlcd/libui/page.cpp | 11 +---- radio/src/gui/colorlcd/libui/page.h | 2 - radio/src/gui/colorlcd/libui/window.cpp | 40 ++++++++++++++----- radio/src/gui/colorlcd/libui/window.h | 5 +++ radio/src/gui/colorlcd/mainview/topbar.cpp | 4 +- radio/src/gui/colorlcd/mainview/view_main.cpp | 3 +- .../gui/colorlcd/mainview/widgets_setup.cpp | 5 +-- .../gui/colorlcd/setup_menus/pagegroup.cpp | 13 +----- .../src/gui/colorlcd/setup_menus/pagegroup.h | 2 - .../gui/colorlcd/setup_menus/quick_menu.cpp | 4 +- .../setup_menus/quick_menu_favorites.cpp | 5 +-- radio/src/gui/colorlcd/standalone_lua.cpp | 10 ++--- 17 files changed, 64 insertions(+), 78 deletions(-) diff --git a/radio/src/gui/colorlcd/libui/fullscreen_dialog.cpp b/radio/src/gui/colorlcd/libui/fullscreen_dialog.cpp index b816cceec..d4df80d13 100644 --- a/radio/src/gui/colorlcd/libui/fullscreen_dialog.cpp +++ b/radio/src/gui/colorlcd/libui/fullscreen_dialog.cpp @@ -45,7 +45,7 @@ FullScreenDialog::FullScreenDialog( // In case alert raised while splash screen is showing. cancelSplash(); - Layer::push(this); + pushLayer(); bringToTop(); @@ -156,7 +156,6 @@ void FullScreenDialog::deleteLater(bool detach, bool trash) running = false; } else { Window::deleteLater(detach, trash); - Layer::pop(this); } } diff --git a/radio/src/gui/colorlcd/libui/layer.cpp b/radio/src/gui/colorlcd/libui/layer.cpp index fba8468d4..f9f3ff706 100644 --- a/radio/src/gui/colorlcd/libui/layer.cpp +++ b/radio/src/gui/colorlcd/libui/layer.cpp @@ -20,7 +20,7 @@ std::list Layer::stack; -Layer::Layer(Window* w, lv_group_t* g) : window(w), group(g) {} +Layer::Layer(Window* w, lv_group_t* g, lv_group_t* pg) : window(w), group(g), prevGroup(pg) {} Layer::~Layer() { lv_group_del(group); } void _assign_lv_group(lv_group_t* g) @@ -37,12 +37,15 @@ void _assign_lv_group(lv_group_t* g) void Layer::push(Window* w) { + // save prev group + auto pg = lv_group_get_default(); + // create a new group auto g = lv_group_create(); _assign_lv_group(g); // and store - stack.emplace_back(w, g); + stack.emplace_back(w, g, pg); } void Layer::pop(Window* w) @@ -50,6 +53,14 @@ void Layer::pop(Window* w) if (stack.empty()) return; if (back() == w) { + lv_group_t* prevGroup = stack.back().prevGroup; + if (prevGroup) { + _assign_lv_group(prevGroup); + } else if (!stack.empty()) { + _assign_lv_group(stack.back().group); + } else { + lv_group_set_default(NULL); + } stack.pop_back(); } else { for (auto layer = stack.crbegin(); layer != stack.crend(); layer++) { @@ -60,13 +71,6 @@ void Layer::pop(Window* w) } return; } - - if (!stack.empty()) { - lv_group_t* g = stack.back().group; - _assign_lv_group(g); - } else { - lv_group_set_default(NULL); - } } Window* Layer::back() diff --git a/radio/src/gui/colorlcd/libui/layer.h b/radio/src/gui/colorlcd/libui/layer.h index e5d4b10d4..d00e4da5a 100644 --- a/radio/src/gui/colorlcd/libui/layer.h +++ b/radio/src/gui/colorlcd/libui/layer.h @@ -26,9 +26,10 @@ class Layer Window* window; lv_group_t* group; + lv_group_t* prevGroup; public: - explicit Layer(Window* w, lv_group_t* g); + explicit Layer(Window* w, lv_group_t* g, lv_group_t* pg); ~Layer(); static void push(Window* window); diff --git a/radio/src/gui/colorlcd/libui/modal_window.cpp b/radio/src/gui/colorlcd/libui/modal_window.cpp index 804875c5e..b8ac01af7 100644 --- a/radio/src/gui/colorlcd/libui/modal_window.cpp +++ b/radio/src/gui/colorlcd/libui/modal_window.cpp @@ -51,14 +51,7 @@ ModalWindow::ModalWindow(bool closeWhenClickOutside) : closeWhenClickOutside(closeWhenClickOutside) { setWindowFlag(OPAQUE); - Layer::push(this); -} - -void ModalWindow::deleteLater(bool detach, bool trash) -{ - if (_deleted) return; - Window::deleteLater(detach, trash); - Layer::pop(this); + pushLayer(); } void ModalWindow::onClicked() diff --git a/radio/src/gui/colorlcd/libui/modal_window.h b/radio/src/gui/colorlcd/libui/modal_window.h index a8eafd485..4fcd4694f 100644 --- a/radio/src/gui/colorlcd/libui/modal_window.h +++ b/radio/src/gui/colorlcd/libui/modal_window.h @@ -35,7 +35,6 @@ class ModalWindow : public Window } void onClicked() override; - void deleteLater(bool detach = true, bool trash = true) override; protected: bool closeWhenClickOutside; diff --git a/radio/src/gui/colorlcd/libui/page.cpp b/radio/src/gui/colorlcd/libui/page.cpp index 991e69a07..293661e63 100644 --- a/radio/src/gui/colorlcd/libui/page.cpp +++ b/radio/src/gui/colorlcd/libui/page.cpp @@ -100,20 +100,11 @@ Page::Page(EdgeTxIcon icon, PaddingSize padding, bool pauseRefresh) : LV_PART_MAIN); etx_scrollbar(body->getLvObj()); - Layer::back()->hide(); - Layer::push(this); + pushLayer(true); body->padAll(padding); } -void Page::deleteLater(bool detach, bool trash) -{ - NavWindow::deleteLater(detach, trash); - - Layer::pop(this); - Layer::back()->show(); -} - void Page::openMenu() { PageGroup* p = (PageGroup*)Layer::getPageGroup(); diff --git a/radio/src/gui/colorlcd/libui/page.h b/radio/src/gui/colorlcd/libui/page.h index 424fb51a5..63e263ae9 100644 --- a/radio/src/gui/colorlcd/libui/page.h +++ b/radio/src/gui/colorlcd/libui/page.h @@ -54,8 +54,6 @@ class Page : public NavWindow void onCancel() override; void onClicked() override; - void deleteLater(bool detach = true, bool trash = true) override; - void enableRefresh(); void openMenu(); diff --git a/radio/src/gui/colorlcd/libui/window.cpp b/radio/src/gui/colorlcd/libui/window.cpp index 80447a99c..b0dcf11b0 100644 --- a/radio/src/gui/colorlcd/libui/window.cpp +++ b/radio/src/gui/colorlcd/libui/window.cpp @@ -22,6 +22,7 @@ #include "form.h" #include "static.h" #include "etx_lv_theme.h" +#include "layer.h" std::list Window::trash; bool Window::_longPressed = false; @@ -196,6 +197,26 @@ std::string Window::getWindowDebugString(const char *name) const } #endif +void Window::pushLayer(bool hideParent) +{ + if (!layerCreated) { + parentHidden = hideParent; + layerCreated = true; + if (parentHidden) Layer::back()->hide(); + Layer::push(this); + } +} + +void Window::popLayer() +{ + if (layerCreated) { + Layer::pop(this); + if (parentHidden) Layer::back()->show(); + layerCreated = false; + parentHidden = false; + } +} + Window *Window::getFullScreenWindow() { if (width() == LCD_W && height() == LCD_H) return this; @@ -237,26 +258,25 @@ void Window::detach() void Window::deleteLater(bool detach, bool trash) { if (_deleted) return; - - TRACE_WINDOWS("Delete %p %s", this, getWindowDebugString().c_str()); - _deleted = true; - if (closeHandler) { - closeHandler(); - } + TRACE_WINDOWS("Delete %p %s", this, getWindowDebugString().c_str()); if (detach) this->detach(); else parent = nullptr; - if (trash) { - Window::trash.push_back(this); - } - deleteChildren(); + popLayer(); + + if (closeHandler) + closeHandler(); + + if (trash) + Window::trash.push_back(this); + if (lvobj != nullptr) { auto obj = lvobj; lvobj = nullptr; diff --git a/radio/src/gui/colorlcd/libui/window.h b/radio/src/gui/colorlcd/libui/window.h index 9b730c5a5..61d558adb 100644 --- a/radio/src/gui/colorlcd/libui/window.h +++ b/radio/src/gui/colorlcd/libui/window.h @@ -192,6 +192,9 @@ class Window void disableForcedScroll() { noForcedScroll = true; } + void pushLayer(bool hideParent = false); + void popLayer(); + protected: static std::list trash; @@ -210,6 +213,8 @@ class Window static bool _longPressed; bool loaded = false; + bool layerCreated = false; + bool parentHidden = false; CloseHandler closeHandler; FocusHandler focusHandler; diff --git a/radio/src/gui/colorlcd/mainview/topbar.cpp b/radio/src/gui/colorlcd/mainview/topbar.cpp index ad91036b1..4212e11c0 100644 --- a/radio/src/gui/colorlcd/mainview/topbar.cpp +++ b/radio/src/gui/colorlcd/mainview/topbar.cpp @@ -76,7 +76,7 @@ SetupTopBarWidgetsPage::SetupTopBarWidgetsPage() : Window(ViewMain::instance(), rect_t{}) { // remember focus - Layer::push(this); + pushLayer(); auto viewMain = ViewMain::instance(); @@ -109,8 +109,6 @@ void SetupTopBarWidgetsPage::deleteLater(bool detach, bool trash) // and continue async deletion... Window::deleteLater(detach, trash); - Layer::pop(this); - // restore screen setting tab on top QuickMenu::openPage(QM_UI_SETUP); diff --git a/radio/src/gui/colorlcd/mainview/view_main.cpp b/radio/src/gui/colorlcd/mainview/view_main.cpp index bc36cdee2..83f85fc20 100644 --- a/radio/src/gui/colorlcd/mainview/view_main.cpp +++ b/radio/src/gui/colorlcd/mainview/view_main.cpp @@ -79,7 +79,7 @@ ViewMain* ViewMain::_instance = nullptr; ViewMain::ViewMain() : NavWindow(MainWindow::instance(), MainWindow::instance()->getRect()) { - Layer::push(this); + pushLayer(); tile_view = lv_tileview_create(lvobj); lv_obj_set_pos(tile_view, rect.x, rect.y); @@ -103,7 +103,6 @@ ViewMain::~ViewMain() { _instance = nullptr; } void ViewMain::deleteLater(bool detach, bool trash) { NavWindow::deleteLater(detach, trash); - Layer::pop(this); QuickMenu::shutdownQuickMenu(); } diff --git a/radio/src/gui/colorlcd/mainview/widgets_setup.cpp b/radio/src/gui/colorlcd/mainview/widgets_setup.cpp index c2a41dbc8..282820e1a 100644 --- a/radio/src/gui/colorlcd/mainview/widgets_setup.cpp +++ b/radio/src/gui/colorlcd/mainview/widgets_setup.cpp @@ -119,7 +119,7 @@ void SetupWidgetsPageSlot::addNewWidget(WidgetsContainer* container, SetupWidgetsPage::SetupWidgetsPage(uint8_t customScreenIdx) : Window(ViewMain::instance(), rect_t{}), customScreenIdx(customScreenIdx) { - Layer::push(this); + pushLayer(); // attach this custom screen here so we can display it auto screen = customScreens[customScreenIdx]; @@ -162,9 +162,6 @@ void SetupWidgetsPage::deleteLater(bool detach, bool trash) { Window::deleteLater(detach, trash); - // restore screen setting tab on top - Layer::pop(this); - // and continue async deletion... auto screen = customScreens[customScreenIdx]; if (screen) { diff --git a/radio/src/gui/colorlcd/setup_menus/pagegroup.cpp b/radio/src/gui/colorlcd/setup_menus/pagegroup.cpp index f4d652ff0..82b899fb5 100644 --- a/radio/src/gui/colorlcd/setup_menus/pagegroup.cpp +++ b/radio/src/gui/colorlcd/setup_menus/pagegroup.cpp @@ -307,8 +307,7 @@ PageGroupBase::PageGroupBase(coord_t bodyY, EdgeTxIcon icon) : { etx_solid_bg(lvobj); - Layer::back()->hide(); - Layer::push(this); + pushLayer(true); body = new Window(this, {0, bodyY, LCD_W, LCD_H - bodyY}); body->setWindowFlag(NO_FOCUS); @@ -332,16 +331,6 @@ void PageGroupBase::checkEvents() ViewMain::instance()->runBackground(); } -void PageGroupBase::deleteLater(bool detach, bool trash) -{ - if (_deleted) return; - - NavWindow::deleteLater(detach, trash); - - Layer::pop(this); - Layer::back()->show(); -} - void PageGroupBase::onClicked() { Keyboard::hide(false); } void PageGroupBase::onCancel() diff --git a/radio/src/gui/colorlcd/setup_menus/pagegroup.h b/radio/src/gui/colorlcd/setup_menus/pagegroup.h index 2eac861e5..9841ccbfa 100644 --- a/radio/src/gui/colorlcd/setup_menus/pagegroup.h +++ b/radio/src/gui/colorlcd/setup_menus/pagegroup.h @@ -198,8 +198,6 @@ class PageGroupBase : public NavWindow void checkEvents() override; - void deleteLater(bool detach = true, bool trash = true) override; - #if defined(HARDWARE_KEYS) void doKeyShortcut(event_t event); void onPressSYS() override; diff --git a/radio/src/gui/colorlcd/setup_menus/quick_menu.cpp b/radio/src/gui/colorlcd/setup_menus/quick_menu.cpp index a768ed75f..adb223e68 100644 --- a/radio/src/gui/colorlcd/setup_menus/quick_menu.cpp +++ b/radio/src/gui/colorlcd/setup_menus/quick_menu.cpp @@ -291,7 +291,7 @@ void QuickMenu::openQM(std::function cancelHandler, std::function selectHandler, PageGroupBase* newPageGroup, QMPage newCurPage) { - Layer::push(this); + pushLayer(); #if VERSION_MAJOR == 2 curPage = QM_NONE; @@ -514,7 +514,7 @@ void QuickMenu::onSelect(bool close) void QuickMenu::closeMenu() { - Layer::pop(this); + popLayer(); hide(); if (cancelHandler) cancelHandler(); cancelHandler = nullptr; diff --git a/radio/src/gui/colorlcd/setup_menus/quick_menu_favorites.cpp b/radio/src/gui/colorlcd/setup_menus/quick_menu_favorites.cpp index 5a39dffd5..573aa121f 100644 --- a/radio/src/gui/colorlcd/setup_menus/quick_menu_favorites.cpp +++ b/radio/src/gui/colorlcd/setup_menus/quick_menu_favorites.cpp @@ -60,13 +60,12 @@ QMFavoritesPage::QMFavoritesPage(): void QMFavoritesPage::onCancel() { + SubPage::onCancel(); + if (changed) { // Delete quick menu, and close parent page group (in case it is Favorites group) QuickMenu::shutdownQuickMenu(); QuickMenu::setCurrentPage(QM_NONE); - Layer::pop(this); Layer::back()->onCancel(); } - - SubPage::onCancel(); } diff --git a/radio/src/gui/colorlcd/standalone_lua.cpp b/radio/src/gui/colorlcd/standalone_lua.cpp index 170776c77..30df57f57 100644 --- a/radio/src/gui/colorlcd/standalone_lua.cpp +++ b/radio/src/gui/colorlcd/standalone_lua.cpp @@ -193,8 +193,7 @@ void StandaloneLuaWindow::attach() // backup previous screen prevScreen = lv_scr_act(); - Layer::back()->hide(); - Layer::push(this); + pushLayer(true); if (!useLvglLayout()) { lv_group_add_obj(lv_group_get_default(), lvobj); @@ -218,11 +217,6 @@ void StandaloneLuaWindow::deleteLater(bool detach, bool trash) luaScriptManager = nullptr; - Window::deleteLater(detach, trash); - - Layer::pop(this); - Layer::back()->show(); - if (prevScreen) { prevScreen = nullptr; } @@ -238,6 +232,8 @@ void StandaloneLuaWindow::deleteLater(bool detach, bool trash) luaState = prevLuaState; luaEmptyEventBuffer(); + + Window::deleteLater(detach, trash); } void StandaloneLuaWindow::checkEvents()