basalt-core 0.0.0-rc5

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 (325) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cli/basalt.d.ts +3 -0
  3. package/dist/cli/basalt.d.ts.map +1 -0
  4. package/dist/cli/basalt.js +47 -0
  5. package/dist/cli/basalt.js.map +1 -0
  6. package/dist/cli/bundle-cli.d.ts +12 -0
  7. package/dist/cli/bundle-cli.d.ts.map +1 -0
  8. package/dist/cli/bundle-cli.js +124 -0
  9. package/dist/cli/bundle-cli.js.map +1 -0
  10. package/dist/cli/bundleWithAssets.d.ts +79 -0
  11. package/dist/cli/bundleWithAssets.d.ts.map +1 -0
  12. package/dist/cli/bundleWithAssets.js +198 -0
  13. package/dist/cli/bundleWithAssets.js.map +1 -0
  14. package/dist/cli/desktop.d.ts +339 -0
  15. package/dist/cli/desktop.d.ts.map +1 -0
  16. package/dist/cli/desktop.js +1029 -0
  17. package/dist/cli/desktop.js.map +1 -0
  18. package/dist/cli/doctor.d.ts +31 -0
  19. package/dist/cli/doctor.d.ts.map +1 -0
  20. package/dist/cli/doctor.js +283 -0
  21. package/dist/cli/doctor.js.map +1 -0
  22. package/dist/cli/init.d.ts +77 -0
  23. package/dist/cli/init.d.ts.map +1 -0
  24. package/dist/cli/init.js +442 -0
  25. package/dist/cli/init.js.map +1 -0
  26. package/dist/cli/metro.d.ts +49 -0
  27. package/dist/cli/metro.d.ts.map +1 -0
  28. package/dist/cli/metro.js +148 -0
  29. package/dist/cli/metro.js.map +1 -0
  30. package/dist/cli/packageApp.d.ts +102 -0
  31. package/dist/cli/packageApp.d.ts.map +1 -0
  32. package/dist/cli/packageApp.js +319 -0
  33. package/dist/cli/packageApp.js.map +1 -0
  34. package/dist/cli/steps.d.ts +34 -0
  35. package/dist/cli/steps.d.ts.map +1 -0
  36. package/dist/cli/steps.js +53 -0
  37. package/dist/cli/steps.js.map +1 -0
  38. package/dist/metro-config.d.ts +168 -0
  39. package/dist/metro-config.d.ts.map +1 -0
  40. package/dist/metro-config.js +671 -0
  41. package/dist/metro-config.js.map +1 -0
  42. package/dist/react-native.config.d.ts +7 -0
  43. package/dist/react-native.config.d.ts.map +1 -0
  44. package/dist/react-native.config.js +80 -0
  45. package/dist/react-native.config.js.map +1 -0
  46. package/dist/src/DragSource.d.ts +52 -0
  47. package/dist/src/DragSource.d.ts.map +1 -0
  48. package/dist/src/DragSource.js +97 -0
  49. package/dist/src/DragSource.js.map +1 -0
  50. package/dist/src/DropTarget.d.ts +58 -0
  51. package/dist/src/DropTarget.d.ts.map +1 -0
  52. package/dist/src/DropTarget.js +131 -0
  53. package/dist/src/DropTarget.js.map +1 -0
  54. package/dist/src/KeyHandler.d.ts +57 -0
  55. package/dist/src/KeyHandler.d.ts.map +1 -0
  56. package/dist/src/KeyHandler.js +48 -0
  57. package/dist/src/KeyHandler.js.map +1 -0
  58. package/dist/src/Menu.d.ts +72 -0
  59. package/dist/src/Menu.d.ts.map +1 -0
  60. package/dist/src/Menu.js +179 -0
  61. package/dist/src/Menu.js.map +1 -0
  62. package/dist/src/TitleBar.d.ts +75 -0
  63. package/dist/src/TitleBar.d.ts.map +1 -0
  64. package/dist/src/TitleBar.js +236 -0
  65. package/dist/src/TitleBar.js.map +1 -0
  66. package/dist/src/Window.d.ts +87 -0
  67. package/dist/src/Window.d.ts.map +1 -0
  68. package/dist/src/Window.js +248 -0
  69. package/dist/src/Window.js.map +1 -0
  70. package/dist/src/closeRequest.d.ts +55 -0
  71. package/dist/src/closeRequest.d.ts.map +1 -0
  72. package/dist/src/closeRequest.js +134 -0
  73. package/dist/src/closeRequest.js.map +1 -0
  74. package/dist/src/index.d.ts +45 -0
  75. package/dist/src/index.d.ts.map +1 -0
  76. package/dist/src/index.js +92 -0
  77. package/dist/src/index.js.map +1 -0
  78. package/dist/src/overrides/Alert.d.ts +69 -0
  79. package/dist/src/overrides/Alert.d.ts.map +1 -0
  80. package/dist/src/overrides/Alert.js +112 -0
  81. package/dist/src/overrides/Alert.js.map +1 -0
  82. package/dist/src/overrides/BaseViewConfig.d.ts +28 -0
  83. package/dist/src/overrides/BaseViewConfig.d.ts.map +1 -0
  84. package/dist/src/overrides/BaseViewConfig.js +72 -0
  85. package/dist/src/overrides/BaseViewConfig.js.map +1 -0
  86. package/dist/src/overrides/Platform.linux.d.ts +10 -0
  87. package/dist/src/overrides/Platform.linux.d.ts.map +1 -0
  88. package/dist/src/overrides/Platform.linux.js +15 -0
  89. package/dist/src/overrides/Platform.linux.js.map +1 -0
  90. package/dist/src/overrides/Platform.macos.d.ts +10 -0
  91. package/dist/src/overrides/Platform.macos.d.ts.map +1 -0
  92. package/dist/src/overrides/Platform.macos.js +15 -0
  93. package/dist/src/overrides/Platform.macos.js.map +1 -0
  94. package/dist/src/overrides/Platform.windows.d.ts +10 -0
  95. package/dist/src/overrides/Platform.windows.d.ts.map +1 -0
  96. package/dist/src/overrides/Platform.windows.js +15 -0
  97. package/dist/src/overrides/Platform.windows.js.map +1 -0
  98. package/dist/src/overrides/ReactDevToolsSettingsManager.d.ts +24 -0
  99. package/dist/src/overrides/ReactDevToolsSettingsManager.d.ts.map +1 -0
  100. package/dist/src/overrides/ReactDevToolsSettingsManager.js +30 -0
  101. package/dist/src/overrides/ReactDevToolsSettingsManager.js.map +1 -0
  102. package/dist/src/overrides/RefreshControl.d.ts +52 -0
  103. package/dist/src/overrides/RefreshControl.d.ts.map +1 -0
  104. package/dist/src/overrides/RefreshControl.js +92 -0
  105. package/dist/src/overrides/RefreshControl.js.map +1 -0
  106. package/dist/src/overrides/ScrollView.d.ts +39 -0
  107. package/dist/src/overrides/ScrollView.d.ts.map +1 -0
  108. package/dist/src/overrides/ScrollView.js +59 -0
  109. package/dist/src/overrides/ScrollView.js.map +1 -0
  110. package/dist/src/overrides/Share.d.ts +96 -0
  111. package/dist/src/overrides/Share.d.ts.map +1 -0
  112. package/dist/src/overrides/Share.js +97 -0
  113. package/dist/src/overrides/Share.js.map +1 -0
  114. package/dist/src/overrides/TextInput.d.ts +81 -0
  115. package/dist/src/overrides/TextInput.d.ts.map +1 -0
  116. package/dist/src/overrides/TextInput.js +213 -0
  117. package/dist/src/overrides/TextInput.js.map +1 -0
  118. package/dist/src/overrides/View.d.ts +36 -0
  119. package/dist/src/overrides/View.d.ts.map +1 -0
  120. package/dist/src/overrides/View.js +99 -0
  121. package/dist/src/overrides/View.js.map +1 -0
  122. package/dist/src/overrides/createPlatform.d.ts +32 -0
  123. package/dist/src/overrides/createPlatform.d.ts.map +1 -0
  124. package/dist/src/overrides/createPlatform.js +84 -0
  125. package/dist/src/overrides/createPlatform.js.map +1 -0
  126. package/dist/src/overrides/setUpDeveloperTools.d.ts +28 -0
  127. package/dist/src/overrides/setUpDeveloperTools.d.ts.map +1 -0
  128. package/dist/src/overrides/setUpDeveloperTools.js +84 -0
  129. package/dist/src/overrides/setUpDeveloperTools.js.map +1 -0
  130. package/dist/src/overrides/setUpXHR.d.ts +46 -0
  131. package/dist/src/overrides/setUpXHR.d.ts.map +1 -0
  132. package/dist/src/overrides/setUpXHR.js +236 -0
  133. package/dist/src/overrides/setUpXHR.js.map +1 -0
  134. package/dist/src/quitRequest.d.ts +55 -0
  135. package/dist/src/quitRequest.d.ts.map +1 -0
  136. package/dist/src/quitRequest.js +121 -0
  137. package/dist/src/quitRequest.js.map +1 -0
  138. package/dist/src/resourcePath.d.ts +18 -0
  139. package/dist/src/resourcePath.d.ts.map +1 -0
  140. package/dist/src/resourcePath.js +31 -0
  141. package/dist/src/resourcePath.js.map +1 -0
  142. package/dist/src/responseBody.d.ts +76 -0
  143. package/dist/src/responseBody.d.ts.map +1 -0
  144. package/dist/src/responseBody.js +94 -0
  145. package/dist/src/responseBody.js.map +1 -0
  146. package/dist/src/responseHeaders.d.ts +40 -0
  147. package/dist/src/responseHeaders.d.ts.map +1 -0
  148. package/dist/src/responseHeaders.js +75 -0
  149. package/dist/src/responseHeaders.js.map +1 -0
  150. package/dist/src/titleBarState.d.ts +43 -0
  151. package/dist/src/titleBarState.d.ts.map +1 -0
  152. package/dist/src/titleBarState.js +77 -0
  153. package/dist/src/titleBarState.js.map +1 -0
  154. package/dist/src/useContextMenu.d.ts +113 -0
  155. package/dist/src/useContextMenu.d.ts.map +1 -0
  156. package/dist/src/useContextMenu.js +109 -0
  157. package/dist/src/useContextMenu.js.map +1 -0
  158. package/dist/src/useDialog.d.ts +98 -0
  159. package/dist/src/useDialog.d.ts.map +1 -0
  160. package/dist/src/useDialog.js +112 -0
  161. package/dist/src/useDialog.js.map +1 -0
  162. package/dist/src/useDisplays.d.ts +70 -0
  163. package/dist/src/useDisplays.d.ts.map +1 -0
  164. package/dist/src/useDisplays.js +118 -0
  165. package/dist/src/useDisplays.js.map +1 -0
  166. package/dist/src/useHandledKeys.d.ts +38 -0
  167. package/dist/src/useHandledKeys.d.ts.map +1 -0
  168. package/dist/src/useHandledKeys.js +70 -0
  169. package/dist/src/useHandledKeys.js.map +1 -0
  170. package/dist/src/useWindow.d.ts +140 -0
  171. package/dist/src/useWindow.d.ts.map +1 -0
  172. package/dist/src/useWindow.js +233 -0
  173. package/dist/src/useWindow.js.map +1 -0
  174. package/dist/tsconfig.tsbuildinfo +1 -0
  175. package/native/CMakeLists.txt +355 -0
  176. package/native/bootstrap.sh +613 -0
  177. package/native/cmake/CompilerFlags.cmake +49 -0
  178. package/native/cmake/Expo.cmake +125 -0
  179. package/native/cmake/ReactNativeCore.cmake +612 -0
  180. package/native/cmake/Reanimated.cmake +108 -0
  181. package/native/cmake/Skia.cmake +379 -0
  182. package/native/cmake/ThirdParty.cmake +290 -0
  183. package/native/cmake/Worklets.cmake +67 -0
  184. package/native/cmake/codegen/CMakeLists.txt +32 -0
  185. package/native/core/AppIdentity.cpp +85 -0
  186. package/native/core/AppIdentity.h +59 -0
  187. package/native/core/AppPaths.cpp +96 -0
  188. package/native/core/AppPaths.h +53 -0
  189. package/native/core/AppearanceModule.cpp +60 -0
  190. package/native/core/AppearanceModule.h +40 -0
  191. package/native/core/Backface.h +59 -0
  192. package/native/core/BlobModule.cpp +283 -0
  193. package/native/core/BlobModule.h +76 -0
  194. package/native/core/BlobRegistry.cpp +75 -0
  195. package/native/core/BlobRegistry.h +44 -0
  196. package/native/core/ColorScheme.cpp +105 -0
  197. package/native/core/ColorScheme.h +59 -0
  198. package/native/core/ComponentRegistry.h +30 -0
  199. package/native/core/ControlMetrics.h +37 -0
  200. package/native/core/CoreModules.cpp +592 -0
  201. package/native/core/CoreModules.h +308 -0
  202. package/native/core/DebuggingOverlay.cpp +106 -0
  203. package/native/core/DebuggingOverlay.h +65 -0
  204. package/native/core/DesktopControls.cpp +232 -0
  205. package/native/core/DesktopControls.h +170 -0
  206. package/native/core/DevBundle.cpp +108 -0
  207. package/native/core/DevBundle.h +69 -0
  208. package/native/core/DevMenu.cpp +99 -0
  209. package/native/core/DevMenu.h +75 -0
  210. package/native/core/DialogModule.cpp +150 -0
  211. package/native/core/DialogModule.h +51 -0
  212. package/native/core/DragAndDrop.cpp +45 -0
  213. package/native/core/DragAndDrop.h +225 -0
  214. package/native/core/ExpoImageComponent.cpp +79 -0
  215. package/native/core/ExpoImageComponent.h +80 -0
  216. package/native/core/ExpoModules.cpp +415 -0
  217. package/native/core/ExpoModules.h +115 -0
  218. package/native/core/ExpoRuntime.cpp +366 -0
  219. package/native/core/ExpoRuntime.h +42 -0
  220. package/native/core/FocusRing.h +36 -0
  221. package/native/core/FontRegistry.h +51 -0
  222. package/native/core/GestureHandlerModule.cpp +136 -0
  223. package/native/core/GestureHandlerModule.h +71 -0
  224. package/native/core/Gestures.cpp +533 -0
  225. package/native/core/Gestures.h +145 -0
  226. package/native/core/HoverTracker.cpp +69 -0
  227. package/native/core/HoverTracker.h +109 -0
  228. package/native/core/HttpClient.cpp +282 -0
  229. package/native/core/ImageBytes.cpp +205 -0
  230. package/native/core/ImageBytes.h +29 -0
  231. package/native/core/ImageCache.cpp +51 -0
  232. package/native/core/ImageCache.h +89 -0
  233. package/native/core/JsRuntimeAccess.cpp +70 -0
  234. package/native/core/JsRuntimeAccess.h +60 -0
  235. package/native/core/JsiPromise.h +51 -0
  236. package/native/core/KeyEvents.cpp +116 -0
  237. package/native/core/KeyEvents.h +144 -0
  238. package/native/core/LogBoxSurface.cpp +46 -0
  239. package/native/core/LogBoxSurface.h +68 -0
  240. package/native/core/MenuModel.h +117 -0
  241. package/native/core/MenuModule.cpp +209 -0
  242. package/native/core/MenuModule.h +66 -0
  243. package/native/core/MountingWalk.h +524 -0
  244. package/native/core/PackageModules.cpp.in +25 -0
  245. package/native/core/PackageModules.h +50 -0
  246. package/native/core/PlatformConstantsModule.cpp +63 -0
  247. package/native/core/PlatformConstantsModule.h +64 -0
  248. package/native/core/PlatformServices.h +213 -0
  249. package/native/core/PointerButtons.h +63 -0
  250. package/native/core/PullToRefresh.cpp +57 -0
  251. package/native/core/PullToRefresh.h +73 -0
  252. package/native/core/ReanimatedCompat.h +47 -0
  253. package/native/core/ReanimatedModule.cpp +203 -0
  254. package/native/core/ReanimatedModule.h +55 -0
  255. package/native/core/ScrollAnimation.cpp +59 -0
  256. package/native/core/ScrollAnimation.h +70 -0
  257. package/native/core/ScrollBounds.cpp +26 -0
  258. package/native/core/ScrollBounds.h +68 -0
  259. package/native/core/ScrollIndicator.cpp +50 -0
  260. package/native/core/ScrollIndicator.h +69 -0
  261. package/native/core/ScrollMomentum.cpp +71 -0
  262. package/native/core/ScrollMomentum.h +73 -0
  263. package/native/core/ScrollSnap.cpp +123 -0
  264. package/native/core/ScrollSnap.h +80 -0
  265. package/native/core/ShareFallback.cpp +101 -0
  266. package/native/core/ShareFallback.h +45 -0
  267. package/native/core/SkiaPictureViewComponent.cpp +11 -0
  268. package/native/core/SkiaPictureViewComponent.h +47 -0
  269. package/native/core/SourceCodeModule.cpp +55 -0
  270. package/native/core/SourceCodeModule.h +53 -0
  271. package/native/core/StatusBarModule.cpp +23 -0
  272. package/native/core/StatusBarModule.h +42 -0
  273. package/native/core/TestDialog.cpp +148 -0
  274. package/native/core/TestDialog.h +96 -0
  275. package/native/core/TestKeys.cpp +78 -0
  276. package/native/core/TestKeys.h +50 -0
  277. package/native/core/TestQuitFile.cpp +33 -0
  278. package/native/core/TestQuitFile.h +60 -0
  279. package/native/core/TestSettle.h +192 -0
  280. package/native/core/TitleBarRegions.h +31 -0
  281. package/native/core/TurboModuleProxy.cpp +51 -0
  282. package/native/core/TurboModuleProxy.h +46 -0
  283. package/native/core/UIManagerAccess.cpp +43 -0
  284. package/native/core/UIManagerAccess.h +43 -0
  285. package/native/core/WindowBoundsCache.cpp +319 -0
  286. package/native/core/WindowControl.h +235 -0
  287. package/native/core/WindowHost.h +158 -0
  288. package/native/core/WindowMethods.cpp +167 -0
  289. package/native/core/WindowMethods.h +84 -0
  290. package/native/core/WindowsModule.cpp +448 -0
  291. package/native/core/WindowsModule.h +133 -0
  292. package/native/core/WorkletsModule.cpp +199 -0
  293. package/native/core/WorkletsModule.h +57 -0
  294. package/native/core/portability_probe.cpp +210 -0
  295. package/native/tests/EventRecorder.h +124 -0
  296. package/native/tests/TestHarness.cpp +109 -0
  297. package/native/tests/TestHarness.h +89 -0
  298. package/native/tests/TreeDump.h +49 -0
  299. package/native/tests/test_app_identity.cpp +114 -0
  300. package/native/tests/test_app_paths.cpp +48 -0
  301. package/native/tests/test_appearance.cpp +107 -0
  302. package/native/tests/test_backface.cpp +79 -0
  303. package/native/tests/test_blobs.cpp +157 -0
  304. package/native/tests/test_controls.cpp +185 -0
  305. package/native/tests/test_devbundle.cpp +103 -0
  306. package/native/tests/test_drag_and_drop.cpp +143 -0
  307. package/native/tests/test_gestures.cpp +331 -0
  308. package/native/tests/test_hover.cpp +92 -0
  309. package/native/tests/test_image_cache.cpp +109 -0
  310. package/native/tests/test_js_runtime_access.cpp +137 -0
  311. package/native/tests/test_key_events.cpp +235 -0
  312. package/native/tests/test_momentum.cpp +138 -0
  313. package/native/tests/test_quit_file.cpp +104 -0
  314. package/native/tests/test_scroll_animation.cpp +120 -0
  315. package/native/tests/test_scroll_bounds.cpp +66 -0
  316. package/native/tests/test_scroll_indicator.cpp +149 -0
  317. package/native/tests/test_scroll_snap.cpp +112 -0
  318. package/native/tests/test_settle.cpp +115 -0
  319. package/native/tests/test_share.cpp +75 -0
  320. package/native/tests/test_sourcecode.cpp +62 -0
  321. package/native/tests/test_window_close.cpp +119 -0
  322. package/native/tests/test_window_limits.cpp +123 -0
  323. package/package.json +43 -0
  324. package/react-native.config.js +86 -0
  325. package/supported-versions.json +66 -0
