basalt-appkit 0.1.0 → 0.2.1

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.
@@ -88,6 +88,13 @@ get_property(BASALT_PACKAGE_APPKIT_LINK_LIBRARIES GLOBAL PROPERTY BASALT_PACKAGE
88
88
  # with a platform half has nowhere else to be tested: it is compiled into the
89
89
  # host binary, so the host's suite is the only binary that has it.
90
90
  get_property(BASALT_PACKAGE_TESTS GLOBAL PROPERTY BASALT_PACKAGE_TESTS)
91
+ # And the ones only this host can compile. A capability whose platform half is
92
+ # Apple's -- basalt-skia, whose Skia archives and Dawn are Apple binaries --
93
+ # has tests that are Objective-C++ or link those archives, and
94
+ # BASALT_PACKAGE_TESTS goes to all three suites. The GTK suite took them and
95
+ # failed on an `AppKitSkiaPeer.h` it has no path to, which is the cheap half of
96
+ # what it would have failed on.
97
+ get_property(BASALT_PACKAGE_APPKIT_TESTS GLOBAL PROPERTY BASALT_PACKAGE_APPKIT_TESTS)
91
98
 
92
99
  if(NOT APPLE)
93
100
  # Not an error. A checkout builds every package it finds, and on anything but
@@ -223,6 +230,34 @@ if(TARGET basalt_core)
223
230
  # has to provide is a link error rather than a discovery. It failed on exactly
224
231
  # those three symbols, which is the probe doing its job: this is a host's
225
232
  # dependency, not a portable one.
233
+ # What capability packages contributed for this host, compiled into the
234
+ # mounting library rather than into each executable that wants it.
235
+ #
236
+ # They were on the two executables (basalt_appkit and basalt_appkit_tests)
237
+ # and that was wrong in a way nothing here could see: this library *calls*
238
+ # into them -- AppKitMountingManager.mm calls applySkiaCanvas and
239
+ # forgetSkiaCanvas -- so every binary linking it needs the definitions, and
240
+ # mount_harness_appkit links it and got none. Found by building kino, where
241
+ # the link failed on exactly those two symbols; the repository's own build
242
+ # never caught it because basalt-skia contributes nothing without a Skia
243
+ # installed, and the one target built by hand while writing the canvas was
244
+ # basalt_appkit_tests, which had them.
245
+ #
246
+ # The 2.x peer beside this has always been a `target_sources` on this
247
+ # library, which is the shape this follows.
248
+ if(BASALT_PACKAGE_APPKIT_SOURCES)
249
+ target_sources(basalt_appkit_mounting PRIVATE ${BASALT_PACKAGE_APPKIT_SOURCES})
250
+ endif()
251
+ # And whatever those sources need linked, PUBLIC so it travels to every
252
+ # binary that links this library. The two executables name it themselves as
253
+ # well, which costs nothing -- a static archive named twice is searched
254
+ # twice -- and mount_harness_appkit names nothing, which is why this is
255
+ # here: it failed on `sk_abort_no_print` referenced from a
256
+ # BasaltSkPlatformContext.cpp now sitting in libbasalt_appkit_mounting.a.
257
+ if(BASALT_PACKAGE_APPKIT_LINK_LIBRARIES)
258
+ target_link_libraries(basalt_appkit_mounting PUBLIC ${BASALT_PACKAGE_APPKIT_LINK_LIBRARIES})
259
+ endif()
260
+
226
261
  if(TARGET skia_core)
227
262
  target_link_libraries(basalt_appkit_mounting PUBLIC skia_core "-framework AppKit")
228
263
  target_sources(basalt_appkit_mounting PUBLIC $<TARGET_OBJECTS:skia_core>)
@@ -250,8 +285,6 @@ if(TARGET basalt_core)
250
285
  appkit/AppKitAnimationChoreographer.mm
251
286
  appkit/AppKitFocus.mm
252
287
  appkit/AppKitKeyEvents.mm
253
- # Why macOS cannot show a notification; see the file.
254
- ${BASALT_PACKAGE_APPKIT_SOURCES}
255
288
  appkit/AppKitTouchDispatcher.mm)
256
289
  target_compile_options(basalt_appkit PRIVATE -Wall -Wextra -fobjc-arc)
257
290
  target_link_libraries(basalt_appkit PRIVATE basalt_appkit_mounting)
@@ -274,6 +307,7 @@ if(TARGET basalt_core)
274
307
  # no React Native, so no core -- compiles neither, rather than failing on a
275
308
  # package header it was never given the include path for.
276
309
  ${BASALT_PACKAGE_TESTS}
310
+ ${BASALT_PACKAGE_APPKIT_TESTS}
277
311
  tests/test_appkit_mounting.mm
278
312
  # Fonts loaded at runtime: core/FontRegistry.h's macOS half, and the
279
313
  # measurement cache a late registration has to invalidate. Needs React
@@ -283,8 +317,10 @@ if(TARGET basalt_core)
283
317
  # tests need it too, and it pulls in nothing else.
284
318
  appkit/AppKitFocus.mm
