address transport opt-in review findings

This commit is contained in:
Torlando
2026-08-03 18:14:44 +00:00
parent d75d7370bd
commit 8a72f40198
5 changed files with 60 additions and 7 deletions
+30 -5
View File
@@ -69,7 +69,8 @@ SettingsScreen::SettingsScreen(lv_obj_t* parent)
_slider_lora_power(nullptr), _label_lora_power_value(nullptr),
_lora_params_container(nullptr), _switch_auto_enabled(nullptr), _switch_ble_enabled(nullptr),
_ta_announce_interval(nullptr), _ta_sync_interval(nullptr), _switch_gps_sync(nullptr),
_switch_transport_enabled(nullptr), _transport_warning_modal(nullptr), _transport_enable_confirmed(false),
_switch_transport_enabled(nullptr), _transport_warning_modal(nullptr),
_transport_modal_group(nullptr), _transport_enable_confirmed(false),
_btn_propagation_nodes(nullptr), _switch_prop_fallback(nullptr), _switch_prop_only(nullptr),
_gps(nullptr) {
LVGL_LOCK();
@@ -974,19 +975,43 @@ void SettingsScreen::show_transport_warning() {
lv_label_set_text(confirm_label, "ENABLE ANYWAY");
lv_obj_center(confirm_label);
lv_group_t* group = LVGL::LVGLInit::get_default_group();
if (group) {
lv_group_add_obj(group, cancel);
lv_group_add_obj(group, confirm);
_transport_modal_group = lv_group_create();
if (_transport_modal_group) {
lv_group_add_obj(_transport_modal_group, cancel);
lv_group_add_obj(_transport_modal_group, confirm);
lv_group_focus_obj(cancel);
// Isolate keyboard and trackball focus inside the warning. Otherwise
// users can navigate into and activate Settings controls behind the
// still-visible modal.
lv_indev_t* keyboard = LVGL::LVGLInit::get_keyboard();
lv_indev_t* trackball = LVGL::LVGLInit::get_trackball();
if (keyboard) lv_indev_set_group(keyboard, _transport_modal_group);
if (trackball) lv_indev_set_group(trackball, _transport_modal_group);
}
}
void SettingsScreen::close_transport_warning() {
if (!_transport_warning_modal) return;
lv_group_t* default_group = LVGL::LVGLInit::get_default_group();
lv_indev_t* keyboard = LVGL::LVGLInit::get_keyboard();
lv_indev_t* trackball = LVGL::LVGLInit::get_trackball();
if (keyboard) lv_indev_set_group(keyboard, default_group);
if (trackball) lv_indev_set_group(trackball, default_group);
if (_transport_modal_group) {
lv_group_del(_transport_modal_group);
_transport_modal_group = nullptr;
}
lv_obj_t* modal = _transport_warning_modal;
_transport_warning_modal = nullptr;
lv_obj_del_async(modal);
if (default_group && _switch_transport_enabled) {
lv_group_focus_obj(_switch_transport_enabled);
}
}
void SettingsScreen::load_settings() {
+1
View File
@@ -297,6 +297,7 @@ private:
// Dangerous transport-mode section (must remain last in Settings)
lv_obj_t* _switch_transport_enabled;
lv_obj_t* _transport_warning_modal;
lv_group_t* _transport_modal_group;
bool _transport_enable_confirmed;
// Delivery/Propagation section
+23 -2
View File
@@ -48,6 +48,8 @@ def mirror(src: Path, dst: Path):
return False
src_files = 0
copied = 0
removed = 0
mirrored_paths = set()
for root, dirs, files in os.walk(src):
# Skip git, build artifacts.
dirs[:] = [d for d in dirs if d not in (".git", ".pio", "__pycache__", "build")]
@@ -57,6 +59,7 @@ def mirror(src: Path, dst: Path):
continue
sp = Path(root) / fn
dp = dst / rel / fn
mirrored_paths.add((rel / fn).as_posix())
src_files += 1
# A freshly fetched dependency can have a newer mtime than an older
# local checkout even when the local bytes contain the intended fix.
@@ -68,8 +71,26 @@ def mirror(src: Path, dst: Path):
# incremental PlatformIO builds recompile changed dependency code.
dp.touch()
copied += 1
if copied > 0:
print(f"SYNC: {dst.name}: refreshed {copied}/{src_files} files from {src}")
# A mirror must also remove source files deleted from the explicit local
# checkout. Otherwise PlatformIO can continue compiling stale translation
# units that no longer exist in the dependency being tested.
for root, dirs, files in os.walk(dst):
dirs[:] = [d for d in dirs if d not in (".git", ".pio", "__pycache__", "build")]
rel = Path(root).relative_to(dst)
for fn in files:
if fn == ".piopm" or fn.endswith((".pyc", ".o", ".a", ".elf", ".bin")):
continue
relative_path = (rel / fn).as_posix()
if relative_path not in mirrored_paths:
(Path(root) / fn).unlink()
removed += 1
if copied > 0 or removed > 0:
print(
f"SYNC: {dst.name}: refreshed {copied}/{src_files} files, "
f"removed {removed} stale files from {src}"
)
return True
@@ -22,8 +22,10 @@ def test_local_override_uses_content_not_mtime(tmp_path, monkeypatch):
source_file = source / "Transport.cpp"
destination_file = destination / "Transport.cpp"
orphan_file = destination / "Removed.cpp"
source_file.write_text("patched source\n")
destination_file.write_text("stale fetched source\n")
orphan_file.write_text("removed local source\n")
# A just-fetched dependency can have a newer mtime than the local checkout.
# The override must still win based on bytes, not timestamps.
@@ -43,6 +45,7 @@ def test_local_override_uses_content_not_mtime(tmp_path, monkeypatch):
assert destination_file.read_text() == "patched source\n"
assert destination_file.stat().st_mtime > 2
assert not orphan_file.exists()
def test_local_override_runs_before_dependency_patch_scripts():
@@ -34,3 +34,6 @@ def test_transport_toggle_is_last_and_requires_explicit_warning_confirmation():
assert "Takes effect after reboot" in SETTINGS_CPP
assert "on_transport_enabled_changed" in SETTINGS_CPP
assert "on_transport_confirm_enable" in SETTINGS_CPP
assert "lv_group_create()" in SETTINGS_CPP
assert "lv_indev_set_group(keyboard, _transport_modal_group)" in SETTINGS_CPP
assert "lv_indev_set_group(trackball, _transport_modal_group)" in SETTINGS_CPP