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.
- package/LICENSE +21 -0
- package/dist/cli/basalt.d.ts +3 -0
- package/dist/cli/basalt.d.ts.map +1 -0
- package/dist/cli/basalt.js +47 -0
- package/dist/cli/basalt.js.map +1 -0
- package/dist/cli/bundle-cli.d.ts +12 -0
- package/dist/cli/bundle-cli.d.ts.map +1 -0
- package/dist/cli/bundle-cli.js +124 -0
- package/dist/cli/bundle-cli.js.map +1 -0
- package/dist/cli/bundleWithAssets.d.ts +79 -0
- package/dist/cli/bundleWithAssets.d.ts.map +1 -0
- package/dist/cli/bundleWithAssets.js +198 -0
- package/dist/cli/bundleWithAssets.js.map +1 -0
- package/dist/cli/desktop.d.ts +339 -0
- package/dist/cli/desktop.d.ts.map +1 -0
- package/dist/cli/desktop.js +1029 -0
- package/dist/cli/desktop.js.map +1 -0
- package/dist/cli/doctor.d.ts +31 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +283 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/init.d.ts +77 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +442 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/metro.d.ts +49 -0
- package/dist/cli/metro.d.ts.map +1 -0
- package/dist/cli/metro.js +148 -0
- package/dist/cli/metro.js.map +1 -0
- package/dist/cli/packageApp.d.ts +102 -0
- package/dist/cli/packageApp.d.ts.map +1 -0
- package/dist/cli/packageApp.js +319 -0
- package/dist/cli/packageApp.js.map +1 -0
- package/dist/cli/steps.d.ts +34 -0
- package/dist/cli/steps.d.ts.map +1 -0
- package/dist/cli/steps.js +53 -0
- package/dist/cli/steps.js.map +1 -0
- package/dist/metro-config.d.ts +168 -0
- package/dist/metro-config.d.ts.map +1 -0
- package/dist/metro-config.js +671 -0
- package/dist/metro-config.js.map +1 -0
- package/dist/react-native.config.d.ts +7 -0
- package/dist/react-native.config.d.ts.map +1 -0
- package/dist/react-native.config.js +80 -0
- package/dist/react-native.config.js.map +1 -0
- package/dist/src/DragSource.d.ts +52 -0
- package/dist/src/DragSource.d.ts.map +1 -0
- package/dist/src/DragSource.js +97 -0
- package/dist/src/DragSource.js.map +1 -0
- package/dist/src/DropTarget.d.ts +58 -0
- package/dist/src/DropTarget.d.ts.map +1 -0
- package/dist/src/DropTarget.js +131 -0
- package/dist/src/DropTarget.js.map +1 -0
- package/dist/src/KeyHandler.d.ts +57 -0
- package/dist/src/KeyHandler.d.ts.map +1 -0
- package/dist/src/KeyHandler.js +48 -0
- package/dist/src/KeyHandler.js.map +1 -0
- package/dist/src/Menu.d.ts +72 -0
- package/dist/src/Menu.d.ts.map +1 -0
- package/dist/src/Menu.js +179 -0
- package/dist/src/Menu.js.map +1 -0
- package/dist/src/TitleBar.d.ts +75 -0
- package/dist/src/TitleBar.d.ts.map +1 -0
- package/dist/src/TitleBar.js +236 -0
- package/dist/src/TitleBar.js.map +1 -0
- package/dist/src/Window.d.ts +87 -0
- package/dist/src/Window.d.ts.map +1 -0
- package/dist/src/Window.js +248 -0
- package/dist/src/Window.js.map +1 -0
- package/dist/src/closeRequest.d.ts +55 -0
- package/dist/src/closeRequest.d.ts.map +1 -0
- package/dist/src/closeRequest.js +134 -0
- package/dist/src/closeRequest.js.map +1 -0
- package/dist/src/index.d.ts +45 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +92 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/overrides/Alert.d.ts +69 -0
- package/dist/src/overrides/Alert.d.ts.map +1 -0
- package/dist/src/overrides/Alert.js +112 -0
- package/dist/src/overrides/Alert.js.map +1 -0
- package/dist/src/overrides/BaseViewConfig.d.ts +28 -0
- package/dist/src/overrides/BaseViewConfig.d.ts.map +1 -0
- package/dist/src/overrides/BaseViewConfig.js +72 -0
- package/dist/src/overrides/BaseViewConfig.js.map +1 -0
- package/dist/src/overrides/Platform.linux.d.ts +10 -0
- package/dist/src/overrides/Platform.linux.d.ts.map +1 -0
- package/dist/src/overrides/Platform.linux.js +15 -0
- package/dist/src/overrides/Platform.linux.js.map +1 -0
- package/dist/src/overrides/Platform.macos.d.ts +10 -0
- package/dist/src/overrides/Platform.macos.d.ts.map +1 -0
- package/dist/src/overrides/Platform.macos.js +15 -0
- package/dist/src/overrides/Platform.macos.js.map +1 -0
- package/dist/src/overrides/Platform.windows.d.ts +10 -0
- package/dist/src/overrides/Platform.windows.d.ts.map +1 -0
- package/dist/src/overrides/Platform.windows.js +15 -0
- package/dist/src/overrides/Platform.windows.js.map +1 -0
- package/dist/src/overrides/ReactDevToolsSettingsManager.d.ts +24 -0
- package/dist/src/overrides/ReactDevToolsSettingsManager.d.ts.map +1 -0
- package/dist/src/overrides/ReactDevToolsSettingsManager.js +30 -0
- package/dist/src/overrides/ReactDevToolsSettingsManager.js.map +1 -0
- package/dist/src/overrides/RefreshControl.d.ts +52 -0
- package/dist/src/overrides/RefreshControl.d.ts.map +1 -0
- package/dist/src/overrides/RefreshControl.js +92 -0
- package/dist/src/overrides/RefreshControl.js.map +1 -0
- package/dist/src/overrides/ScrollView.d.ts +39 -0
- package/dist/src/overrides/ScrollView.d.ts.map +1 -0
- package/dist/src/overrides/ScrollView.js +59 -0
- package/dist/src/overrides/ScrollView.js.map +1 -0
- package/dist/src/overrides/Share.d.ts +96 -0
- package/dist/src/overrides/Share.d.ts.map +1 -0
- package/dist/src/overrides/Share.js +97 -0
- package/dist/src/overrides/Share.js.map +1 -0
- package/dist/src/overrides/TextInput.d.ts +81 -0
- package/dist/src/overrides/TextInput.d.ts.map +1 -0
- package/dist/src/overrides/TextInput.js +213 -0
- package/dist/src/overrides/TextInput.js.map +1 -0
- package/dist/src/overrides/View.d.ts +36 -0
- package/dist/src/overrides/View.d.ts.map +1 -0
- package/dist/src/overrides/View.js +99 -0
- package/dist/src/overrides/View.js.map +1 -0
- package/dist/src/overrides/createPlatform.d.ts +32 -0
- package/dist/src/overrides/createPlatform.d.ts.map +1 -0
- package/dist/src/overrides/createPlatform.js +84 -0
- package/dist/src/overrides/createPlatform.js.map +1 -0
- package/dist/src/overrides/setUpDeveloperTools.d.ts +28 -0
- package/dist/src/overrides/setUpDeveloperTools.d.ts.map +1 -0
- package/dist/src/overrides/setUpDeveloperTools.js +84 -0
- package/dist/src/overrides/setUpDeveloperTools.js.map +1 -0
- package/dist/src/overrides/setUpXHR.d.ts +46 -0
- package/dist/src/overrides/setUpXHR.d.ts.map +1 -0
- package/dist/src/overrides/setUpXHR.js +236 -0
- package/dist/src/overrides/setUpXHR.js.map +1 -0
- package/dist/src/quitRequest.d.ts +55 -0
- package/dist/src/quitRequest.d.ts.map +1 -0
- package/dist/src/quitRequest.js +121 -0
- package/dist/src/quitRequest.js.map +1 -0
- package/dist/src/resourcePath.d.ts +18 -0
- package/dist/src/resourcePath.d.ts.map +1 -0
- package/dist/src/resourcePath.js +31 -0
- package/dist/src/resourcePath.js.map +1 -0
- package/dist/src/responseBody.d.ts +76 -0
- package/dist/src/responseBody.d.ts.map +1 -0
- package/dist/src/responseBody.js +94 -0
- package/dist/src/responseBody.js.map +1 -0
- package/dist/src/responseHeaders.d.ts +40 -0
- package/dist/src/responseHeaders.d.ts.map +1 -0
- package/dist/src/responseHeaders.js +75 -0
- package/dist/src/responseHeaders.js.map +1 -0
- package/dist/src/titleBarState.d.ts +43 -0
- package/dist/src/titleBarState.d.ts.map +1 -0
- package/dist/src/titleBarState.js +77 -0
- package/dist/src/titleBarState.js.map +1 -0
- package/dist/src/useContextMenu.d.ts +113 -0
- package/dist/src/useContextMenu.d.ts.map +1 -0
- package/dist/src/useContextMenu.js +109 -0
- package/dist/src/useContextMenu.js.map +1 -0
- package/dist/src/useDialog.d.ts +98 -0
- package/dist/src/useDialog.d.ts.map +1 -0
- package/dist/src/useDialog.js +112 -0
- package/dist/src/useDialog.js.map +1 -0
- package/dist/src/useDisplays.d.ts +70 -0
- package/dist/src/useDisplays.d.ts.map +1 -0
- package/dist/src/useDisplays.js +118 -0
- package/dist/src/useDisplays.js.map +1 -0
- package/dist/src/useHandledKeys.d.ts +38 -0
- package/dist/src/useHandledKeys.d.ts.map +1 -0
- package/dist/src/useHandledKeys.js +70 -0
- package/dist/src/useHandledKeys.js.map +1 -0
- package/dist/src/useWindow.d.ts +140 -0
- package/dist/src/useWindow.d.ts.map +1 -0
- package/dist/src/useWindow.js +233 -0
- package/dist/src/useWindow.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/native/CMakeLists.txt +355 -0
- package/native/bootstrap.sh +613 -0
- package/native/cmake/CompilerFlags.cmake +49 -0
- package/native/cmake/Expo.cmake +125 -0
- package/native/cmake/ReactNativeCore.cmake +612 -0
- package/native/cmake/Reanimated.cmake +108 -0
- package/native/cmake/Skia.cmake +379 -0
- package/native/cmake/ThirdParty.cmake +290 -0
- package/native/cmake/Worklets.cmake +67 -0
- package/native/cmake/codegen/CMakeLists.txt +32 -0
- package/native/core/AppIdentity.cpp +85 -0
- package/native/core/AppIdentity.h +59 -0
- package/native/core/AppPaths.cpp +96 -0
- package/native/core/AppPaths.h +53 -0
- package/native/core/AppearanceModule.cpp +60 -0
- package/native/core/AppearanceModule.h +40 -0
- package/native/core/Backface.h +59 -0
- package/native/core/BlobModule.cpp +283 -0
- package/native/core/BlobModule.h +76 -0
- package/native/core/BlobRegistry.cpp +75 -0
- package/native/core/BlobRegistry.h +44 -0
- package/native/core/ColorScheme.cpp +105 -0
- package/native/core/ColorScheme.h +59 -0
- package/native/core/ComponentRegistry.h +30 -0
- package/native/core/ControlMetrics.h +37 -0
- package/native/core/CoreModules.cpp +592 -0
- package/native/core/CoreModules.h +308 -0
- package/native/core/DebuggingOverlay.cpp +106 -0
- package/native/core/DebuggingOverlay.h +65 -0
- package/native/core/DesktopControls.cpp +232 -0
- package/native/core/DesktopControls.h +170 -0
- package/native/core/DevBundle.cpp +108 -0
- package/native/core/DevBundle.h +69 -0
- package/native/core/DevMenu.cpp +99 -0
- package/native/core/DevMenu.h +75 -0
- package/native/core/DialogModule.cpp +150 -0
- package/native/core/DialogModule.h +51 -0
- package/native/core/DragAndDrop.cpp +45 -0
- package/native/core/DragAndDrop.h +225 -0
- package/native/core/ExpoImageComponent.cpp +79 -0
- package/native/core/ExpoImageComponent.h +80 -0
- package/native/core/ExpoModules.cpp +415 -0
- package/native/core/ExpoModules.h +115 -0
- package/native/core/ExpoRuntime.cpp +366 -0
- package/native/core/ExpoRuntime.h +42 -0
- package/native/core/FocusRing.h +36 -0
- package/native/core/FontRegistry.h +51 -0
- package/native/core/GestureHandlerModule.cpp +136 -0
- package/native/core/GestureHandlerModule.h +71 -0
- package/native/core/Gestures.cpp +533 -0
- package/native/core/Gestures.h +145 -0
- package/native/core/HoverTracker.cpp +69 -0
- package/native/core/HoverTracker.h +109 -0
- package/native/core/HttpClient.cpp +282 -0
- package/native/core/ImageBytes.cpp +205 -0
- package/native/core/ImageBytes.h +29 -0
- package/native/core/ImageCache.cpp +51 -0
- package/native/core/ImageCache.h +89 -0
- package/native/core/JsRuntimeAccess.cpp +70 -0
- package/native/core/JsRuntimeAccess.h +60 -0
- package/native/core/JsiPromise.h +51 -0
- package/native/core/KeyEvents.cpp +116 -0
- package/native/core/KeyEvents.h +144 -0
- package/native/core/LogBoxSurface.cpp +46 -0
- package/native/core/LogBoxSurface.h +68 -0
- package/native/core/MenuModel.h +117 -0
- package/native/core/MenuModule.cpp +209 -0
- package/native/core/MenuModule.h +66 -0
- package/native/core/MountingWalk.h +524 -0
- package/native/core/PackageModules.cpp.in +25 -0
- package/native/core/PackageModules.h +50 -0
- package/native/core/PlatformConstantsModule.cpp +63 -0
- package/native/core/PlatformConstantsModule.h +64 -0
- package/native/core/PlatformServices.h +213 -0
- package/native/core/PointerButtons.h +63 -0
- package/native/core/PullToRefresh.cpp +57 -0
- package/native/core/PullToRefresh.h +73 -0
- package/native/core/ReanimatedCompat.h +47 -0
- package/native/core/ReanimatedModule.cpp +203 -0
- package/native/core/ReanimatedModule.h +55 -0
- package/native/core/ScrollAnimation.cpp +59 -0
- package/native/core/ScrollAnimation.h +70 -0
- package/native/core/ScrollBounds.cpp +26 -0
- package/native/core/ScrollBounds.h +68 -0
- package/native/core/ScrollIndicator.cpp +50 -0
- package/native/core/ScrollIndicator.h +69 -0
- package/native/core/ScrollMomentum.cpp +71 -0
- package/native/core/ScrollMomentum.h +73 -0
- package/native/core/ScrollSnap.cpp +123 -0
- package/native/core/ScrollSnap.h +80 -0
- package/native/core/ShareFallback.cpp +101 -0
- package/native/core/ShareFallback.h +45 -0
- package/native/core/SkiaPictureViewComponent.cpp +11 -0
- package/native/core/SkiaPictureViewComponent.h +47 -0
- package/native/core/SourceCodeModule.cpp +55 -0
- package/native/core/SourceCodeModule.h +53 -0
- package/native/core/StatusBarModule.cpp +23 -0
- package/native/core/StatusBarModule.h +42 -0
- package/native/core/TestDialog.cpp +148 -0
- package/native/core/TestDialog.h +96 -0
- package/native/core/TestKeys.cpp +78 -0
- package/native/core/TestKeys.h +50 -0
- package/native/core/TestQuitFile.cpp +33 -0
- package/native/core/TestQuitFile.h +60 -0
- package/native/core/TestSettle.h +192 -0
- package/native/core/TitleBarRegions.h +31 -0
- package/native/core/TurboModuleProxy.cpp +51 -0
- package/native/core/TurboModuleProxy.h +46 -0
- package/native/core/UIManagerAccess.cpp +43 -0
- package/native/core/UIManagerAccess.h +43 -0
- package/native/core/WindowBoundsCache.cpp +319 -0
- package/native/core/WindowControl.h +235 -0
- package/native/core/WindowHost.h +158 -0
- package/native/core/WindowMethods.cpp +167 -0
- package/native/core/WindowMethods.h +84 -0
- package/native/core/WindowsModule.cpp +448 -0
- package/native/core/WindowsModule.h +133 -0
- package/native/core/WorkletsModule.cpp +199 -0
- package/native/core/WorkletsModule.h +57 -0
- package/native/core/portability_probe.cpp +210 -0
- package/native/tests/EventRecorder.h +124 -0
- package/native/tests/TestHarness.cpp +109 -0
- package/native/tests/TestHarness.h +89 -0
- package/native/tests/TreeDump.h +49 -0
- package/native/tests/test_app_identity.cpp +114 -0
- package/native/tests/test_app_paths.cpp +48 -0
- package/native/tests/test_appearance.cpp +107 -0
- package/native/tests/test_backface.cpp +79 -0
- package/native/tests/test_blobs.cpp +157 -0
- package/native/tests/test_controls.cpp +185 -0
- package/native/tests/test_devbundle.cpp +103 -0
- package/native/tests/test_drag_and_drop.cpp +143 -0
- package/native/tests/test_gestures.cpp +331 -0
- package/native/tests/test_hover.cpp +92 -0
- package/native/tests/test_image_cache.cpp +109 -0
- package/native/tests/test_js_runtime_access.cpp +137 -0
- package/native/tests/test_key_events.cpp +235 -0
- package/native/tests/test_momentum.cpp +138 -0
- package/native/tests/test_quit_file.cpp +104 -0
- package/native/tests/test_scroll_animation.cpp +120 -0
- package/native/tests/test_scroll_bounds.cpp +66 -0
- package/native/tests/test_scroll_indicator.cpp +149 -0
- package/native/tests/test_scroll_snap.cpp +112 -0
- package/native/tests/test_settle.cpp +115 -0
- package/native/tests/test_share.cpp +75 -0
- package/native/tests/test_sourcecode.cpp +62 -0
- package/native/tests/test_window_close.cpp +119 -0
- package/native/tests/test_window_limits.cpp +123 -0
- package/package.json +43 -0
- package/react-native.config.js +86 -0
- 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
|