285
319
  appkit/AppKitKeyEvents.mm
286
- # Why macOS cannot show a notification; see the file.
287
- ${BASALT_PACKAGE_APPKIT_SOURCES}
320
+ # A capability package's AppKit sources are *not* listed here: with a
321
+ # mounting library they are compiled into it and arrive with the link, and
322
+ # compiling them again here would be a duplicate symbol in every one. The
323
+ # view-only branch, which has no mounting library, adds them below.
288
324
  appkit/AppKitTouchDispatcher.mm
289
325
  tests/test_appkit_input.mm
290
326
  tests/test_appkit_key_events.mm
@@ -296,6 +332,14 @@ if(TARGET basalt_core)
296
332
  tests/test_appkit_scrollview.mm)
297
333
  endif()
298
334
 
335
+ # Without a mounting library there is nowhere else for a package's AppKit
336
+ # sources to go, so the suite carries them. This is the view-only build: no
337
+ # React Native, no core, and a package source that needs either does not
338
+ # compile here anyway -- which is the honest place to find that out.
339
+ if(NOT TARGET basalt_appkit_mounting AND BASALT_PACKAGE_APPKIT_SOURCES)
340
+ list(APPEND BASALT_APPKIT_TEST_SOURCES ${BASALT_PACKAGE_APPKIT_SOURCES})
341
+ endif()
342
+
299
343
  add_executable(basalt_appkit_tests ${BASALT_APPKIT_TEST_SOURCES})
300
344
  target_compile_options(basalt_appkit_tests PRIVATE -Wall -Wextra -fobjc-arc)
301
345
  target_include_directories(basalt_appkit_tests PRIVATE ${BASALT_TEST_INCLUDE})
@@ -17,7 +17,10 @@
17
17
  #include "Gradients.h"
18
18
  #include "ExpoImageComponent.h"
19
19
  #include "ImageProgress.h"
20
- #ifdef BASALT_HAS_SKIA
20
+ // Either Skia: the 2.x peer in this package or the 3.x one in basalt-skia,
21
+ // which share this header's two functions and are never both linked. See
22
+ // AppKitSkiaPeer.h.
23
+ #if defined(BASALT_HAS_SKIA) || BASALT_HAS_SKIA_GRAPHITE
21
24
  #include "AppKitSkiaPeer.h"
22
25
  #endif
23
26
  #include "UIManagerAccess.h"
