Keep a slider's value when you let go, and stop needless full resends (0.2.55)
A light's colour slider on Studio 1 sometimes sent red on release. Measured live: an automation with a state trigger on a six-lamp group (no `to:`) set "Standby after" to its current value after every colour change. The screen reported the setting, ESP Screen Manager saved the layout and resent layout, header and every tile state, and the screen drew its whole page again, reading no touch input meanwhile. The GT911's stray (0, 0) contact then became the finger's last position, and LVGL 9.5 set the slider from it on release. Both red commits left 75-85 ms after such a resync. The app no longer saves or resends a setting event whose value the layout already has. The four setting numbers return before the preference write and the event when nothing changed. A layout message that changes nothing on the screen no longer runs layout_changed() and refresh_all(); the tile states after it redraw their own tiles. The Guition wraps the LVGL touch read callback with cyd::GhostTouch, which repeats the previous read for a pressed (0, 0), and the edge swipe skips that sample too. Both slider handlers log a jump to an end on release. Checked with 214 Python and 14 C++ tests, generate_packages --check, and ESP32 builds of both Easy profiles. Firmware 0.2.47. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+11
-1
@@ -18,7 +18,7 @@
|
||||
############################################################
|
||||
|
||||
substitutions:
|
||||
SCREEN_FIRMWARE_VERSION: "0.2.46"
|
||||
SCREEN_FIRMWARE_VERSION: "0.2.47"
|
||||
# A tap survives a finger that drifts up to this far (320 px over 58 mm: 1 cm); further is a swipe.
|
||||
TOUCH_MOVE_LIMIT_PX: "56"
|
||||
# Shortest contact that counts as a tap; a resistive panel bounces, a capacitive one does not.
|
||||
@@ -4537,9 +4537,13 @@ number:
|
||||
set_action:
|
||||
- lambda: |-
|
||||
auto &s = screen_settings::current;
|
||||
const auto before = s;
|
||||
s.brightness = (int)x;
|
||||
s.standby_brightness = std::min(s.standby_brightness,s.brightness);
|
||||
s.night_brightness = std::min(s.night_brightness,s.brightness);
|
||||
// The value the screen already has (an automation that sets it on every light change):
|
||||
// no flash write, no event, so ESP Screen Manager does not resend the whole screen.
|
||||
if (s == before) return;
|
||||
if (runtime_tiles::enabled) runtime_tiles::settings_preference.save(&s);
|
||||
runtime_tiles::setting_event("brightness",s.brightness);
|
||||
id(apply_screen_settings).execute();
|
||||
@@ -4556,9 +4560,11 @@ number:
|
||||
set_action:
|
||||
- lambda: |-
|
||||
auto &s = screen_settings::current;
|
||||
const auto before = s;
|
||||
s.standby_brightness = (int)x;
|
||||
s.standby_brightness = std::min(s.standby_brightness,s.brightness);
|
||||
s.night_brightness = std::min(s.night_brightness,s.brightness);
|
||||
if (s == before) return;
|
||||
if (runtime_tiles::enabled) runtime_tiles::settings_preference.save(&s);
|
||||
runtime_tiles::setting_event("standby_brightness",s.standby_brightness);
|
||||
id(apply_screen_settings).execute();
|
||||
@@ -4575,9 +4581,11 @@ number:
|
||||
set_action:
|
||||
- lambda: |-
|
||||
auto &s = screen_settings::current;
|
||||
const auto before = s;
|
||||
s.night_brightness = (int)x;
|
||||
s.standby_brightness = std::min(s.standby_brightness,s.brightness);
|
||||
s.night_brightness = std::min(s.night_brightness,s.brightness);
|
||||
if (s == before) return;
|
||||
if (runtime_tiles::enabled) runtime_tiles::settings_preference.save(&s);
|
||||
runtime_tiles::setting_event("night_brightness",s.night_brightness);
|
||||
id(apply_screen_settings).execute();
|
||||
@@ -4594,9 +4602,11 @@ number:
|
||||
set_action:
|
||||
- lambda: |-
|
||||
auto &s = screen_settings::current;
|
||||
const auto before = s;
|
||||
s.standby_seconds = (int)x;
|
||||
s.standby_brightness = std::min(s.standby_brightness,s.brightness);
|
||||
s.night_brightness = std::min(s.night_brightness,s.brightness);
|
||||
if (s == before) return;
|
||||
if (runtime_tiles::enabled) runtime_tiles::settings_preference.save(&s);
|
||||
runtime_tiles::setting_event("standby_seconds",s.standby_seconds);
|
||||
id(apply_screen_settings).execute();
|
||||
|
||||
+33
-1
@@ -3,7 +3,7 @@
|
||||
# Source profile for packages/guition.yaml (tools/generate_packages.py); see docs/GUITION.md.
|
||||
# A screen gets its tiles from the ESP Screen Manager add-on while it runs. The CYD is its own profile.
|
||||
substitutions:
|
||||
SCREEN_FIRMWARE_VERSION: "0.2.46"
|
||||
SCREEN_FIRMWARE_VERSION: "0.2.47"
|
||||
# 0: no drift limit; LVGL decides, releasing inside the tile is a tap, leaving it is not
|
||||
# (like iOS). The CYD keeps a limit because its resistive panel jumps.
|
||||
TOUCH_MOVE_LIMIT_PX: "0"
|
||||
@@ -146,6 +146,26 @@ esphome:
|
||||
// starving the touch polling for the whole length of a quick swipe.
|
||||
lv_obj_remove_flag(id(home_page)->obj, LV_OBJ_FLAG_CLICKABLE);
|
||||
lv_obj_remove_flag(id(tile_scroll), LV_OBJ_FLAG_CLICKABLE);
|
||||
// A stray GT911 contact at exactly (0, 0) never reaches LVGL (cyd::GhostTouch): as the last
|
||||
// sample of a drag it sent a slider to its end on release. LVGL still reads ESPHome's callback.
|
||||
if (auto *indev = lv_indev_get_next(nullptr)) {
|
||||
static lv_indev_read_cb_t esphome_read = nullptr;
|
||||
static const lv_indev_read_cb_t filtered = [](lv_indev_t *input, lv_indev_data_t *data) {
|
||||
esphome_read(input, data);
|
||||
int32_t ghost_x = 0, ghost_y = 0;
|
||||
id(screen_lvgl).rotate_coordinates(ghost_x, ghost_y);
|
||||
const unsigned dropped = cyd::ghost_touch.dropped();
|
||||
const auto read = cyd::ghost_touch.filter({data->state == LV_INDEV_STATE_PRESSED, (int) data->point.x, (int) data->point.y}, ghost_x, ghost_y);
|
||||
if (cyd::ghost_touch.dropped() != dropped) ESP_LOGI("touch", "GT911 stray contact at (0,0) ignored");
|
||||
data->state = read.pressed ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
|
||||
data->point.x = read.x;
|
||||
data->point.y = read.y;
|
||||
};
|
||||
if (lv_indev_get_read_cb(indev) != filtered) {
|
||||
esphome_read = lv_indev_get_read_cb(indev);
|
||||
lv_indev_set_read_cb(indev, filtered);
|
||||
}
|
||||
}
|
||||
id(last_touch_ms) = millis();
|
||||
id(display_dimmed) = false;
|
||||
- lambda: |-
|
||||
@@ -1118,6 +1138,8 @@ touchscreen:
|
||||
// Trace every sample of an edge touch: the log then shows how often the panel delivers.
|
||||
if (cyd::edge_swipe.armed())
|
||||
ESP_LOGI("touch", "swipe id=%u st=%u x=%u y=%u", (unsigned) point.id, (unsigned) point.state, point.x, point.y);
|
||||
// The stray (0, 0) contact (cyd::GhostTouch) is not where the finger went.
|
||||
if (point.x == 0 && point.y == 0) continue;
|
||||
cyd::touch_guard.update(point.x, point.y, point.id);
|
||||
if (point.id != cyd::touch_guard.contact()) continue;
|
||||
// Swiping in from a side edge flips the page ("Swiping between pages"); the tap
|
||||
@@ -4525,9 +4547,13 @@ number:
|
||||
set_action:
|
||||
- lambda: |-
|
||||
auto &s = screen_settings::current;
|
||||
const auto before = s;
|
||||
s.brightness = (int)x;
|
||||
s.standby_brightness = std::min(s.standby_brightness,s.brightness);
|
||||
s.night_brightness = std::min(s.night_brightness,s.brightness);
|
||||
// The value the screen already has (an automation that sets it on every light change):
|
||||
// no flash write, no event, so ESP Screen Manager does not resend the whole screen.
|
||||
if (s == before) return;
|
||||
if (runtime_tiles::enabled) runtime_tiles::settings_preference.save(&s);
|
||||
runtime_tiles::setting_event("brightness",s.brightness);
|
||||
id(apply_screen_settings).execute();
|
||||
@@ -4544,9 +4570,11 @@ number:
|
||||
set_action:
|
||||
- lambda: |-
|
||||
auto &s = screen_settings::current;
|
||||
const auto before = s;
|
||||
s.standby_brightness = (int)x;
|
||||
s.standby_brightness = std::min(s.standby_brightness,s.brightness);
|
||||
s.night_brightness = std::min(s.night_brightness,s.brightness);
|
||||
if (s == before) return;
|
||||
if (runtime_tiles::enabled) runtime_tiles::settings_preference.save(&s);
|
||||
runtime_tiles::setting_event("standby_brightness",s.standby_brightness);
|
||||
id(apply_screen_settings).execute();
|
||||
@@ -4563,9 +4591,11 @@ number:
|
||||
set_action:
|
||||
- lambda: |-
|
||||
auto &s = screen_settings::current;
|
||||
const auto before = s;
|
||||
s.night_brightness = (int)x;
|
||||
s.standby_brightness = std::min(s.standby_brightness,s.brightness);
|
||||
s.night_brightness = std::min(s.night_brightness,s.brightness);
|
||||
if (s == before) return;
|
||||
if (runtime_tiles::enabled) runtime_tiles::settings_preference.save(&s);
|
||||
runtime_tiles::setting_event("night_brightness",s.night_brightness);
|
||||
id(apply_screen_settings).execute();
|
||||
@@ -4582,9 +4612,11 @@ number:
|
||||
set_action:
|
||||
- lambda: |-
|
||||
auto &s = screen_settings::current;
|
||||
const auto before = s;
|
||||
s.standby_seconds = (int)x;
|
||||
s.standby_brightness = std::min(s.standby_brightness,s.brightness);
|
||||
s.night_brightness = std::min(s.night_brightness,s.brightness);
|
||||
if (s == before) return;
|
||||
if (runtime_tiles::enabled) runtime_tiles::settings_preference.save(&s);
|
||||
runtime_tiles::setting_event("standby_seconds",s.standby_seconds);
|
||||
id(apply_screen_settings).execute();
|
||||
|
||||
Reference in New Issue
Block a user