@@ -0,0 +1,31 @@
1
+ // Which parts of an app-drawn header drag the window.
2
+ //
3
+ // `<TitleBar.DragRegion>` and `<TitleBar.NoDragRegion>` mark a view by setting
4
+ // its `nativeID`, because that is the one prop a plain <View> already carries
5
+ // all the way to the host on every platform. It is Electron's
6
+ // `app-region: drag | no-drag`, spelled in something React Native already has.
7
+ //
8
+ // The strings live here rather than in a host because every host that reads
9
+ // them has to read the *same* ones, and JavaScript writes them from a fourth
10
+ // place -- src/TitleBar.tsx, whose comment says they must match. Three copies
11
+ // of a string literal is three chances for a header that silently stops
12
+ // dragging on one desktop, which is a bug nobody notices until they try it.
13
+ //
14
+ // The rule each host applies is the same too, and worth stating once: the
15
+ // deepest view under the point, then each of its ancestors in turn, and the
16
+ // nearest one marked either way decides. So a label inside a drag region drags
17
+ // without being marked, a button inside one stays pressable once it is marked
18
+ // no-drag, and a point under nothing marked is ordinary client area.
19
+ //
20
+ // The hit test itself is per-host -- Win32 walks its own view tree, GTK asks
21
+ // the toolkit with gtk_widget_pick -- because the tree is the toolkit's, not
22
+ // this project's. Only the vocabulary is shared.
23
+
24
+ #pragma once
25
+
26
+ namespace basalt {
27
+
28
+ inline constexpr const char *kTitleBarDragRegionId = "basalt-titlebar-drag";
29
+ inline constexpr const char *kTitleBarNoDragRegionId = "basalt-titlebar-no-drag";
30
+
31
+ } // namespace basalt
@@ -0,0 +1,51 @@
1
+ #include "TurboModuleProxy.h"
2
+
3
+ #include <glog/logging.h>
4
+
5
+ #include <string>
6
+
7
+ namespace basalt {
8
+
9
+ using facebook::jsi::Function;
10
+ using facebook::jsi::Object;
11
+ using facebook::jsi::PropNameID;
12
+ using facebook::jsi::Runtime;
13
+ using facebook::jsi::Value;
14
+
15
+ void installTurboModuleProxy(Runtime &runtime) {
16
+ if (runtime.global().hasProperty(runtime, "__turboModuleProxy")) {
17
+ // A non-bridgeless runtime installed a real one. Leave it.
18
+ return;
19
+ }
20
+
21
+ runtime.global().setProperty(
22
+ runtime,
23
+ "__turboModuleProxy",
24
+ Function::createFromHostFunction(
25
+ runtime,
26
+ PropNameID::forAscii(runtime, "__turboModuleProxy"),
27
+ 1,
28
+ [](Runtime &rt, const Value & /*thisVal*/, const Value *args, size_t count) -> Value {
29
+ if (count < 1 || !args[0].isString()) {
30
+ return Value::undefined();
31
+ }
32
+ const std::string name = args[0].getString(rt).utf8(rt);
33
+ // `nativeModuleProxy` rather than a captured provider: it is what
34
+ // NativeModules reads, so this answers for the same set of modules
35
+ // by construction rather than by being kept in step.
36
+ const Value proxy = rt.global().getProperty(rt, "nativeModuleProxy");
37
+ if (!proxy.isObject()) {
38
+ return Value::undefined();
39
+ }
40
+ // Undefined for an unknown name, not an exception: a caller that
41
+ // asks for a module this platform does not have is the ordinary
42
+ // case, and `TurboModuleRegistry.get` is allowed to return null.
43
+ try {
44
+ return proxy.getObject(rt).getProperty(rt, PropNameID::forUtf8(rt, name));
45
+ } catch (const facebook::jsi::JSError &) {
46
+ return Value::undefined();
47
+ }
48
+ }));
49
+ }
50
+
51
+ } // namespace basalt
@@ -0,0 +1,46 @@
1
+ // `globalThis.__turboModuleProxy`, which this platform does not otherwise have.
2
+ //
3
+ // `TurboModuleRegistry.requireModule` asks two things in order:
4
+ //
5
+ // if (turboModuleProxy != null) { const m = turboModuleProxy(name); if (m) return m; }
6
+ // const legacy = NativeModules[name]; if (legacy) return legacy;
7
+ //
8
+ // and `TurboModuleBinding::install` installs the first only when `RN$Bridgeless`
9
+ // is absent, and `nativeModuleProxy` -- which is what `NativeModules` reads --
10
+ // otherwise. This platform is bridgeless, so it gets the second and every lookup
11
+ // arrives by the fallback. On the React Native this is built against that is
12
+ // fine: the fallback is unconditional.
13
+ //
14
+ // It is not fine on 0.82 and earlier, where the fallback is gated behind
15
+ // `RN$Bridgeless !== true || RN$TurboInterop === true ||
16
+ // RN$UnifiedNativeModuleProxy === true`, all of which are false here. So on those
17
+ // versions every `getEnforcing` fails, starting with `PlatformConstants`, and an
18
+ // app has to prepend a flag to its own bundle to start at all. React Native's
19
+ // own modules are reached the same way, which is why this is not a niche
20
+ // problem on those versions -- it is all of them.
21
+ //
22
+ // This installs the first question as an alias for the second, so path one
23
+ // succeeds and the gate is never reached:
24
+ //
25
+ // __turboModuleProxy = name => nativeModuleProxy[name]
26
+ //
27
+ // **An alias rather than a second provider**, which is the point. Writing our own
28
+ // would see only the modules this platform registers and not React Native's, so
29
+ // it would answer null for `PlatformConstants` -- and on the very versions this
30
+ // exists for, a null from path one does not fall through. Delegating means it
31
+ // answers for exactly what the platform can answer for, whoever provides it.
32
+ //
33
+ // Read lazily, at call time, so it does not matter whether `nativeModuleProxy`
34
+ // exists yet when this runs. It does not replace an existing
35
+ // `__turboModuleProxy`: a non-bridgeless runtime has a real one, and this is not
36
+ // better than it.
37
+
38
+ #pragma once
39
+
40
+ #include <jsi/jsi.h>
41
+
42
+ namespace basalt {
43
+
44
+ void installTurboModuleProxy(facebook::jsi::Runtime &runtime);
45
+
46
+ } // namespace basalt
@@ -0,0 +1,43 @@
1
+ #include "UIManagerAccess.h"
2
+
3
+ namespace basalt {
4
+
5
+ namespace {
6
+
7
+ std::weak_ptr<facebook::react::UIManager> &held() {
8
+ static std::weak_ptr<facebook::react::UIManager> uiManager;
9
+ return uiManager;
10
+ }
11
+
12
+ } // namespace
13
+
14
+ void setSharedUIManager(std::weak_ptr<facebook::react::UIManager> uiManager) {
15
+ held() = std::move(uiManager);
16
+ }
17
+
18
+ std::shared_ptr<facebook::react::UIManager> sharedUIManager() {
19
+ return held().lock();
20
+ }
21
+
22
+ namespace {
23
+
24
+ EventListenerInstaller &installer() {
25
+ static EventListenerInstaller function;
26
+ return function;
27
+ }
28
+
29
+ } // namespace
30
+
31
+ void setEventListenerInstaller(EventListenerInstaller function) {
32
+ installer() = std::move(function);
33
+ }
34
+
35
+ bool installEventListener(std::shared_ptr<const facebook::react::EventListener> listener) {
36
+ if (!installer()) {
37
+ return false;
38
+ }
39
+ installer()(std::move(listener));
40
+ return true;
41
+ }
42
+
43
+ } // namespace basalt
@@ -0,0 +1,43 @@
1
+ // The UIManager, for the one thing that needs it outside the renderer.
2
+ //
3
+ // Reanimated commits to the shadow tree itself -- that is how an animated style
4
+ // reaches the screen without a React re-render -- so it needs the UIManager,
5
+ // and it is constructed from JavaScript, where no host object is in reach.
6
+ //
7
+ // ReactCxxPlatform already hands the UIManager to the mounting manager through
8
+ // `IMountingManager::setUIManager`, whose default implementation ignores it. So
9
+ // each platform's mounting manager overrides that and puts it here, and the
10
+ // module takes it back out. Weak, because the UIManager belongs to the
11
+ // scheduler and outlives neither a reload nor a quit.
12
+
13
+ #pragma once
14
+
15
+ #include <react/renderer/core/EventListener.h>
16
+ #include <react/renderer/uimanager/UIManager.h>
17
+
18
+ #include <functional>
19
+
20
+ #include <memory>
21
+
22
+ namespace basalt {
23
+
24
+ void setSharedUIManager(std::weak_ptr<facebook::react::UIManager> uiManager);
25
+ std::shared_ptr<facebook::react::UIManager> sharedUIManager();
26
+
27
+ // Watching every event Fabric dispatches.
28
+ //
29
+ // `Scheduler::addEventListener` is how a library sees events before the
30
+ // components do -- Reanimated needs it so that a scroll handler or a gesture
31
+ // callback declared as a worklet runs on the UI thread rather than a frame
32
+ // later on the JavaScript one. The scheduler belongs to ReactHost, which only
33
+ // the host has, so the host leaves a way to reach it here.
34
+ using EventListenerInstaller =
35
+ std::function<void(std::shared_ptr<const facebook::react::EventListener>)>;
36
+
37
+ void setEventListenerInstaller(EventListenerInstaller installer);
38
+
39
+ // False when no host left one, which is every build that is not a host --
40
+ // the tests and the portability probe.
41
+ bool installEventListener(std::shared_ptr<const facebook::react::EventListener> listener);
42
+
43
+ } // namespace basalt
@@ -0,0 +1,319 @@
1
+ // The last bounds the host reported, readable from any thread.
2
+ //
3
+ // The other half of `notifyWindowBoundsChanged`, and the reason `getBounds()`
4
+ // can answer without a thread hop: a TurboModule method runs on the JavaScript
5
+ // thread, `windowBounds()` may only be called on the UI one, and an app reads
6
+ // bounds during render. A cache the host writes on every change is exact, and
7
+ // the alternative -- blocking the JavaScript thread on a hop to ask the
8
+ // toolkit -- would be a render that waits on a window manager.
9
+ //
10
+ // Deliberately not in each platform's file: the caching is identical in all
11
+ // three and the listener dispatch is what they would each have copied.
12
+
13
+ #include "WindowControl.h"
14
+ #include "WindowHost.h"
15
+
16
+ #include <mutex>
17
+ #include <set>
18
+ #include <utility>
19
+
20
+ namespace basalt {
21
+
22
+ namespace {
23
+
24
+ std::mutex &lock() {
25
+ static std::mutex value;
26
+ return value;
27
+ }
28
+
29
+ WindowBounds &cache() {
30
+ static WindowBounds bounds;
31
+ return bounds;
32
+ }
33
+
34
+ std::function<void(const WindowBounds &)> &listener() {
35
+ static std::function<void(const WindowBounds &)> value;
36
+ return value;
37
+ }
38
+
39
+ } // namespace
40
+
41
+ void setWindowBoundsListener(std::function<void(const WindowBounds &)> value) {
42
+ const std::lock_guard<std::mutex> guard(lock());
43
+ listener() = std::move(value);
44
+ }
45
+
46
+ // --- The displays, changing -------------------------------------------------
47
+ //
48
+ // Only the listener lives here. The list itself is not cached, unlike the
49
+ // window's bounds: bounds are read during render and must not hop, and a
50
+ // display list is read when an app is deciding where to put something, which
51
+ // is rare enough to afford the marshal -- and a stale display list is worse
52
+ // than a slow one, because the thing it is wrong about is whether a screen
53
+ // exists.
54
+
55
+ std::function<void()> &displaysListener() {
56
+ static std::function<void()> value;
57
+ return value;
58
+ }
59
+
60
+ void setDisplaysListener(std::function<void()> listener) {
61
+ const std::lock_guard<std::mutex> guard(lock());
62
+ displaysListener() = std::move(listener);
63
+ }
64
+
65
+ namespace {
66
+ std::vector<DisplayInfo> &displaysCache() {
67
+
68
+ static std::vector<DisplayInfo> value;
69
+ return value;
70
+ }
71
+ } // namespace
72
+
73
+ std::vector<DisplayInfo> lastKnownDisplays() {
74
+ const std::lock_guard<std::mutex> guard(lock());
75
+ return displaysCache();
76
+ }
77
+
78
+ void notifyDisplaysChanged() {
79
+ // Asked on the UI thread, which is where this is called from, and stored
80
+ // where the JavaScript thread can read it -- exactly what
81
+ // notifyWindowBoundsChanged does with the window's bounds.
82
+ //
83
+ // Which is also why this must be called once at startup and not only on a
84
+ // change: an app that asks before any monitor has been unplugged should not
85
+ // get an empty list.
86
+ std::vector<DisplayInfo> found = displays();
87
+
88
+ std::function<void()> toCall;
89
+ {
90
+ const std::lock_guard<std::mutex> guard(lock());
91
+ displaysCache() = std::move(found);
92
+ toCall = displaysListener();
93
+ }
94
+ // Outside the lock, for the reason notifyWindowBoundsChanged gives.
95
+ if (toCall) {
96
+ toCall();
97
+ }
98
+ }
99
+
100
+ // --- How big it may be ------------------------------------------------------
101
+ //
102
+ // Stored here rather than three times, and stored at all rather than simply
103
+ // handed to the toolkit, because Windows answers WM_GETMINMAXINFO -- a message
104
+ // that arrives whenever the window manager feels like asking, with nowhere to
105
+ // have passed the numbers in.
106
+
107
+ namespace {
108
+
109
+ WindowSizeLimits &limits() {
110
+ static WindowSizeLimits value;
111
+ return value;
112
+ }
113
+
114
+ } // namespace
115
+
116
+ void setWindowMinimumSize(double width, double height) {
117
+ {
118
+ const std::lock_guard<std::mutex> guard(lock());
119
+ // Negatives are the same as zero: "no limit". An app clearing a constraint
120
+ // is more likely to pass 0 than -1, and neither should be a window that
121
+ // cannot be smaller than minus one pixel.
122
+ limits().minWidth = width > 0.0 ? width : 0.0;
123
+ limits().minHeight = height > 0.0 ? height : 0.0;
124
+ }
125
+ applyWindowSizeLimits();
126
+ }
127
+
128
+ void setWindowMaximumSize(double width, double height) {
129
+ {
130
+ const std::lock_guard<std::mutex> guard(lock());
131
+ limits().maxWidth = width > 0.0 ? width : 0.0;
132
+ limits().maxHeight = height > 0.0 ? height : 0.0;
133
+ }
134
+ applyWindowSizeLimits();
135
+ }
136
+
137
+ void constrainToWindowSizeLimits(double &width, double &height) {
138
+ // `inForce` rather than `limits`, which is the name of the storage next door.
139
+ const WindowSizeLimits inForce = windowSizeLimits();
140
+ const WindowCapabilities able = windowCapabilities();
141
+ if (able.minimumSize) {
142
+ if (inForce.minWidth > 0.0 && width < inForce.minWidth) {
143
+ width = inForce.minWidth;
144
+ }
145
+ if (inForce.minHeight > 0.0 && height < inForce.minHeight) {
146
+ height = inForce.minHeight;
147
+ }
148
+ }
149
+ if (able.maximumSize) {
150
+ if (inForce.maxWidth > 0.0 && width > inForce.maxWidth) {
151
+ width = inForce.maxWidth;
152
+ }
153
+ if (inForce.maxHeight > 0.0 && height > inForce.maxHeight) {
154
+ height = inForce.maxHeight;
155
+ }
156
+ }
157
+ }
158
+
159
+ WindowSizeLimits windowSizeLimits() {
160
+ const std::lock_guard<std::mutex> guard(lock());
161
+ return limits();
162
+ }
163
+
164
+ WindowBounds lastKnownWindowBounds() {
165
+ const std::lock_guard<std::mutex> guard(lock());
166
+ return cache();
167
+ }
168
+
169
+ void notifyWindowBoundsChanged() {
170
+ // Asked on the UI thread, which is where this is called from, and stored
171
+ // where the JavaScript thread can read it.
172
+ const WindowBounds bounds = windowBounds();
173
+
174
+ std::function<void(const WindowBounds &)> toCall;
175
+ {
176
+ const std::lock_guard<std::mutex> guard(lock());
177
+ cache() = bounds;
178
+ toCall = listener();
179
+ }
180
+ // Called outside the lock: it emits a device event, and holding a lock across
181
+ // a call into the runtime is how a deadlock is built.
182
+ if (toCall) {
183
+ toCall(bounds);
184
+ }
185
+ }
186
+
187
+ // --- Windows closing themselves ----------------------------------------------
188
+ //
189
+ // Kept here rather than in each host for the same reason the bounds listener
190
+ // is: the storage and the null check are identical in all three, and what
191
+ // differs is only which toolkit notices.
192
+
193
+ namespace {
194
+
195
+ std::function<void(facebook::react::SurfaceId)> &closedListener() {
196
+ static std::function<void(facebook::react::SurfaceId)> value;
197
+ return value;
198
+ }
199
+
200
+ // Which windows have an app listening for close attempts, and the listener that
201
+ // tells it about one -- the "refusing to close" half below. Declared up here
202
+ // because `hostWindowClosed` forgets a window's interception on the way out.
203
+ std::set<facebook::react::SurfaceId> &intercepted() {
204
+ static std::set<facebook::react::SurfaceId> value;
205
+ return value;
206
+ }
207
+
208
+ std::function<void(facebook::react::SurfaceId)> &closeRequestListener() {
209
+ static std::function<void(facebook::react::SurfaceId)> value;
210
+ return value;
211
+ }
212
+
213
+ // Quitting is one question about the application rather than one per window,
214
+ // so this is a bool and not a set. See WindowHost.h for why it is a flag at
215
+ // all rather than a callback the system waits on.
216
+ bool &quitIntercepted() {
217
+ static bool value = false;
218
+ return value;
219
+ }
220
+
221
+ std::function<void()> &quitRequestListener() {
222
+ static std::function<void()> value;
223
+ return value;
224
+ }
225
+
226
+ } // namespace
227
+
228
+ void setHostWindowClosedListener(std::function<void(facebook::react::SurfaceId)> listener) {
229
+ const std::lock_guard<std::mutex> guard(lock());
230
+ closedListener() = std::move(listener);
231
+ }
232
+
233
+ void hostWindowClosed(facebook::react::SurfaceId surfaceId) {
234
+ std::function<void(facebook::react::SurfaceId)> toCall;
235
+ {
236
+ const std::lock_guard<std::mutex> guard(lock());
237
+ toCall = closedListener();
238
+ // A window that is gone cannot refuse anything, and leaving its id behind
239
+ // would mark whichever window is given that surface id next. Surface ids
240
+ // are not reused today; relying on that would be relying on it.
241
+ intercepted().erase(surfaceId);
242
+ }
243
+ // Outside the lock: it emits a device event, and holding a lock across a call
244
+ // into the runtime is how a deadlock is built.
245
+ if (toCall) {
246
+ toCall(surfaceId);
247
+ }
248
+ }
249
+
250
+ // --- Windows refusing to close ----------------------------------------------
251
+ //
252
+ // Here for the same reason as the rest of this file: three hosts would each
253
+ // have written the same set and the same null check, and what differs between
254
+ // them is only which toolkit message means "somebody is trying to close this".
255
+
256
+ void setHostWindowCloseIntercepted(facebook::react::SurfaceId surfaceId, bool value) {
257
+ const std::lock_guard<std::mutex> guard(lock());
258
+ if (value) {
259
+ intercepted().insert(surfaceId);
260
+ } else {
261
+ intercepted().erase(surfaceId);
262
+ }
263
+ }
264
+
265
+ bool hostWindowCloseIntercepted(facebook::react::SurfaceId surfaceId) {
266
+ const std::lock_guard<std::mutex> guard(lock());
267
+ return intercepted().count(surfaceId) != 0;
268
+ }
269
+
270
+ void setHostWindowCloseRequestListener(std::function<void(facebook::react::SurfaceId)> listener) {
271
+ const std::lock_guard<std::mutex> guard(lock());
272
+ closeRequestListener() = std::move(listener);
273
+ }
274
+
275
+ // --- The application refusing to quit ---------------------------------------
276
+ //
277
+ // The same shape one level up, and here for the same reason. What differs
278
+ // between the hosts is only which message means "the session is ending":
279
+ // `applicationShouldTerminate:`, `WM_QUERYENDSESSION`, and GTK's session
280
+ // manager.
281
+
282
+ void setHostQuitIntercepted(bool value) {
283
+ const std::lock_guard<std::mutex> guard(lock());
284
+ quitIntercepted() = value;
285
+ }
286
+
287
+ bool hostQuitIntercepted() {
288
+ const std::lock_guard<std::mutex> guard(lock());
289
+ return quitIntercepted();
290
+ }
291
+
292
+ void setHostQuitRequestListener(std::function<void()> listener) {
293
+ const std::lock_guard<std::mutex> guard(lock());
294
+ quitRequestListener() = std::move(listener);
295
+ }
296
+
297
+ void hostQuitRequested() {
298
+ std::function<void()> toCall;
299
+ {
300
+ const std::lock_guard<std::mutex> guard(lock());
301
+ toCall = quitRequestListener();
302
+ }
303
+ if (toCall) {
304
+ toCall();
305
+ }
306
+ }
307
+
308
+ void hostWindowCloseRequested(facebook::react::SurfaceId surfaceId) {
309
+ std::function<void(facebook::react::SurfaceId)> toCall;
310
+ {
311
+ const std::lock_guard<std::mutex> guard(lock());
312
+ toCall = closeRequestListener();
313
+ }
314
+ if (toCall) {
315
+ toCall(surfaceId);
316
+ }
317
+ }
318
+
319
+ } // namespace basalt