@@ -395,7 +398,7 @@ void AppKitMountingManager::forgetTag(Tag tag) {
395
398
  textInputs_.remove(tag);
396
399
  imageUris_.erase(tag);
397
400
  switchValues_.erase(tag);
398
- #ifdef BASALT_HAS_SKIA
401
+ #if defined(BASALT_HAS_SKIA) || BASALT_HAS_SKIA_GRAPHITE
399
402
  // Unregisters the canvas and takes its layer off the view. This is the one
400
403
  // moment a view is known to be finished with, which matters more here than
401
404
  // elsewhere: a canvas left registered keeps a Metal layer and a GPU surface
@@ -663,7 +666,7 @@ void AppKitMountingManager::updateView(RnAppKitView *view, const ShadowView &sha
663
666
  // needed the same swap for the same reason.
664
667
  applyTextInput(view, shadowView);
665
668
  applyAccessibility(view, shadowView);
666
- #ifdef BASALT_HAS_SKIA
669
+ #if defined(BASALT_HAS_SKIA) || BASALT_HAS_SKIA_GRAPHITE
667
670
  // After applyProps, which is what puts nativeID on the view -- a canvas
668
671
  // registers itself by that id and cannot be attached before it is there. And
669
672
  // before applyLayoutMetrics only incidentally: the size it reads comes from the
@@ -1,5 +1,20 @@
1
1
  // The AppKit half of a `<Canvas>`: a Metal layer inside an ordinary view.
2
2
  //
3
+ // **Two implementations, one at a time.** This header is the contract; which
4
+ // file defines it depends on which Skia the app installed. 2.x is Ganesh over
5
+ // Metal and its half is `AppKitSkiaPeer.mm` beside this, compiled when
6
+ // `BASALT_HAS_SKIA` says core's cmake/Skia.cmake built the Ganesh sources. 3.x
7
+ // is Graphite over Dawn and its half is
8
+ // `basalt-skia/native/appkit/BasaltSkiaCanvasAppKit.mm`, compiled when
9
+ // `BASALT_HAS_SKIA_GRAPHITE` says that package found Dawn. The two cannot both
10
+ // be true -- Skia.cmake refuses a 3.x install by version -- so exactly one
11
+ // definition of each function below is linked, and the mounting manager calls
12
+ // them under a guard that covers either.
13
+ //
14
+ // They differ in the component they answer to as well, which is 3.x's rename:
15
+ // a 2.x `<Canvas>` mounts a `SkiaPictureView` and a 3.x one a `SkiaView`. Both
16
+ // descriptors are registered on all three hosts.
17
+ //
3
18
  // The package's SkiaUIView is an RCTViewComponentView that does three things --
4
19
  // creates a drawing view, adds its layer as a sublayer of its own, and registers
5
20
  // it with RNSkManager under the nativeId. None of the three needs React Native;
@@ -24,6 +24,7 @@
24
24
  #include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
25
25
 
26
26
  #include "SkiaPictureViewComponent.h"
27
+ #include "SkiaViewComponent.h"
27
28
  #include <react/renderer/components/FBReactNativeSpec/ComponentDescriptors.h>
28
29
  #include <react/renderer/components/image/ImageComponentDescriptor.h>
29
30
  #include <react/renderer/components/iostextinput/TextInputComponentDescriptor.h>
@@ -81,11 +82,15 @@ ComponentRegistryFactory getDefaultComponentRegistryFactory() {
81
82
  // through a TextLayoutManager, which here is the Core Text one.
82
83
  // Android's needs fbjni. Its component name is "TextInput".
83
84
  registry->add(concreteComponentDescriptorProvider<TextInputComponentDescriptor>());
84
- // @shopify/react-native-skia's <Canvas>. Registered whether or not the
85
- // build has Skia in it, for the reason the Expo one below gives: it costs
86
- // a name in a registry. Without Skia the view mounts and stays empty, and
85
+ // React Native Skia's <Canvas>, under both of its names: 2.x mounts a
86
+ // "SkiaPictureView" and 3.x a "SkiaView", and which one an app mounts is
87
+ // decided by the Skia it installed, which a host binary cannot know
88
+ // until the app's JavaScript runs. Registered whether or not the build
89
+ // has Skia in it, for the reason the Expo one below gives: it costs a
90
+ // name in a registry. Without Skia the view mounts and stays empty, and
87
91
  // an app that draws has already failed at getEnforcing('RNSkiaModule').
88
92
  registry->add(concreteComponentDescriptorProvider<SkiaPictureViewComponentDescriptor>());
93
+ registry->add(concreteComponentDescriptorProvider<SkiaViewComponentDescriptor>());
89
94
  // expo-image's view. Registered whether or not the build has Expo in it:
90
95
  // the descriptor is ordinary Fabric C++, and an app that never renders
91
96
  // one pays a registry entry. See core/ExpoImageComponent.h.
@@ -51,6 +51,13 @@
51
51
  #ifdef BASALT_HAS_SKIA
52
52
  #include "AppKitSkiaModule.h"
53
53
  #endif
54
+ #if BASALT_HAS_SKIA_GRAPHITE
55
+ // The 3.x module, from basalt-skia. Registered here rather than through
56
+ // BASALT_PACKAGE_TURBO_MODULES because that property has core generate the
57
+ // call, and core is shared with hosts that cannot link Apple's Skia -- see
58
+ // that package's CMakeLists. The same arrangement the 2.x module above has.
59
+ #include "BasaltSkiaModule.h"
60
+ #endif
54
61
  #include "TestSettle.h"
55
62
  #import "AppKitRunLoopObserver.h"
56
63
  #import "AppKitFocus.h"
@@ -428,13 +435,24 @@ facebook::react::TurboModuleProviders makeTurboModuleProviders(
428
435
  return std::make_shared<basalt::DesktopGestureHandlerModule>(jsInvoker);
429
436
  }
430
437
  #ifdef BASALT_HAS_SKIA
431
- // @shopify/react-native-skia, when the build was pointed at an app that
432
- // has it. Its `install` is what puts Skia's whole JavaScript API on the
433
- // global object; see appkit/AppKitSkiaModule.h.
438
+ // React Native Skia's 2.x line, when the build was pointed at an app
439
+ // that has it. Its `install` is what puts Skia's whole JavaScript API
440
+ // on the global object; see appkit/AppKitSkiaModule.h.
434
441
  if (name == basalt::AppKitSkiaModule::kModuleName) {
435
442
  return std::make_shared<basalt::AppKitSkiaModule>(jsInvoker);
436
443
  }
437
444
  #endif
445
+ #if BASALT_HAS_SKIA_GRAPHITE
446
+ // And 3.x, which is Graphite over Dawn and a different module for the
447
+ // same name. Never both: cmake/Skia.cmake refuses a 3.x install by
448
+ // version, so BASALT_HAS_SKIA is defined in exactly the builds this is
449
+ // not.
450
+ if (name == basalt::BasaltSkiaModule::kModuleName) {
451
+ if (auto module = basalt::makeSkiaTurboModule(name, jsInvoker)) {
452
+ return module;
453
+ }
454
+ }
455
+ #endif
438
456
  #ifdef BASALT_HAS_WORKLETS
439
457
  // react-native-worklets, when the build was pointed at one. Reanimated
440
458
  // is built on it; see core/WorkletsModule.h.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "basalt-appkit",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "The macOS view layer for basalt-core: an AppKit view layer, a Fabric mounting manager, and a host. Everything behind them is in basalt-core.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -22,6 +22,6 @@
22
22
  "react-native": "*"
23
23
  },
24
24
  "dependencies": {
25
- "basalt-core": "0.1.0"
25
+ "basalt-core": "0.2.1"
26
26
  }
27
27
  }