peachsim 0.1.939 → 0.1.1399

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (396) hide show
  1. package/README.md +28 -22
  2. package/cli/app-catalog.ts +29 -14
  3. package/cli/app-fonts.ts +5 -3
  4. package/cli/bridge-flow-runner.ts +40 -29
  5. package/cli/cloud-client.ts +57 -21
  6. package/cli/cloud-test-tunnel.ts +12 -18
  7. package/cli/commands/agent.ts +1 -1
  8. package/cli/commands/app-fonts.ts +3 -3
  9. package/cli/commands/assert.ts +8 -8
  10. package/cli/commands/auth.ts +8 -3
  11. package/cli/commands/box/bundle-plane.ts +13 -1
  12. package/cli/commands/box.ts +16 -5
  13. package/cli/commands/compat.ts +1 -1
  14. package/cli/commands/config.ts +2 -2
  15. package/cli/commands/control.ts +125 -71
  16. package/cli/commands/cpu-profile.ts +45 -1
  17. package/cli/commands/daemon.ts +131 -33
  18. package/cli/commands/debug.ts +24 -17
  19. package/cli/commands/desktop.ts +7 -1
  20. package/cli/commands/detect.ts +101 -0
  21. package/cli/commands/detox.ts +6 -6
  22. package/cli/commands/device.ts +12 -12
  23. package/cli/commands/electron.ts +32 -14
  24. package/cli/commands/flow.ts +49 -41
  25. package/cli/commands/guest-host.ts +39 -1
  26. package/cli/commands/inspect/core.ts +14 -8
  27. package/cli/commands/inspect/list.ts +1 -1
  28. package/cli/commands/inspect/settle.ts +5 -3
  29. package/cli/commands/inspect/settling.ts +229 -44
  30. package/cli/commands/inspect/wait-idle.ts +3 -2
  31. package/cli/commands/inspect.ts +105 -93
  32. package/cli/commands/install-cli.ts +36 -15
  33. package/cli/commands/install-desktop.ts +68 -195
  34. package/cli/commands/kotlin.ts +6 -5
  35. package/cli/commands/login.ts +5 -5
  36. package/cli/commands/maestro-compare.ts +554 -0
  37. package/cli/commands/maestro-generate.ts +6 -3
  38. package/cli/commands/maestro.ts +22 -0
  39. package/cli/commands/mode.ts +2 -2
  40. package/cli/commands/no-bridge-hint.ts +6 -2
  41. package/cli/commands/platform.ts +35 -6
  42. package/cli/commands/preview.ts +6 -0
  43. package/cli/commands/project-report.ts +10 -12
  44. package/cli/commands/record.ts +37 -37
  45. package/cli/commands/runtime.ts +9 -9
  46. package/cli/commands/screenshot-layers.ts +4 -4
  47. package/cli/commands/screenshot-mode.ts +2 -2
  48. package/cli/commands/screenshot.ts +8 -8
  49. package/cli/commands/screenshots-capture.ts +2 -2
  50. package/cli/commands/serve.ts +9 -12
  51. package/cli/commands/setup.ts +29 -14
  52. package/cli/commands/shell-boolean-mode.ts +2 -2
  53. package/cli/commands/show-touches-mode.ts +2 -2
  54. package/cli/commands/skills.ts +11 -11
  55. package/cli/commands/swift.ts +29 -11
  56. package/cli/commands/telemetry.ts +2 -2
  57. package/cli/commands/test.ts +5 -0
  58. package/cli/commands/three-mode.ts +3 -3
  59. package/cli/commands/timeline.ts +4 -4
  60. package/cli/commands/upgrade.ts +2 -2
  61. package/cli/commands/upload.ts +15 -15
  62. package/cli/commands/what-happened.ts +2 -2
  63. package/cli/current-sim.ts +6 -3
  64. package/cli/desktop-companion.ts +55 -149
  65. package/cli/dev-build-freshness.ts +2 -2
  66. package/cli/drivers/desktop.ts +17 -9
  67. package/cli/drivers/electron.ts +1 -2
  68. package/cli/drivers/playwright-sim-host.ts +11 -2
  69. package/cli/drivers/playwright.ts +35 -2
  70. package/cli/drivers/types.ts +8 -0
  71. package/cli/maestro-compare.ts +670 -0
  72. package/cli/outbound-endpoints.ts +46 -8
  73. package/cli/recording-access.ts +6 -6
  74. package/cli/run-registry.ts +1 -1
  75. package/cli/runtime-compat.ts +5 -1
  76. package/cli/send-to-box.ts +3 -3
  77. package/cli/shell-init.ts +2 -1
  78. package/cli/ws-bridge.ts +9 -5
  79. package/detox/element-types.ts +1 -0
  80. package/detox/gestures.ts +3 -3
  81. package/detox/index.ts +67 -38
  82. package/detox/navigation-lifecycle.ts +9 -6
  83. package/detox/proof-frame.cjs +6 -4
  84. package/dist-lib/agent-daemon-client.cjs +1 -1
  85. package/dist-lib/agent-events.cjs +1 -1
  86. package/dist-lib/attached-projects.cjs +1 -1
  87. package/dist-lib/auth/shared-session.cjs +1 -1
  88. package/dist-lib/backend-origin.cjs +1 -1
  89. package/dist-lib/beta.cjs +1 -1
  90. package/dist-lib/beta.mjs +1 -1
  91. package/dist-lib/bridge-constants.cjs +1 -1
  92. package/dist-lib/bridge-contract-input.cjs +42 -17
  93. package/dist-lib/bridge-contract-input.mjs +41 -16
  94. package/dist-lib/bridge-contract.cjs +1 -4
  95. package/dist-lib/bridge-contract.mjs +1 -3
  96. package/dist-lib/bundle-channel.cjs +2918 -550
  97. package/dist-lib/capture-contract.cjs +65 -24
  98. package/dist-lib/capture-contract.mjs +63 -24
  99. package/dist-lib/cloud-contract.cjs +2 -2
  100. package/dist-lib/cloud-contract.mjs +2 -2
  101. package/dist-lib/cloud-test-args.cjs +1 -1
  102. package/dist-lib/cloud-test-args.mjs +1 -1
  103. package/dist-lib/cloud.cjs +3 -3
  104. package/dist-lib/cloud.mjs +3 -3
  105. package/dist-lib/config.cjs +15 -5
  106. package/dist-lib/config.mjs +154 -0
  107. package/dist-lib/detox/index.cjs +495 -139
  108. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  109. package/dist-lib/expo-swift-bundle.cjs +1168 -238
  110. package/dist-lib/expo-swift-metadata.cjs +34 -23
  111. package/dist-lib/expo-swift-metadata.mjs +32 -23
  112. package/dist-lib/home-paths.cjs +2 -2
  113. package/dist-lib/host/bridge-host.cjs +2938 -654
  114. package/dist-lib/host/fetch-proxy-handler.cjs +14 -1
  115. package/dist-lib/host/fetch-proxy-overrides.cjs +7 -1
  116. package/dist-lib/host/fetch-proxy-overrides.mjs +5 -1
  117. package/dist-lib/host/replacement-module-handler.cjs +2 -2
  118. package/dist-lib/host/websocket-proxy.cjs +1 -1
  119. package/dist-lib/index.cjs +999 -353
  120. package/dist-lib/jump-to-source-babel.cjs +1 -1
  121. package/dist-lib/jump-to-source-native.cjs +1 -1
  122. package/dist-lib/kotlin-host.cjs +332 -19
  123. package/dist-lib/menu.cjs +1 -1
  124. package/dist-lib/menu.mjs +1 -1
  125. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  126. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  127. package/dist-lib/metro-production-bundle.cjs +7 -7
  128. package/dist-lib/metro-production-bundle.mjs +5 -5
  129. package/dist-lib/metro.cjs +688 -250
  130. package/dist-lib/native-app-identity-project.cjs +2647 -0
  131. package/dist-lib/native-app-identity-project.mjs +1257 -0
  132. package/dist-lib/native-app-identity.cjs +325 -25
  133. package/dist-lib/native-app-identity.mjs +323 -25
  134. package/dist-lib/native-firebase-metadata.cjs +1 -1
  135. package/dist-lib/native-firebase-metadata.mjs +1 -1
  136. package/dist-lib/plist.cjs +1 -1
  137. package/dist-lib/plist.mjs +1 -1
  138. package/dist-lib/profiles.cjs +1 -1
  139. package/dist-lib/public-brand.cjs +1 -1
  140. package/dist-lib/react-native-host-modules.cjs +5 -1
  141. package/dist-lib/react-native-host-modules.mjs +5 -1
  142. package/dist-lib/scripts/dev-server-scanner.cjs +57 -32
  143. package/dist-lib/sdk.cjs +231 -51
  144. package/dist-lib/sdk.mjs +231 -51
  145. package/dist-lib/skills.cjs +4107 -1374
  146. package/dist-lib/swift-compile.cjs +290 -30
  147. package/dist-lib/swift-compile.mjs +290 -30
  148. package/dist-lib/swift-package.cjs +143 -12
  149. package/dist-lib/swift-package.mjs +137 -11
  150. package/dist-lib/swift-submit.cjs +47 -5
  151. package/dist-lib/swift-submit.mjs +42 -5
  152. package/dist-lib/swift-toolchain.cjs +7 -2
  153. package/dist-lib/swift.cjs +1 -1
  154. package/dist-lib/vite-swift.cjs +1392 -458
  155. package/dist-lib/vite.cjs +13 -17
  156. package/dist-lib/worklet-executable.cjs +248 -33
  157. package/dist-lib/worklet-executable.mjs +248 -33
  158. package/install.sh +10 -1
  159. package/kotlin/{AppSources → AndroidViewSources}/android/content/res/Resources.kt +9 -9
  160. package/kotlin/AndroidViewSources/android/graphics/Canvas.kt +20 -0
  161. package/kotlin/AndroidViewSources/android/view/View.kt +211 -0
  162. package/kotlin/AndroidViewSources/android/widget/FrameLayout.kt +61 -0
  163. package/kotlin/AndroidViewSources/android/widget/LinearLayout.kt +49 -0
  164. package/kotlin/AppSources/android/view/Window.kt +36 -0
  165. package/kotlin/AppSources/android/view/WindowInsets.kt +9 -0
  166. package/kotlin/AppSources/android/view/WindowInsetsController.kt +5 -0
  167. package/kotlin/AppSources/android/window/OnBackInvokedDispatcher.kt +48 -0
  168. package/kotlin/AppSources/androidx/activity/OnBackPressedDispatcher.kt +20 -5
  169. package/kotlin/AppSources/androidx/compose/foundation/layout/WindowInsets.kt +15 -0
  170. package/kotlin/AppSources/androidx/compose/ui/platform/ComposeView.kt +2 -1
  171. package/kotlin/AppSources/dev/peach/app/PeachApp.kt +42 -50
  172. package/kotlin/ComposeSources/PeachComposeHost.kt +200 -84
  173. package/kotlin/ExpoComposeSources/PeachAndroidView.kt +87 -0
  174. package/kotlin/ExpoComposeSources/PeachExpoViewMount.kt +24 -0
  175. package/kotlin/ExpoComposeSources/dev/peach/expo/PeachExpoCompose.kt +28 -0
  176. package/kotlin/ExpoComposeSources/expo/modules/kotlin/views/ExpoComposeView.kt +70 -0
  177. package/kotlin/ExpoSources/dev/peach/expo/PeachExpoRuntime.kt +513 -0
  178. package/kotlin/ExpoSources/dev/peach/expo/PeachExpoTypes.kt +173 -0
  179. package/kotlin/ExpoSources/expo/modules/kotlin/AppContext.kt +20 -0
  180. package/kotlin/ExpoSources/expo/modules/kotlin/Promise.kt +19 -0
  181. package/kotlin/ExpoSources/expo/modules/kotlin/classcomponent/ClassComponentBuilder.kt +198 -0
  182. package/kotlin/ExpoSources/expo/modules/kotlin/exception/CodedException.kt +126 -0
  183. package/kotlin/ExpoSources/expo/modules/kotlin/functions/Functions.kt +132 -0
  184. package/kotlin/ExpoSources/expo/modules/kotlin/jni/JavaScriptTypedArray.kt +81 -0
  185. package/kotlin/ExpoSources/expo/modules/kotlin/modules/Module.kt +98 -0
  186. package/kotlin/ExpoSources/expo/modules/kotlin/objects/ObjectDefinitionBuilder.kt +236 -0
  187. package/kotlin/ExpoSources/expo/modules/kotlin/records/Record.kt +12 -0
  188. package/kotlin/ExpoSources/expo/modules/kotlin/runtime/Runtime.kt +9 -0
  189. package/kotlin/ExpoSources/expo/modules/kotlin/sharedobjects/SharedObject.kt +50 -0
  190. package/kotlin/ExpoSources/expo/modules/kotlin/sharedobjects/SharedObjectRegistry.kt +57 -0
  191. package/kotlin/ExpoSources/expo/modules/kotlin/sharedobjects/SharedRef.kt +19 -0
  192. package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/ConcreteTypedArrays.kt +158 -0
  193. package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/GenericTypedArray.kt +8 -0
  194. package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/TypedArray.kt +29 -0
  195. package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/TypedArrayIterator.kt +9 -0
  196. package/kotlin/ExpoSources/expo/modules/kotlin/types/AnyType.kt +155 -0
  197. package/kotlin/ExpoSources/expo/modules/kotlin/types/Either.kt +91 -0
  198. package/kotlin/ExpoSources/expo/modules/kotlin/types/Enumerable.kt +6 -0
  199. package/kotlin/ExpoSources/expo/modules/kotlin/viewevent/ViewEvent.kt +54 -0
  200. package/kotlin/ExpoSources/expo/modules/kotlin/views/ExpoView.kt +23 -0
  201. package/kotlin/ExpoSources/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +71 -0
  202. package/kotlin/ExpoSources/expo/modules/kotlin/views/ViewProps.kt +35 -0
  203. package/kotlin/README.md +13 -3
  204. package/kotlin/Sources/android/os/Build.kt +17 -0
  205. package/kotlin/Sources/android/os/Handler.kt +35 -0
  206. package/kotlin/Sources/android/os/Looper.kt +17 -0
  207. package/kotlin/Sources/android/os/MessageQueue.kt +56 -0
  208. package/kotlin/Sources/android/os/SystemClock.kt +14 -0
  209. package/kotlin/Sources/android/util/Log.kt +64 -0
  210. package/kotlin/Sources/java/security/MessageDigest.kt +114 -0
  211. package/kotlin/Sources/kotlin/text/StringFormat.kt +9 -0
  212. package/kotlin/Sources/org/json/JSON.kt +44 -0
  213. package/kotlin/fixtures/counter/Counter.d.kt.ts +1 -0
  214. package/kotlin/fixtures/counter/Counter.kt +10 -3
  215. package/kotlin/fixtures/counter/CounterApp.native.tsx +1 -1
  216. package/kotlin/fixtures/counter/vite.config.ts +2 -2
  217. package/kotlin/fixtures/headless-counter/Headless.kt +7 -6
  218. package/kotlin/fixtures/import-animation/Animation.d.kt.ts +7 -0
  219. package/kotlin/fixtures/import-animation/Animation.kt +80 -0
  220. package/kotlin/fixtures/import-animation/ImportAnimation.native.tsx +13 -0
  221. package/kotlin/fixtures/import-animation/README.md +24 -0
  222. package/kotlin/fixtures/import-animation/app/_layout.tsx +4 -0
  223. package/kotlin/fixtures/import-animation/app/index+spa.tsx +1 -0
  224. package/kotlin/fixtures/import-animation/app/routes.d.ts +18 -0
  225. package/kotlin/fixtures/import-animation/package.json +23 -0
  226. package/kotlin/fixtures/import-animation/tsconfig.json +20 -0
  227. package/kotlin/fixtures/import-animation/vite.config.ts +20 -0
  228. package/kotlin/fixtures/import-editor/Editor.d.kt.ts +7 -0
  229. package/kotlin/fixtures/import-editor/Editor.kt +59 -0
  230. package/kotlin/fixtures/import-editor/ImportEditor.native.tsx +23 -0
  231. package/kotlin/fixtures/import-editor/README.md +27 -0
  232. package/kotlin/fixtures/import-editor/app/_layout.tsx +4 -0
  233. package/kotlin/fixtures/import-editor/app/index+spa.tsx +1 -0
  234. package/kotlin/fixtures/import-editor/package.json +23 -0
  235. package/kotlin/fixtures/import-editor/tsconfig.json +20 -0
  236. package/kotlin/fixtures/import-editor/vite.config.ts +20 -0
  237. package/kotlin/fixtures/import-effects/Effects.d.kt.ts +7 -0
  238. package/kotlin/fixtures/import-effects/Effects.kt +87 -0
  239. package/kotlin/fixtures/import-effects/ImportEffects.native.tsx +13 -0
  240. package/kotlin/fixtures/import-effects/README.md +19 -0
  241. package/kotlin/fixtures/import-effects/app/_layout.tsx +4 -0
  242. package/kotlin/fixtures/import-effects/app/index+spa.tsx +1 -0
  243. package/kotlin/fixtures/import-effects/package.json +23 -0
  244. package/kotlin/fixtures/import-effects/tsconfig.json +20 -0
  245. package/kotlin/fixtures/import-effects/vite.config.ts +20 -0
  246. package/kotlin/fixtures/import-layout/ImportLayout.native.tsx +13 -0
  247. package/kotlin/fixtures/import-layout/Layout.d.kt.ts +7 -0
  248. package/kotlin/fixtures/import-layout/Layout.kt +72 -0
  249. package/kotlin/fixtures/import-layout/README.md +24 -0
  250. package/kotlin/fixtures/import-layout/app/_layout.tsx +4 -0
  251. package/kotlin/fixtures/import-layout/app/index+spa.tsx +1 -0
  252. package/kotlin/fixtures/import-layout/package.json +23 -0
  253. package/kotlin/fixtures/import-layout/tsconfig.json +20 -0
  254. package/kotlin/fixtures/import-layout/vite.config.ts +20 -0
  255. package/kotlin/fixtures/import-navigation/ImportNavigation.native.tsx +18 -0
  256. package/kotlin/fixtures/import-navigation/Navigation.d.kt.ts +7 -0
  257. package/kotlin/fixtures/import-navigation/Navigation.kt +104 -0
  258. package/kotlin/fixtures/import-navigation/README.md +31 -0
  259. package/kotlin/fixtures/import-navigation/app/_layout.tsx +4 -0
  260. package/kotlin/fixtures/import-navigation/app/index+spa.tsx +1 -0
  261. package/kotlin/fixtures/import-navigation/package.json +23 -0
  262. package/kotlin/fixtures/import-navigation/tsconfig.json +20 -0
  263. package/kotlin/fixtures/import-navigation/vite.config.ts +20 -0
  264. package/kotlin/fixtures/import-overlays/ImportOverlays.native.tsx +29 -0
  265. package/kotlin/fixtures/import-overlays/Overlays.d.kt.ts +7 -0
  266. package/kotlin/fixtures/import-overlays/Overlays.kt +93 -0
  267. package/kotlin/fixtures/import-overlays/README.md +34 -0
  268. package/kotlin/fixtures/import-overlays/app/_layout.tsx +4 -0
  269. package/kotlin/fixtures/import-overlays/app/index+spa.tsx +1 -0
  270. package/kotlin/fixtures/import-overlays/package.json +23 -0
  271. package/kotlin/fixtures/import-overlays/tsconfig.json +20 -0
  272. package/kotlin/fixtures/import-overlays/vite.config.ts +20 -0
  273. package/kotlin/fixtures/import-scroll/ImportScroll.native.tsx +13 -0
  274. package/kotlin/fixtures/import-scroll/README.md +23 -0
  275. package/kotlin/fixtures/import-scroll/Scroll.d.kt.ts +7 -0
  276. package/kotlin/fixtures/import-scroll/Scroll.kt +91 -0
  277. package/kotlin/fixtures/import-scroll/app/_layout.tsx +4 -0
  278. package/kotlin/fixtures/import-scroll/app/index+spa.tsx +1 -0
  279. package/kotlin/fixtures/import-scroll/package.json +23 -0
  280. package/kotlin/fixtures/import-scroll/tsconfig.json +20 -0
  281. package/kotlin/fixtures/import-scroll/vite.config.ts +20 -0
  282. package/kotlin/fixtures/import-selection/ImportSelection.native.tsx +44 -0
  283. package/kotlin/fixtures/import-selection/README.md +32 -0
  284. package/kotlin/fixtures/import-selection/Selection.d.kt.ts +8 -0
  285. package/kotlin/fixtures/import-selection/Selection.kt +78 -0
  286. package/kotlin/fixtures/import-selection/app/_layout.tsx +4 -0
  287. package/kotlin/fixtures/import-selection/app/index+spa.tsx +1 -0
  288. package/kotlin/fixtures/import-selection/package.json +23 -0
  289. package/kotlin/fixtures/import-selection/tsconfig.json +20 -0
  290. package/kotlin/fixtures/import-selection/vite.config.ts +20 -0
  291. package/kotlin/fixtures/import-surfaces/ImportSurfaces.native.tsx +13 -0
  292. package/kotlin/fixtures/import-surfaces/README.md +22 -0
  293. package/kotlin/fixtures/import-surfaces/Surfaces.d.kt.ts +7 -0
  294. package/kotlin/fixtures/import-surfaces/Surfaces.kt +64 -0
  295. package/kotlin/fixtures/import-surfaces/app/_layout.tsx +4 -0
  296. package/kotlin/fixtures/import-surfaces/app/index+spa.tsx +1 -0
  297. package/kotlin/fixtures/import-surfaces/package.json +23 -0
  298. package/kotlin/fixtures/import-surfaces/tsconfig.json +20 -0
  299. package/kotlin/fixtures/import-surfaces/vite.config.ts +20 -0
  300. package/kotlin/fixtures/import-values/ImportValues.native.tsx +35 -0
  301. package/kotlin/fixtures/import-values/README.md +23 -0
  302. package/kotlin/fixtures/import-values/Values.d.kt.ts +11 -0
  303. package/kotlin/fixtures/import-values/Values.kt +66 -0
  304. package/kotlin/fixtures/import-values/app/_layout.tsx +4 -0
  305. package/kotlin/fixtures/import-values/app/index+spa.tsx +1 -0
  306. package/kotlin/fixtures/import-values/package.json +23 -0
  307. package/kotlin/fixtures/import-values/tsconfig.json +20 -0
  308. package/kotlin/fixtures/import-values/vite.config.ts +20 -0
  309. package/kotlin/fixtures/kotlin-app-variants/BarBehavior.kt +38 -0
  310. package/kotlin/fixtures/kotlin-app-variants/BarVisibility.kt +36 -0
  311. package/kotlin/fixtures/kotlin-app-variants/Ime.kt +3 -1
  312. package/kotlin/fixtures/kotlin-app-variants/TransientInsets.kt +50 -0
  313. package/kotlin/fork/NOTICE +6 -1
  314. package/kotlin/fork/README.md +15 -7
  315. package/kotlin/fork/build.sh +2 -0
  316. package/kotlin/fork/compose-worker-globals.patch +186 -4
  317. package/kotlin/fork/fork.json +2 -2
  318. package/kotlin/fork/skiko-worker-clock.patch +12 -0
  319. package/kotlin/toolchain.json +12 -12
  320. package/kotlin/tools/expo-types.main.kts +115 -0
  321. package/package.json +17 -23
  322. package/scripts/dev-server-scanner.ts +92 -66
  323. package/skills/contrast/SKILL.md +2 -2
  324. package/skills/peach-debug/SKILL.md +1 -1
  325. package/skills/peach-perf/SKILL.md +1 -1
  326. package/skills/peach-setup/SKILL.md +2 -1
  327. package/skills/peach-test/SKILL.md +8 -0
  328. package/src/assetCatalogContract.ts +43 -1
  329. package/src/bridge-contract-input.ts +46 -19
  330. package/src/bridge-contract.ts +0 -1
  331. package/src/bundle-channel.mjs +197 -84
  332. package/src/bundleGlobalFooter.ts +38 -0
  333. package/src/capture-contract.ts +107 -33
  334. package/src/cloud-contract.ts +5 -1
  335. package/src/cloud.ts +5 -2
  336. package/src/config.ts +22 -3
  337. package/src/configured-bundle-producer.ts +1 -1
  338. package/src/desktop-host-delivery.ts +95 -1
  339. package/src/expo-kotlin-bundle.ts +29 -0
  340. package/src/expo-kotlin-host.ts +201 -0
  341. package/src/expo-swift-host.ts +96 -76
  342. package/src/expoKotlinContract.ts +70 -0
  343. package/src/expoSwiftContract.ts +4 -25
  344. package/src/home-paths.ts +7 -4
  345. package/src/host/bridge-host.ts +23 -3
  346. package/src/host/fetch-proxy-handler.ts +13 -0
  347. package/src/host/fetch-proxy-overrides.ts +11 -0
  348. package/src/host/replacement-module-handler.ts +5 -2
  349. package/src/index.ts +3 -1
  350. package/src/kotlin-host.ts +463 -19
  351. package/src/metro-plugin.ts +56 -28
  352. package/src/metro-production-bundle.ts +2 -2
  353. package/src/native-app-identity-project.ts +190 -0
  354. package/src/native-app-identity.ts +398 -34
  355. package/src/native-firebase-config.ts +69 -15
  356. package/src/native-seam-manifest.ts +6 -0
  357. package/src/one-widget-discovery.ts +2 -1
  358. package/src/openstep-plist.ts +107 -0
  359. package/src/react-native-host-modules.ts +4 -0
  360. package/src/runtime-assets.ts +2 -2
  361. package/src/sim-client.ts +2 -2
  362. package/src/swift-binary-modules.ts +3 -1
  363. package/src/swift-compile.ts +286 -38
  364. package/src/swift-distribution-contract.ts +4 -0
  365. package/src/swift-distribution.lock.json +123 -12
  366. package/src/swift-distribution.ts +7 -3
  367. package/src/swift-host.ts +298 -83
  368. package/src/swift-package-manifest.ts +29 -2
  369. package/src/swift-package.ts +180 -10
  370. package/src/swift-packages.ts +4 -0
  371. package/src/swift-standin-emit.ts +4 -1
  372. package/src/swift-standins.ts +274 -15
  373. package/src/swift-submit.ts +62 -7
  374. package/src/swift-toolchain.ts +6 -1
  375. package/src/swiftContract.ts +126 -3
  376. package/src/vite-plugin-one.ts +13 -16
  377. package/src/vite-plugin-swift.ts +4 -5
  378. package/src/vite-plugin.ts +360 -144
  379. package/src/vite.d.ts +1 -1
  380. package/src/worker-system-chunks.ts +221 -0
  381. package/src/worklet-executable.ts +348 -38
  382. package/src/worklets-babel.ts +1 -1
  383. package/src/xcode-project.ts +243 -127
  384. package/dist-lib/agent-identity.cjs +0 -39
  385. package/dist-lib/agent-sessions.cjs +0 -760
  386. package/dist-lib/cli-constants.cjs +0 -32
  387. package/dist-lib/render-mode.cjs +0 -44
  388. package/kotlin/AppSources/android/view/View.kt +0 -74
  389. package/kotlin/AppSources/android/widget/FrameLayout.kt +0 -6
  390. package/src/render-mode.ts +0 -15
  391. /package/kotlin/{AppSources → AndroidViewSources}/android/content/Context.kt +0 -0
  392. /package/kotlin/{AppSources → AndroidViewSources}/android/content/res/Configuration.kt +0 -0
  393. /package/kotlin/{AppSources → AndroidViewSources}/android/graphics/Color.kt +0 -0
  394. /package/kotlin/{AppSources → AndroidViewSources}/android/util/DisplayMetrics.kt +0 -0
  395. /package/kotlin/{AppSources → AndroidViewSources}/dev/peach/app/JavaFormat.kt +0 -0
  396. /package/kotlin/{AppSources → Sources}/java/lang/Runnable.kt +0 -0
