From 8510c5094188beaa27462fb6db2f45928e2b4689 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Fri, 22 May 2026 15:19:25 +0200 Subject: [PATCH 1/2] fix(ui-ios): register SecureField with geisterhand (#1384) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SecureField called register_widget but, unlike TextField, never called perry_geisterhand_register, so it was absent from the geisterhand widget registry. /widgets didn't list password fields and /type couldn't drive them — blocking automated testing of any login/signup flow on iOS. Mirror TextField's registration: register as widget_type=1, callback_kind=1 with the onChange closure and placeholder label, under cfg(geisterhand). --- crates/perry-ui-ios/src/widgets/securefield.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/crates/perry-ui-ios/src/widgets/securefield.rs b/crates/perry-ui-ios/src/widgets/securefield.rs index 6abcaa75d..9779f7a4b 100644 --- a/crates/perry-ui-ios/src/widgets/securefield.rs +++ b/crates/perry-ui-ios/src/widgets/securefield.rs @@ -100,7 +100,17 @@ pub fn create(placeholder_ptr: *const u8, on_change: f64) -> i64 { std::mem::forget(target); let view: Retained = Retained::cast_unchecked(text_field); - super::register_widget(view) + let handle = super::register_widget(view); + #[cfg(feature = "geisterhand")] + { + extern "C" { + fn perry_geisterhand_register(h: i64, wt: u8, ck: u8, cb: f64, lbl: *const u8); + } + unsafe { + perry_geisterhand_register(handle, 1, 1, on_change, placeholder_ptr); + } + } + handle } } From 7885ed346364c3292356d8432b54eb15e7209767 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Fri, 22 May 2026 15:19:25 +0200 Subject: [PATCH 2/2] fix(compile): include perry-stdlib in geisterhand auto-build (#1383) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit build_geisterhand_libs built perry-runtime + the UI crate + the geisterhand server, but not perry-stdlib. The geisterhand lib set was therefore incomplete: apps pulling native-FFI packages that depend on perry-stdlib's async surface (perry_ffi_promise_*) had no consistent stdlib to link against under --enable-geisterhand, and a separate `cargo build -p perry-stdlib` resolves perry-runtime WITHOUT the geisterhand feature → a second runtime variant → undefined-symbol link errors. Add -p perry-stdlib to the same cargo invocation so the shared perry-runtime is built once (with geisterhand) and unified across all crates, keeping the lib set complete and hash-consistent. --- crates/perry/src/commands/compile/library_search.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/crates/perry/src/commands/compile/library_search.rs b/crates/perry/src/commands/compile/library_search.rs index 9a260f00f..6e6125cc1 100644 --- a/crates/perry/src/commands/compile/library_search.rs +++ b/crates/perry/src/commands/compile/library_search.rs @@ -1197,7 +1197,17 @@ pub(super) fn build_geisterhand_libs(target: Option<&str>, format: OutputFormat) .arg("--features") .arg(format!("{}/geisterhand", ui_crate)) .arg("-p") - .arg("perry-ui-geisterhand"); + .arg("perry-ui-geisterhand") + // Build perry-stdlib in the same invocation so the geisterhand lib + // set is complete and its shared `perry-runtime` is hash-consistent + // with the runtime/ui libs above (a separate `cargo build -p + // perry-stdlib` would resolve `perry-runtime` without the geisterhand + // feature → a second runtime variant → undefined-symbol link errors). + // Without stdlib here, apps that pull native-FFI packages depending on + // perry-stdlib's async surface (`perry_ffi_promise_*`) had no + // consistent stdlib to link against under --enable-geisterhand (#1383). + .arg("-p") + .arg("perry-stdlib"); // Add cross-compilation target if needed if let Some(triple) = rust_target_triple(target) {