diff --git a/runtime-patches.lock.json b/runtime-patches.lock.json index d2a186a9..e6d1747b 100644 --- a/runtime-patches.lock.json +++ b/runtime-patches.lock.json @@ -4,7 +4,7 @@ "base_revision": "d653bc4493619ab979ccff165cf48c0c63b77d19", "patch": "tools/runtime-patches/makepad-settings.patch", "sha256": "3a79cddddc89dc4d064a9f0bdd17dc8111dcab9c796a334d95f61ecb9d5011aa", - "tree": "e756018052209a8159ae5ba6d3a66dba8e04d4c0", + "tree": "dafa573454b957f2f1183d517256d5a28e66487f", "product_fixes": [ "Settings integration: Android IME synchronization, accessibility and reduced motion, GLES program-cache validation, obscured-gesture cancellation and scroll-position observation.", "Contained-app isolation and secret-input restrictions come from the pinned upstream runtime; the Settings overlay preserves those gates.", @@ -51,7 +51,8 @@ "A hidden Android native composer remembers animated IME insets without requesting a root layout every frame; showing it applies the latest inset before its first visible frame.", "Launch-input hardening: the Studio connection and the OCTOS_PROXY app HTTP proxy, which Makepad itself acts on from an Android Intent extra, are honoured only when the build opts into launch-time development input (debuggable, or the manifest meta-data dev.makepad.LAUNCH_STUDIO). A shipped build ignores them and drops any Studio host a development build saved. The exported activity would otherwise let another installed app point it at a host or a proxy.", "Apple UI typeface (OctoSense-org/makepad#129): on macOS and iOS every text role leads with PingFang SC, read from the system and never packaged (Regular for regular and italic, Semibold for bold), fitted to the theme's line box so layouts keep their size; the bundled IBM Plex, LXGW WenKai and emoji chain stays behind it, code and icon roles keep their faces, and MAKEPAD_SYSTEM_FONTS=0 or another platform keeps today's chains. A font member can name a face of a collection (PingFang.ttc's face 0 is PingFang HK).", - "CachedView can opt into an isolated depth buffer. Maps driving views use it so tilted terrain, roads and buildings are not hidden by host UI backgrounds, while route and navigation overlays retain normal composition." + "CachedView can opt into an isolated depth buffer. Maps driving views use it so tilted terrain, roads and buildings are not hidden by host UI backgrounds, while route and navigation overlays retain normal composition.", + "Finance's first open (OctoSense-org/makepad#130): an empty file is seeded with the demo household in one transaction instead of one commit per row, so the first open no longer freezes the UI for seconds of per-row journal syncs (the first-start test: 1.8-3.3 s to 0.29 s in release); a failed seed leaves the file empty for the next start to seed again." ], "stacked": [ { @@ -205,6 +206,10 @@ { "patch": "tools/runtime-patches/makepad-map-texture-depth.patch", "sha256": "bf54076f55d8c501b0dda378e2ed9121aca3f47bc243f1b72256aa9f0844b6d8" + }, + { + "patch": "tools/runtime-patches/makepad-finance-seed.patch", + "sha256": "100fb98976ede125f64a7c78d8f8d51a902de9bfd0502fa08b06dfee6c9ca0fe" } ] } diff --git a/tools/runtime-patches/makepad-finance-seed.patch b/tools/runtime-patches/makepad-finance-seed.patch new file mode 100644 index 00000000..d1e79a89 --- /dev/null +++ b/tools/runtime-patches/makepad-finance-seed.patch @@ -0,0 +1,42 @@ +diff --git a/apps/finance/src/db.rs b/apps/finance/src/db.rs +index 507f5709a..5cf0a19e3 100644 +--- a/apps/finance/src/db.rs ++++ b/apps/finance/src/db.rs +@@ -396,9 +396,20 @@ pub fn set_setting(&mut self, key: &str, value: &str) -> Result<(), String> { + pub fn transact( + &mut self, + body: impl FnOnce(&mut Connection) -> Result, ++ ) -> Result { ++ self.transact_db(|db| body(&mut db.conn)) ++ } ++ ++ /// [`Db::transact`] for a body that writes through `Db`'s own methods. ++ /// The first-run seed writes thousands of rows; committed one by one, ++ /// each journaled and synced the file again, a freeze of seconds on the ++ /// UI thread. ++ pub(crate) fn transact_db( ++ &mut self, ++ body: impl FnOnce(&mut Db) -> Result, + ) -> Result { + self.conn.execute("BEGIN", &[]).map_err(|e| format!("begin: {e:?}"))?; +- match body(&mut self.conn) { ++ match body(self) { + Ok(value) => { + self.conn.execute("COMMIT", &[]).map_err(|e| format!("commit: {e:?}"))?; + Ok(value) +diff --git a/apps/finance/src/native.rs b/apps/finance/src/native.rs +index 37f18e1bd..5b21458f7 100644 +--- a/apps/finance/src/native.rs ++++ b/apps/finance/src/native.rs +@@ -34,7 +34,10 @@ fn start(&mut self, db_path: &Path) -> Start { + match db.is_empty() { + Ok(true) => { + let ledger = crate::seed::generate(crate::seed::DEFAULT_YEARS, today); +- match persist(&mut db, &ledger) { ++ // One transaction for the whole household: one journal and ++ // one sync instead of one per row, and a failure leaves the ++ // file empty rather than half seeded. ++ match db.transact_db(|db| persist(db, &ledger)) { + Ok(_) => { + let start = date::month_start(date::add_months( + today,