perf(l2): no redraws while nothing changes

Found by counting flushes on idle screens in the sim:
- The compose field's cursor blinked (a redraw every 400 ms) as soon as
  a conversation opened, the keyboard hidden: lv_keyboard_set_textarea()
  focuses the field, and LVGL only stops a blink when the cursor moves.
  fieldFocus() sets the state and nudges the blink; also used for the
  WiFi and channel fields, which left theirs running.
- lv_obj_align_to() restyles on every call, so the status bar's icons
  redrew every second; placeLeftOf() moves them only when they move.
- Text colours set every second (nav bar, GPS status, Diag errors) go
  through setTextColor(), which skips an unchanged colour.
- A LV_LABEL_LONG_DOT label writes its "..." into its own text, so
  setText() never matched and rewrote it every refresh (the nav bar's
  hint); labelShows() reads past the dots.
- The map area, the area-outline, trail and vector-label layers were
  invalidated on every map refresh (every 3 s, a full-map redraw); now
  only when the view or what they draw changed.

Idle map: 17 -> 1 flush in 5 s; list and settings screens: 0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-09-30 23:22:31 +02:00
co-authored by Claude Opus 5.5
parent 74efb6addd
commit 1ff58d4a81
10 changed files with 102 additions and 43 deletions
@@ -152,10 +152,10 @@ static void wifiRebuild(UITask* ui, lv_obj_t*& body) {
void UITask::wifiEdit(lv_obj_t* ta) {
if (!_wifi_kb) return;
lv_obj_remove_state(_wifi_ssid, LV_STATE_FOCUSED);
lv_obj_remove_state(_wifi_pass, LV_STATE_FOCUSED);
lv_obj_add_state(ta, LV_STATE_FOCUSED); // draws the cursor
fieldFocus(_wifi_ssid, false);
fieldFocus(_wifi_pass, false);
lv_keyboard_set_textarea(_wifi_kb, ta);
fieldFocus(ta, true);
if (lv_obj_has_flag(_wifi_kb, LV_OBJ_FLAG_HIDDEN)) {
lv_obj_remove_flag(_wifi_kb, LV_OBJ_FLAG_HIDDEN);
if (_body) lv_obj_set_height(_body, lv_obj_get_height(_body) - lv_obj_get_height(_wifi_kb));
@@ -167,8 +167,8 @@ void UITask::wifiEdit(lv_obj_t* ta) {
void UITask::wifiKeyboardHide() {
if (!_wifi_kb || lv_obj_has_flag(_wifi_kb, LV_OBJ_FLAG_HIDDEN)) return;
lv_obj_add_flag(_wifi_kb, LV_OBJ_FLAG_HIDDEN);
lv_obj_remove_state(_wifi_ssid, LV_STATE_FOCUSED);
lv_obj_remove_state(_wifi_pass, LV_STATE_FOCUSED);
fieldFocus(_wifi_ssid, false);
fieldFocus(_wifi_pass, false);
if (_body) lv_obj_set_height(_body, lv_obj_get_height(_body) + lv_obj_get_height(_wifi_kb));
}