@@ -0,0 +1,49 @@
1
+ package android.widget
2
+
3
+ import android.content.Context
4
+ import android.view.View
5
+ import android.view.ViewGroup
6
+
7
+ open class LinearLayout(context: Context) : ViewGroup(context) {
8
+ var orientation: Int = HORIZONTAL
9
+ set(value) { field = value; requestLayout() }
10
+
11
+ override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
12
+ var usedWidth = 0
13
+ var usedHeight = 0
14
+ for (index in 0 until childCount) {
15
+ val child = checkNotNull(getChildAt(index))
16
+ val params = child.layoutParams
17
+ child.measure(
18
+ getChildMeasureSpec(widthMeasureSpec, paddingLeft + paddingRight + if (orientation == HORIZONTAL) usedWidth else 0, params?.width ?: LayoutParams.WRAP_CONTENT),
19
+ getChildMeasureSpec(heightMeasureSpec, paddingTop + paddingBottom + if (orientation == VERTICAL) usedHeight else 0, params?.height ?: LayoutParams.WRAP_CONTENT),
20
+ )
21
+ if (orientation == VERTICAL) {
22
+ usedHeight += child.measuredHeight
23
+ usedWidth = maxOf(usedWidth, child.measuredWidth)
24
+ } else {
25
+ usedWidth += child.measuredWidth
26
+ usedHeight = maxOf(usedHeight, child.measuredHeight)
27
+ }
28
+ }
29
+ setMeasuredDimension(
30
+ View.resolveSize(maxOf(minimumWidth, usedWidth + paddingLeft + paddingRight), widthMeasureSpec),
31
+ View.resolveSize(maxOf(minimumHeight, usedHeight + paddingTop + paddingBottom), heightMeasureSpec),
32
+ )
33
+ }
34
+
35
+ override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
36
+ var x = paddingLeft
37
+ var y = paddingTop
38
+ for (index in 0 until childCount) {
39
+ val child = checkNotNull(getChildAt(index))
40
+ child.layout(x, y, x + child.measuredWidth, y + child.measuredHeight)
41
+ if (orientation == VERTICAL) y += child.measuredHeight else x += child.measuredWidth
42
+ }
43
+ }
44
+
45
+ companion object {
46
+ const val HORIZONTAL = 0
47
+ const val VERTICAL = 1
48
+ }
49
+ }
@@ -30,10 +30,15 @@ class Window internal constructor(
30
30
  theme: WindowTheme,
31
31
  internal val host: PeachWindowHost,
32
32
  ) {
33
+ private companion object { var nextBackGeneration = 0 }
34
+ private val backGeneration = ++nextBackGeneration
33
35
  private val edgeToEdgeEnforced = theme.edgeToEdgeEnforced
34
36
  internal val contentParent = FrameLayout(context)
35
37
  val decorView: View get() = contentParent
36
38
  val attributes = WindowManager.LayoutParams()
39
+ private val backDispatcher = android.window.WindowOnBackInvokedDispatcher { host.windowChanged() }
40
+ val onBackInvokedDispatcher: android.window.OnBackInvokedDispatcher get() = backDispatcher
41
+ internal fun invokeBack(): Boolean = backDispatcher.invoke()
37
42
 
38
43
  // PhoneWindow fits system windows until told otherwise; an enforced edge
39
44
  // to edge window never does, and ignores the request
@@ -91,6 +96,20 @@ class Window internal constructor(
91
96
  fun setNavigationBarContrastEnforced(enforced: Boolean) { isNavigationBarContrastEnforced = enforced }
92
97
 
93
98
  val insetsController: WindowInsetsController = object : WindowInsetsController {
99
+ override fun hide(types: Int) = setSystemBarsVisible(types, false)
100
+ override fun show(types: Int) = setSystemBarsVisible(types, true)
101
+
102
+ override var systemBarsBehavior: Int = WindowInsetsController.BEHAVIOR_DEFAULT
103
+ set(value) {
104
+ require(value == WindowInsetsController.BEHAVIOR_DEFAULT ||
105
+ value == WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE) {
106
+ "unsupported system bar behavior: $value"
107
+ }
108
+ if (field == value) return
109
+ field = value
110
+ host.windowChanged()
111
+ }
112
+
94
113
  private var appearance =
95
114
  (if (theme.lightStatusBar) WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS else 0) or
96
115
  (if (theme.lightNavigationBar) WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS else 0)
@@ -105,6 +124,17 @@ class Window internal constructor(
105
124
  }
106
125
  }
107
126
 
127
+ private var hiddenSystemBars = 0
128
+
129
+ private fun setSystemBarsVisible(types: Int, visible: Boolean) {
130
+ val supported = WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars()
131
+ require(types and supported.inv() == 0) { "unsupported window inset visibility types: $types" }
132
+ val next = if (visible) hiddenSystemBars and types.inv() else hiddenSystemBars or types
133
+ if (next == hiddenSystemBars) return
134
+ hiddenSystemBars = next
135
+ host.windowChanged()
136
+ }
137
+
108
138
  // DecorView.calculateBarColor for the status bar of a window that draws
109
139
  // its bar backgrounds: a transparent color under enforced contrast shows
110
140
  // the scrim for the bar's appearance
@@ -124,6 +154,11 @@ class Window internal constructor(
124
154
  .put("decorFitsSystemWindows", fits)
125
155
  .put("statusBarColor", drawnStatusBarColor().toLong() and 0xffffffffL)
126
156
  .put("navigationBarColor", navigationBarColor.toLong() and 0xffffffffL)
157
+ .put("systemBarsAppearance", insetsController.systemBarsAppearance)
158
+ .put("hiddenSystemBars", hiddenSystemBars)
159
+ .put("systemBarsBehavior", insetsController.systemBarsBehavior)
160
+ .put("backCallbacks", backDispatcher.registrations())
161
+ .put("backGeneration", backGeneration)
127
162
 
128
163
  // Activity.setContentView(View) fills the content parent
129
164
  internal fun setContentView(view: View, params: ViewGroup.LayoutParams) {
@@ -137,5 +172,6 @@ class Window internal constructor(
137
172
 
138
173
  internal fun removeFromWindowManager() {
139
174
  if (contentParent.isAttachedToWindow) contentParent.dispatchDetachedFromWindow()
175
+ backDispatcher.clear()
140
176
  }
141
177
  }
@@ -0,0 +1,9 @@
1
+ package android.view
2
+
3
+ // inset type masks accepted by the window's system bar controller
4
+ class WindowInsets private constructor() {
5
+ object Type {
6
+ fun statusBars(): Int = 1
7
+ fun navigationBars(): Int = 1 shl 1
8
+ }
9
+ }
@@ -2,11 +2,16 @@ package android.view
2
2
 
3
3
  // the window's requested system bar appearance: light bars ask for dark icons
4
4
  interface WindowInsetsController {
5
+ fun hide(types: Int)
6
+ fun show(types: Int)
5
7
  fun setSystemBarsAppearance(appearance: Int, mask: Int)
6
8
  val systemBarsAppearance: Int
9
+ var systemBarsBehavior: Int
7
10
 
8
11
  companion object {
9
12
  const val APPEARANCE_LIGHT_STATUS_BARS = 1 shl 3
10
13
  const val APPEARANCE_LIGHT_NAVIGATION_BARS = 1 shl 4
14
+ const val BEHAVIOR_DEFAULT = 1
15
+ const val BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE = 2
11
16
  }
12
17
  }
@@ -0,0 +1,48 @@
1
+ package android.window
2
+
3
+ fun interface OnBackInvokedCallback {
4
+ fun onBackInvoked()
5
+ }
6
+
7
+ interface OnBackInvokedDispatcher {
8
+ fun registerOnBackInvokedCallback(priority: Int, callback: OnBackInvokedCallback)
9
+ fun unregisterOnBackInvokedCallback(callback: OnBackInvokedCallback)
10
+
11
+ companion object {
12
+ const val PRIORITY_DEFAULT = 0
13
+ const val PRIORITY_OVERLAY = 1000000
14
+ }
15
+ }
16
+
17
+ // the receiving window orders by priority, then latest registration.
18
+ internal class WindowOnBackInvokedDispatcher(private val changed: () -> Unit) : OnBackInvokedDispatcher {
19
+ private data class Registration(val priority: Int, val order: Int)
20
+ private val callbacks = linkedMapOf<OnBackInvokedCallback, Registration>()
21
+ private var order = 0
22
+
23
+ override fun registerOnBackInvokedCallback(priority: Int, callback: OnBackInvokedCallback) {
24
+ require(priority >= 0) { "application back callback priority must be nonnegative" }
25
+ callbacks[callback] = Registration(priority, ++order)
26
+ changed()
27
+ }
28
+
29
+ override fun unregisterOnBackInvokedCallback(callback: OnBackInvokedCallback) {
30
+ if (callbacks.remove(callback) != null) changed()
31
+ }
32
+
33
+ fun registrations(): org.json.JSONArray = org.json.JSONArray().also { result ->
34
+ callbacks.values.sortedBy { it.order }.forEach {
35
+ result.put(org.json.JSONObject().put("priority", it.priority).put("registration", it.order))
36
+ }
37
+ }
38
+
39
+ fun invoke(): Boolean {
40
+ val callback = callbacks.maxWithOrNull(compareBy({ it.value.priority }, { it.value.order }))?.key ?: return false
41
+ callback.onBackInvoked()
42
+ return true
43
+ }
44
+
45
+ fun clear() {
46
+ callbacks.clear()
47
+ }
48
+ }
@@ -9,11 +9,8 @@ import androidx.navigationevent.NavigationEventInfo
9
9
  import androidx.navigationevent.NavigationEventInput
10
10
  import java.lang.Runnable
11
11
 
12
- // androidx.activity 1.13.0's OnBackPressedDispatcher, a NavigationEventInput
13
- // over its own NavigationEventDispatcher. the device's back dispatch stands in
14
- // for its OnBackInvokedDispatcher inputs: a window with predictive back gives
15
- // this dispatcher the back only while it has an enabled handler
16
- // (hasEnabledCallbacks), as the registered OnBackInvokedCallback does.
12
+ // activity 1.13.0 routes legacy back through its navigation event input;
13
+ // predictive back registers separate default and overlay inputs with the window.
17
14
  class OnBackPressedDispatcher(
18
15
  private val fallbackOnBackPressed: Runnable?,
19
16
  private val onHasEnabledCallbacksChanged: ((Boolean) -> Unit)?,
@@ -68,6 +65,12 @@ class OnBackPressedDispatcher(
68
65
 
69
66
  fun hasEnabledCallbacks(): Boolean = hasEnabledCallbacks
70
67
 
68
+ // activity 1.13 registers separate default and overlay platform inputs.
69
+ fun setOnBackInvokedDispatcher(invoker: android.window.OnBackInvokedDispatcher) {
70
+ eventDispatcher.addInput(WindowBackInput(invoker, android.window.OnBackInvokedDispatcher.PRIORITY_DEFAULT), NavigationEventDispatcher.PRIORITY_DEFAULT)
71
+ eventDispatcher.addInput(WindowBackInput(invoker, android.window.OnBackInvokedDispatcher.PRIORITY_OVERLAY), NavigationEventDispatcher.PRIORITY_OVERLAY)
72
+ }
73
+
71
74
  fun dispatchOnBackStarted(backEvent: BackEventCompat) {
72
75
  eventInput.backStarted(backEvent.toNavigationEvent())
73
76
  }
@@ -99,6 +102,18 @@ class OnBackPressedDispatcher(
99
102
  }
100
103
  }
101
104
 
105
+ private class WindowBackInput(
106
+ private val invoker: android.window.OnBackInvokedDispatcher,
107
+ private val priority: Int,
108
+ ) : NavigationEventInput() {
109
+ private val callback = android.window.OnBackInvokedCallback { dispatchOnBackCompleted() }
110
+ override fun onHasEnabledHandlersChanged(hasEnabledHandlers: Boolean) {
111
+ if (hasEnabledHandlers) invoker.registerOnBackInvokedCallback(priority, callback)
112
+ else invoker.unregisterOnBackInvokedCallback(callback)
113
+ }
114
+ override fun onRemoved() { invoker.unregisterOnBackInvokedCallback(callback) }
115
+ }
116
+
102
117
  // androidx.activity's Kotlin registration: a callback from a lambda, bound to
103
118
  // owner's lifecycle when one is given
104
119
  fun OnBackPressedDispatcher.addCallback(
@@ -0,0 +1,15 @@
1
+ package androidx.compose.foundation.layout
2
+
3
+ import androidx.compose.runtime.Composable
4
+ import androidx.compose.runtime.NonRestartableComposable
5
+
6
+ // android reports visibility from the content's insets after decor consumption
7
+ val WindowInsets.Companion.isImeVisible: Boolean
8
+ @Composable @NonRestartableComposable get() = dev.peach.app.peachImeVisible()
9
+
10
+ // bar visibility survives fitting decor consuming the content's inset sizes
11
+ val WindowInsets.Companion.areStatusBarsVisible: Boolean
12
+ @Composable @NonRestartableComposable get() = dev.peach.app.peachSystemBarVisible(1)
13
+
14
+ val WindowInsets.Companion.areNavigationBarsVisible: Boolean
15
+ @Composable @NonRestartableComposable get() = dev.peach.app.peachSystemBarVisible(2)
@@ -51,7 +51,8 @@ class ComposeView(context: Context) : ViewGroup(context) {
51
51
  private fun ensureCompositionCreated() {
52
52
  if (composition != null) return
53
53
  check(parentContext == null) { "a ComposeView composing into a parent composition is not supported in Peach yet" }
54
- val window = checkNotNull(attachedWindow) { "ComposeView is not attached to a window" }
54
+ val window = attachedWindow
55
+ check(window is android.view.Window) { "ComposeView is not attached to an activity window" }
55
56
  composition = window.host.compose(this)
56
57
  }
57
58
 
@@ -23,8 +23,6 @@ import androidx.compose.ui.platform.ComposeView
23
23
  import androidx.compose.ui.platform.LocalConfiguration
24
24
  import androidx.compose.ui.platform.LocalContext
25
25
  import androidx.compose.ui.platform.PlatformArchitectureComponentsOwner
26
- import androidx.compose.ui.platform.PlatformInsets
27
- import androidx.compose.ui.platform.PlatformWindowInsets
28
26
  import androidx.compose.runtime.getValue
29
27
  import androidx.compose.runtime.key
30
28
  import androidx.compose.runtime.mutableIntStateOf
@@ -34,6 +32,8 @@ import androidx.compose.runtime.setValue
34
32
  import androidx.compose.ui.text.font.FontFamily
35
33
  import androidx.lifecycle.Lifecycle
36
34
  import PeachComposeMount
35
+ import PeachWindowInsets
36
+ import readPeachWindowInsets
37
37
  import addMount
38
38
  import mounts
39
39
  import preparePeachDevice
@@ -64,42 +64,13 @@ internal class PeachAppSpec(
64
64
  // the app's view models, each built with the constructor the device's
65
65
  // default factory finds for it
66
66
  val viewModels: ViewModelProvider.Factory,
67
+ val predictiveBack: Boolean,
67
68
  )
68
69
 
69
70
  internal fun viewModelFactory(): ViewModelProvider.Factory = runningApp().spec.viewModels
70
71
 
71
72
  internal fun peachApplication(): Application = runningApp().application
72
73
 
73
- // the insets the device delivers to the window's content, in pixels: all of
74
- // them on an edge-to-edge window, none once the decor fits system windows.
75
- // insets lists the status bars, navigation bars, display cutout, system
76
- // gestures, mandatory system gestures and tappable element, each left, top,
77
- // right and bottom. the IME's inset is the keyboard's height above the
78
- // screen's bottom edge, which moves with the keyboard frame by frame.
79
- private class DeviceInsets(private val window: Window, insets: String, imeBottom: () -> Int) : PlatformWindowInsets {
80
- private val pixels = insets.split(',').map { it.toInt() }.also { require(it.size == 24) }
81
-
82
- // read when compose lays out, so a later change to the window applies
83
- private fun type(index: Int): PlatformInsets {
84
- fun side(offset: Int) = { if (window.fitsSystemWindows) 0 else pixels[index * 4 + offset] }
85
- return PlatformInsets(side(0), side(1), side(2), side(3))
86
- }
87
-
88
- override val statusBars = type(0)
89
- override val navigationBars = type(1)
90
- override val displayCutout = type(2)
91
- override val systemGestures = type(3)
92
- override val mandatorySystemGestures = type(4)
93
- override val tappableElement = type(5)
94
- override val ime = PlatformInsets({ 0 }, { 0 }, { 0 }, { if (window.fitsSystemWindows) 0 else imeBottom() })
95
- override val systemBars = PlatformInsets(
96
- { maxOf(statusBars.left, navigationBars.left) },
97
- { maxOf(statusBars.top, navigationBars.top) },
98
- { maxOf(statusBars.right, navigationBars.right) },
99
- { maxOf(statusBars.bottom, navigationBars.bottom) },
100
- )
101
- }
102
-
103
74
  private class ActivityOwners(activity: ComponentActivity) : PlatformArchitectureComponentsOwner {
104
75
  override val lifecycleOwner = activity
105
76
  override val viewModelStoreOwner = activity
@@ -113,11 +84,13 @@ private class ActivityOwners(activity: ComponentActivity) : PlatformArchitecture
113
84
  private class AppProcess(
114
85
  val spec: PeachAppSpec,
115
86
  val application: Application,
116
- val density: Float, val fontScale: Float, val locale: String, val gpu: Boolean, val stencilBits: Int,
87
+ val density: Float, val fontScale: Float, val locale: String,
117
88
  val fonts: FontFamily,
118
- val insets: String,
89
+ insets: String,
119
90
  val invalidate: (Boolean) -> Unit,
120
91
  ) {
92
+ var insets by mutableStateOf(readPeachWindowInsets(insets))
93
+ var visibleSystemBars by mutableStateOf(3)
121
94
  lateinit var activity: Activity
122
95
  lateinit var mount: PeachComposeMount
123
96
  // the window the device presents, once its scene is in place
@@ -135,6 +108,7 @@ private class AppProcess(
135
108
  var reportedNight = false
136
109
  // the software keyboard's height above the screen's bottom edge, in pixels
137
110
  var ime by mutableIntStateOf(0)
111
+ var imeVisible by mutableStateOf(false)
138
112
  // the configuration the content view composes with: a copy the view's
139
113
  // configuration change replaces, as AndroidComposeView's observer does
140
114
  val configuration = mutableStateOf(Configuration(), neverEqualPolicy())
@@ -154,28 +128,27 @@ private fun deviceConfiguration(night: Boolean, locale: String) = Configuration(
154
128
  // window added, which attaches the content view and composes it.
155
129
  internal fun peachStartApp(
156
130
  spec: PeachAppSpec,
157
- density: Float, fontScale: Float, locale: String, backend: String, stencilBits: Int,
158
- regular: String, medium: String, bold: String,
131
+ density: Float, fontScale: Float, locale: String,
132
+ font: String,
159
133
  insets: String, night: Boolean,
160
134
  invalidate: (Boolean) -> Unit,
161
135
  ): String {
162
136
  try {
163
- require(backend == "graphite" || backend == "raster")
164
137
  preparePeachDevice(locale)
165
138
  val metrics = DisplayMetrics()
166
139
  metrics.densityDpi = (density * DisplayMetrics.DENSITY_DEFAULT).roundToInt()
167
140
  metrics.density = metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT.toFloat()
168
- processResources = Resources(deviceConfiguration(night, locale), metrics)
141
+ processResources = Resources(deviceConfiguration(night, locale), metrics, peachAppStrings, peachAppPlurals, peachAppArrays, peachAppColors)
169
142
  val application = spec.createApplication()
170
143
  application.onCreate()
171
144
  val app = AppProcess(
172
- spec, application, density, fontScale, locale, backend == "graphite", stencilBits,
173
- robotoFamily(regular, medium, bold), insets, invalidate,
145
+ spec, application, density, fontScale, locale,
146
+ robotoFamily(font), insets, invalidate,
174
147
  )
175
148
  process = app
176
149
  val view = launchActivity(app, null)
177
150
  val params = view.layoutParams
178
- return app.activity.window.describe().put("ok", true).put("id", app.mountId)
151
+ return app.activity.window.describe().put("dialogs", app.mount.dialogState()).put("ok", true).put("id", app.mountId)
179
152
  .put("wrapWidth", params?.width == ViewGroup.LayoutParams.WRAP_CONTENT)
180
153
  .put("wrapHeight", params?.height == ViewGroup.LayoutParams.WRAP_CONTENT)
181
154
  .put("softInputAdjust", spec.softInputAdjust)
@@ -216,7 +189,7 @@ private fun launchActivity(app: AppProcess, lastNonConfigurationInstance: Any?):
216
189
  // the window itself
217
190
  override fun windowChanged() {
218
191
  if (app.window === window)
219
- mount.emitAtFrame("window") { window.describe().toString() }
192
+ mount.emitAtFrame("window") { window.describe().put("dialogs", mount.dialogState()).toString() }
220
193
  }
221
194
  }
222
195
  // the theme the activity is created under: a relaunch after a night
@@ -230,6 +203,7 @@ private fun launchActivity(app: AppProcess, lastNonConfigurationInstance: Any?):
230
203
  window,
231
204
  lastNonConfigurationInstance,
232
205
  )
206
+ if (spec.predictiveBack) componentActivity?.onBackPressedDispatcher?.setOnBackInvokedDispatcher(window.onBackInvokedDispatcher)
233
207
  activity.performCreate(state)
234
208
  activity.performStart()
235
209
  if (state != null) activity.performRestoreInstanceState(state)
@@ -241,10 +215,10 @@ private fun launchActivity(app: AppProcess, lastNonConfigurationInstance: Any?):
241
215
  app.state = null
242
216
  app.reportedNight = activity.resources.configuration.isNight()
243
217
  mount = PeachComposeMount(
244
- app.density, app.fontScale, app.locale, app.gpu, app.stencilBits, app.fonts, app.invalidate,
218
+ app.density, app.fontScale, app.locale, app.fonts, app.invalidate,
245
219
  night = activity.resources.configuration.isNight(),
246
220
  owners = componentActivity?.let(::ActivityOwners),
247
- insets = DeviceInsets(window, app.insets) { app.ime },
221
+ insets = PeachWindowInsets({ app.insets }, { app.ime }, { window.fitsSystemWindows }),
248
222
  clockRunning = { componentActivity == null || componentActivity.lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED) },
249
223
  )
250
224
  app.configuration.value = Configuration().apply { setTo(activity.resources.configuration) }
@@ -268,7 +242,7 @@ private fun launchActivity(app: AppProcess, lastNonConfigurationInstance: Any?):
268
242
  // window, which the new instance may have set differently
269
243
  mount.constraints = app.mount.constraints
270
244
  mounts[app.mountId] = mount
271
- mount.emitAtFrame("window") { window.describe().toString() }
245
+ mount.emitAtFrame("window") { window.describe().put("dialogs", mount.dialogState()).toString() }
272
246
  app.invalidate(true)
273
247
  }
274
248
  app.mount = mount
@@ -289,9 +263,9 @@ private fun runningApp() = checkNotNull(process) { "the app is not running" }
289
263
  internal fun peachAppBack(predictive: Boolean): Boolean {
290
264
  val activity = runningApp().activity
291
265
  activity.movedTaskToBack = false
292
- val dispatcher = (activity as? ComponentActivity)?.onBackPressedDispatcher
266
+ if (runningApp().mount.dialogBack()) return true
293
267
  if (!predictive) activity.onBackPressed()
294
- else if (dispatcher?.hasEnabledCallbacks() == true) dispatcher.onBackPressed()
268
+ else if (activity.window.invokeBack()) Unit
295
269
  else activity.movedTaskToBack = true
296
270
  return !activity.movedTaskToBack
297
271
  }
@@ -344,11 +318,29 @@ private fun reportConfiguration(app: AppProcess): Boolean {
344
318
  return false
345
319
  }
346
320
 
347
- // the software keyboard moved: its inset reaches the window's content
348
- internal fun peachAppIme(bottom: Int) {
321
+ internal fun peachImeVisible(): Boolean {
322
+ val app = runningApp()
323
+ return !app.activity.window.fitsSystemWindows && app.imeVisible
324
+ }
325
+
326
+ internal fun peachSystemBarVisible(type: Int): Boolean = runningApp().visibleSystemBars and type != 0
327
+
328
+ internal fun peachAppInsets(insets: String, visibleSystemBars: Int) {
329
+ require(visibleSystemBars in 0..3) { "unsupported visible system bar types: $visibleSystemBars" }
330
+ val app = runningApp()
331
+ val next = readPeachWindowInsets(insets)
332
+ if (next == app.insets && visibleSystemBars == app.visibleSystemBars) return
333
+ app.insets = next
334
+ app.visibleSystemBars = visibleSystemBars
335
+ app.invalidate(true)
336
+ }
337
+
338
+ // keep visibility independent of height, then apply the content window's decor
339
+ internal fun peachAppIme(bottom: Int, visible: Boolean) {
349
340
  val app = runningApp()
350
- if (app.ime == bottom) return
341
+ if (app.ime == bottom && app.imeVisible == visible) return
351
342
  app.ime = bottom
343
+ app.imeVisible = visible
352
344
  app.invalidate(true)
353
345
  }
354
346