fix(settings): don't auto-scroll to bottom on screen entry

LVGL re-focuses the default input group when the screen is shown; the
focused member is the last focusable object (the transport switch), so
the view landed at the bottom of the list. A one-shot 50ms LVGL timer
after show() scrolls the content back to the top without touching the
focus state, and leaves subsequent user scrolling alone.
This commit is contained in:
Torlando committed 2026-09-04 05:52:56 +00:00
1 parent 28ea218a18
commit f62f465958
2 files changed
+30

No files matched your search

+28
View File
@@ -17,6 +17,14 @@ using namespace RNS;
namespace UI {
namespace LXMF {
// One-shot scroll reset: when LVGL re-focuses the default input group on
// screen entry it scrolls the view to the focused member (the last
// focusable object — the transport switch), which lands the user at the
// bottom of the list. A short delay after show() puts the view back at the
// top; later scrolling is left to the user.
static SettingsScreen* g_settings_entry_reset = nullptr;
lv_timer_t* SettingsScreen::_entry_scroll_reset_timer = nullptr;
// NVS keys
static const char* NVS_NAMESPACE = "settings";
static const char* KEY_WIFI_SSID = "wifi_ssid";
@@ -1401,6 +1409,17 @@ void SettingsScreen::set_status_callback(StatusScreenCallback callback) {
_status_callback = callback;
}
void SettingsScreen::entry_scroll_reset_cb(lv_timer_t* timer) {
lv_timer_del(timer);
SettingsScreen* screen = g_settings_entry_reset;
g_settings_entry_reset = nullptr;
if (!screen || !screen->_content) return;
LVGL_LOCK();
if (lv_obj_is_visible(screen->_screen)) {
lv_obj_scroll_to_y(screen->_content, 0, LV_ANIM_OFF);
}
}
void SettingsScreen::show() {
LVGL_LOCK();
lv_obj_clear_flag(_screen, LV_OBJ_FLAG_HIDDEN);
@@ -1417,6 +1436,15 @@ void SettingsScreen::show() {
lv_group_focus_obj(_btn_back);
}
}
// Counter the group re-focus auto-scroll (see entry_scroll_reset_cb).
// show() already holds the LVGL lock, so timer creation here is safe.
g_settings_entry_reset = this;
if (!_entry_scroll_reset_timer) {
_entry_scroll_reset_timer = lv_timer_create(entry_scroll_reset_cb, 50, nullptr);
} else {
lv_timer_reset(_entry_scroll_reset_timer);
}
}
void SettingsScreen::hide() {
+2
View File
@@ -340,6 +340,8 @@ private:
static void on_transport_cancel_enable(lv_event_t* event);
void show_transport_warning();
void close_transport_warning();
static lv_timer_t* _entry_scroll_reset_timer;
static void entry_scroll_reset_cb(lv_timer_t* timer);
};
} // namespace LXMF