basalt-win32 0.2.1 → 0.2.3
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/native/CMakeLists.txt +56 -9
- package/native/tests/test_win32_accessibility.cpp +77 -0
- package/native/tests/test_win32_focus.cpp +26 -0
- package/native/tests/test_win32_input.cpp +82 -0
- package/native/tests/test_win32_peer_clip.cpp +266 -0
- package/native/tests/test_win32_run_loop.cpp +122 -0
- package/native/tests/test_win32_textinput.cpp +199 -0
- package/native/tests/test_win32_ui_timer.cpp +195 -0
- package/native/win32/PlatformServicesWin32.cpp +16 -0
- package/native/win32/RnWin32Accessible.cpp +27 -0
- package/native/win32/RnWin32Accessible.h +5 -0
- package/native/win32/RnWin32View.h +18 -0
- package/native/win32/Win32AnimationChoreographer.cpp +15 -32
- package/native/win32/Win32AnimationChoreographer.h +9 -6
- package/native/win32/Win32AppWindow.h +36 -0
- package/native/win32/Win32Cursors.cpp +13 -17
- package/native/win32/Win32DropTarget.cpp +4 -1
- package/native/win32/Win32MenuBar.cpp +3 -1
- package/native/win32/Win32MountingManager.cpp +82 -7
- package/native/win32/Win32MountingManager.h +5 -0
- package/native/win32/Win32PeerClip.cpp +153 -0
- package/native/win32/Win32PeerClip.h +92 -0
- package/native/win32/Win32RunLoopObserver.cpp +39 -9
- package/native/win32/Win32RunLoopObserver.h +41 -2
- package/native/win32/Win32ScrollView.cpp +13 -32
- package/native/win32/Win32ScrollView.h +5 -6
- package/native/win32/Win32SkiaPeer.h +26 -4
- package/native/win32/Win32TextInput.cpp +139 -48
- package/native/win32/Win32TextInput.h +28 -8
- package/native/win32/Win32UiThread.h +11 -0
- package/native/win32/Win32UiTimer.cpp +139 -0
- package/native/win32/Win32UiTimer.h +65 -0
- package/native/win32/Win32WindowControl.cpp +38 -15
- package/native/win32/Win32WindowModule.cpp +8 -13
- package/native/win32/main_win32.cpp +123 -96
- package/package.json +2 -2
|
@@ -55,8 +55,17 @@
|
|
|
55
55
|
#ifdef BASALT_HAS_SKIA
|
|
56
56
|
#include "Win32SkiaModule.h"
|
|
57
57
|
#endif
|
|
58
|
+
#if BASALT_HAS_SKIA_GRAPHITE
|
|
59
|
+
// The 3.x module, from basalt-skia. Registered here rather than through
|
|
60
|
+
// BASALT_PACKAGE_TURBO_MODULES because that property has core generate the
|
|
61
|
+
// call, and core is shared with hosts that cannot link this Skia -- see that
|
|
62
|
+
// package's CMakeLists. The same arrangement the 2.x module above has, and
|
|
63
|
+
// the same one main_appkit.mm makes.
|
|
64
|
+
#include "BasaltSkiaModule.h"
|
|
65
|
+
#endif
|
|
58
66
|
#include "Win32Packaging.h"
|
|
59
67
|
#include "PointerButtons.h"
|
|
68
|
+
#include "Win32AppWindow.h"
|
|
60
69
|
#include "WindowControl.h"
|
|
61
70
|
#include "SystemLocale.h"
|
|
62
71
|
#include "WindowHost.h"
|
|
@@ -70,6 +79,7 @@
|
|
|
70
79
|
#include "TextSelection.h"
|
|
71
80
|
#include "Win32TouchDispatcher.h"
|
|
72
81
|
#include "Win32UiThread.h"
|
|
82
|
+
#include "Win32UiTimer.h"
|
|
73
83
|
#include "DragAndDrop.h"
|
|
74
84
|
#include "Win32DropTarget.h"
|
|
75
85
|
#include "Win32TitleBar.h"
|
|
@@ -162,16 +172,6 @@ constexpr int kInitialHeight = 700;
|
|
|
162
172
|
// See e2e/demo.js. Only used when no module name is given.
|
|
163
173
|
constexpr const char *kRenderFunctionName = "basaltRender";
|
|
164
174
|
|
|
165
|
-
constexpr UINT_PTR kSecondTreeTimer = 100;
|
|
166
|
-
|
|
167
|
-
// BASALT_QUIT_AFTER_MS's timer. A constant rather than the literal 101 it used
|
|
168
|
-
// to be written as at its one call site: the spinner timer below was given 101
|
|
169
|
-
// too, and `SetTimer` with an id that is already in use *replaces* the timer
|
|
170
|
-
// rather than failing. An app with an <ActivityIndicator> in it therefore
|
|
171
|
-
// silently cancelled its own shutdown, and the only symptom was a host that
|
|
172
|
-
// never exited.
|
|
173
|
-
constexpr UINT_PTR kQuitAfterTimer = 101;
|
|
174
|
-
|
|
175
175
|
// One window, and the surface in it.
|
|
176
176
|
//
|
|
177
177
|
// A window is a surface: a surface is what has a size, a layout context and a
|
|
@@ -393,12 +393,16 @@ void requestRepaint() {
|
|
|
393
393
|
// Win32AnimationChoreographer.h gives about its own timer: a timer that runs
|
|
394
394
|
// whether or not anything is animating wakes the process sixty times a second
|
|
395
395
|
// forever, which matters more on a laptop than the frame interval does.
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
//
|
|
399
|
-
//
|
|
400
|
-
|
|
401
|
-
|
|
396
|
+
//
|
|
397
|
+
// Not `SetTimer`, and this is the timer that proves why: the one thing it
|
|
398
|
+
// exists to do is repaint, and a `WM_TIMER` is the message Windows withholds
|
|
399
|
+
// while there is painting to do. A spinner that stops the moment the window
|
|
400
|
+
// gets busy is the exact failure. See win32/Win32UiTimer.h.
|
|
401
|
+
basalt::UiTimerId gAnimationTimer = 0;
|
|
402
|
+
|
|
403
|
+
// Defined below, and named here because the timer that calls it is started
|
|
404
|
+
// above it.
|
|
405
|
+
void tickAnimations(HWND hwnd);
|
|
402
406
|
// When the last tick ran, so a frame delay is measured rather than assumed.
|
|
403
407
|
// A GIF's delays are in hundredths of a second and the timer is 16ms, so
|
|
404
408
|
// counting ticks would quantise every delay to a multiple of the tick and a
|
|
@@ -413,15 +417,16 @@ void updateAnimationTimer() {
|
|
|
413
417
|
gHost.main().root->hasAnimatedImage() ||
|
|
414
418
|
(gHost.logBoxRoot != nullptr &&
|
|
415
419
|
(gHost.logBoxRoot->hasAnimatingSpinner() || gHost.logBoxRoot->hasAnimatedImage()));
|
|
416
|
-
if (wanted ==
|
|
420
|
+
if (wanted == (gAnimationTimer != 0)) {
|
|
417
421
|
return;
|
|
418
422
|
}
|
|
419
|
-
gAnimationTimerRunning = wanted;
|
|
420
423
|
if (wanted) {
|
|
421
424
|
gLastAnimationTick = std::chrono::steady_clock::now();
|
|
422
|
-
|
|
425
|
+
HWND window = gHost.main().window;
|
|
426
|
+
gAnimationTimer = basalt::scheduleUiTimer(16, true, [window] { tickAnimations(window); });
|
|
423
427
|
} else {
|
|
424
|
-
|
|
428
|
+
basalt::cancelUiTimer(gAnimationTimer);
|
|
429
|
+
gAnimationTimer = 0;
|
|
425
430
|
}
|
|
426
431
|
}
|
|
427
432
|
|
|
@@ -566,6 +571,22 @@ facebook::react::TurboModuleProviders makeTurboModuleProviders(
|
|
|
566
571
|
if (name == basalt::Win32SkiaModule::kModuleName) {
|
|
567
572
|
return std::make_shared<basalt::Win32SkiaModule>(jsInvoker);
|
|
568
573
|
}
|
|
574
|
+
#endif
|
|
575
|
+
#if BASALT_HAS_SKIA_GRAPHITE
|
|
576
|
+
// And 3.x, which is Graphite over Dawn and a different module under
|
|
577
|
+
// the same name. Never both: cmake/Skia.cmake refuses a 3.x install by
|
|
578
|
+
// version, so BASALT_HAS_SKIA is defined in exactly the builds this is
|
|
579
|
+
// not.
|
|
580
|
+
//
|
|
581
|
+
// Without this the canvas is built, linked and unreachable: the view
|
|
582
|
+
// mounts, basalt-skia's C++ is all in the binary, and the app still
|
|
583
|
+
// ends at getEnforcing('RNSkiaModule') on its first Skia import --
|
|
584
|
+
// which is where kino's first Windows run stopped.
|
|
585
|
+
if (name == basalt::BasaltSkiaModule::kModuleName) {
|
|
586
|
+
if (auto module = basalt::makeSkiaTurboModule(name, jsInvoker)) {
|
|
587
|
+
return module;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
569
590
|
#endif
|
|
570
591
|
if (name == basalt::DesktopBlobModule::kModuleName) {
|
|
571
592
|
return std::make_shared<basalt::DesktopBlobModule>(jsInvoker);
|
|
@@ -898,25 +919,18 @@ struct ScriptedInput {
|
|
|
898
919
|
// Fired from timers keyed by index, so the vector has to outlive the loop.
|
|
899
920
|
std::vector<ScriptedInput> gScriptedInput;
|
|
900
921
|
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
// Every
|
|
922
|
+
// There is no table of timer ids here any more, and that is the point.
|
|
923
|
+
//
|
|
924
|
+
// Every one of this host's waits used to be a `SetTimer` id written by hand,
|
|
925
|
+
// and `SetTimer` with an id already in use *replaces* the timer rather than
|
|
926
|
+
// failing -- so a collision was silent and showed up as whatever the replaced
|
|
927
|
+
// timer had been for. It happened: the spinner's repaint timer was given the
|
|
928
|
+
// same id as BASALT_QUIT_AFTER_MS's, and an app with an <ActivityIndicator>
|
|
929
|
+
// in it cancelled its own shutdown and hung. Two static_asserts guarded
|
|
930
|
+
// against the next one.
|
|
904
931
|
//
|
|
905
|
-
//
|
|
906
|
-
//
|
|
907
|
-
// replaced was for. That happened: the spinner's repaint timer was given the
|
|
908
|
-
// same id as BASALT_QUIT_AFTER_MS's, and an app with an <ActivityIndicator> in
|
|
909
|
-
// it cancelled its own shutdown and hung. A static_assert cannot check the
|
|
910
|
-
// scripted range against the rest, so the base is held above everything else.
|
|
911
|
-
static_assert(kSecondTreeTimer != kQuitAfterTimer && kSecondTreeTimer != kAnimationTimer &&
|
|
912
|
-
kSecondTreeTimer != kQuitFileTimer && kQuitAfterTimer != kAnimationTimer &&
|
|
913
|
-
kQuitAfterTimer != kQuitFileTimer && kAnimationTimer != kQuitFileTimer,
|
|
914
|
-
"two timers share an id, and SetTimer would silently replace one with the other");
|
|
915
|
-
static_assert(kScriptedInputTimerBase > kSecondTreeTimer &&
|
|
916
|
-
kScriptedInputTimerBase > kQuitAfterTimer &&
|
|
917
|
-
kScriptedInputTimerBase > kAnimationTimer &&
|
|
918
|
-
kScriptedInputTimerBase > kQuitFileTimer,
|
|
919
|
-
"the scripted-input ids count up from the base and must start above the rest");
|
|
932
|
+
// win32/Win32UiTimer.h hands out its own ids from a counter, so there is
|
|
933
|
+
// nothing left to collide and nothing left to assert about.
|
|
920
934
|
|
|
921
935
|
// The numbers in "10,20,30" -- however many there are, which is what lets one
|
|
922
936
|
// parser read both a tap's pair and a drag's four.
|
|
@@ -938,9 +952,10 @@ std::vector<double> parseNumbers(const std::string &spec) {
|
|
|
938
952
|
return numbers;
|
|
939
953
|
}
|
|
940
954
|
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
955
|
+
// One scheduled action, on the UI thread. An index and a window rather than a
|
|
956
|
+
// TIMERPROC's four arguments: the timer behind this carries a closure, so
|
|
957
|
+
// there is nothing to recover from an id.
|
|
958
|
+
void fireScriptedInput(HWND hwnd, size_t index) {
|
|
944
959
|
if (index >= gScriptedInput.size()) {
|
|
945
960
|
return;
|
|
946
961
|
}
|
|
@@ -1159,10 +1174,13 @@ void CALLBACK fireScriptedInput(HWND hwnd, UINT, UINT_PTR id, DWORD) {
|
|
|
1159
1174
|
// the last one, so a drag can be scheduled behind the taps.
|
|
1160
1175
|
UINT scheduleScriptedInput(const ScriptedInput &action, UINT delayMs) {
|
|
1161
1176
|
gScriptedInput.push_back(action);
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1177
|
+
const size_t index = gScriptedInput.size() - 1;
|
|
1178
|
+
HWND window = gHost.main().window;
|
|
1179
|
+
// Not `SetTimer`: scripted input exists to drive a *running* app, and the
|
|
1180
|
+
// apps worth driving are the ones that paint -- which is exactly when a
|
|
1181
|
+
// WM_TIMER never arrives. Every instrument in this file was silently
|
|
1182
|
+
// inoperative on an app with a `<Canvas>`. See win32/Win32UiTimer.h.
|
|
1183
|
+
basalt::scheduleUiTimer(delayMs, false, [window, index] { fireScriptedInput(window, index); });
|
|
1166
1184
|
return delayMs + 1000;
|
|
1167
1185
|
}
|
|
1168
1186
|
|
|
@@ -1440,7 +1458,12 @@ LRESULT CALLBACK hostProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
|
|
|
1440
1458
|
// it needs its own case: WM_SIZE would never arrive, and `center()` would
|
|
1441
1459
|
// look like it had done nothing.
|
|
1442
1460
|
case WM_MOVE:
|
|
1443
|
-
|
|
1461
|
+
// Which window moved. `self` is null for the messages CreateWindowEx
|
|
1462
|
+
// sends before the window is in the list, and a move among those is not
|
|
1463
|
+
// one an app can see.
|
|
1464
|
+
if (self != nullptr) {
|
|
1465
|
+
basalt::notifyWindowBoundsChanged(self->surfaceId);
|
|
1466
|
+
}
|
|
1444
1467
|
return 0;
|
|
1445
1468
|
|
|
1446
1469
|
// `AppState`: whether this application is the one in front. Windows sends
|
|
@@ -1488,8 +1511,8 @@ LRESULT CALLBACK hostProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
|
|
|
1488
1511
|
}
|
|
1489
1512
|
// The window moved or was resized, which `useWindow()` hands an app as live
|
|
1490
1513
|
// bounds. Here rather than in a watcher of its own: this is already the one
|
|
1491
|
-
// place that learns it.
|
|
1492
|
-
basalt::notifyWindowBoundsChanged();
|
|
1514
|
+
// place that learns it, and it already knows which window it was.
|
|
1515
|
+
basalt::notifyWindowBoundsChanged(self->surfaceId);
|
|
1493
1516
|
// The inspector covers the main window, so it resizes with it -- and
|
|
1494
1517
|
// only with it: an error is about the app rather than about a window.
|
|
1495
1518
|
if (gHost.logBoxRoot != nullptr && self->surfaceId == kSurfaceId) {
|
|
@@ -1804,17 +1827,9 @@ LRESULT CALLBACK hostProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
|
|
|
1804
1827
|
}
|
|
1805
1828
|
return 0;
|
|
1806
1829
|
|
|
1807
|
-
case
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
return 0;
|
|
1811
|
-
}
|
|
1812
|
-
if (wparam == kSecondTreeTimer) {
|
|
1813
|
-
KillTimer(hwnd, kSecondTreeTimer);
|
|
1814
|
-
std::fprintf(stderr, "--- committing tree 2 from JS ---\n");
|
|
1815
|
-
callRenderFunction(2);
|
|
1816
|
-
}
|
|
1817
|
-
return 0;
|
|
1830
|
+
// No WM_TIMER case. Nothing this host schedules arrives that way any
|
|
1831
|
+
// more -- see win32/Win32UiTimer.h for why it could not be relied on --
|
|
1832
|
+
// and swallowing the message would hide a timer somebody else set.
|
|
1818
1833
|
|
|
1819
1834
|
case WM_PAINT: {
|
|
1820
1835
|
PAINTSTRUCT paint{};
|
|
@@ -2132,11 +2147,14 @@ facebook::react::SurfaceId openHostWindow(const NewWindowOptions &options) {
|
|
|
2132
2147
|
|
|
2133
2148
|
gHost.reactHost->startSurface(surfaceId,
|
|
2134
2149
|
options.component,
|
|
2135
|
-
options
|
|
2150
|
+
windowRootProps(options, surfaceId),
|
|
2136
2151
|
constraintsFor(width, height),
|
|
2137
2152
|
layoutContextFor(gHost.scaleFactor));
|
|
2138
2153
|
ShowWindow(made->window, SW_SHOW);
|
|
2139
2154
|
UpdateWindow(made->window);
|
|
2155
|
+
// Prime this window's bounds the way the main window's are primed at
|
|
2156
|
+
// startup; see the call beside that one.
|
|
2157
|
+
basalt::notifyWindowBoundsChanged(surfaceId);
|
|
2140
2158
|
std::fprintf(stderr,
|
|
2141
2159
|
"opened window %d for module %s\n",
|
|
2142
2160
|
static_cast<int>(surfaceId),
|
|
@@ -2360,10 +2378,18 @@ int main(int argc, char **argv) {
|
|
|
2360
2378
|
// being visible.
|
|
2361
2379
|
gHost.mountingManager->setOnDidMount(syncPeersAndRepaint);
|
|
2362
2380
|
|
|
2381
|
+
// How the window module finds a window by id, and which one a call that
|
|
2382
|
+
// names none means. See Win32AppWindow.h.
|
|
2383
|
+
basalt::setWin32AppWindowLookup([](facebook::react::SurfaceId surfaceId) -> HWND {
|
|
2384
|
+
HostWindow *found = gHost.windowFor(surfaceId);
|
|
2385
|
+
return found == nullptr ? nullptr : found->window;
|
|
2386
|
+
});
|
|
2387
|
+
basalt::setAppWindowId(kSurfaceId);
|
|
2388
|
+
|
|
2363
2389
|
// Prime the bounds cache, which `getBounds()` answers from: without this an
|
|
2364
2390
|
// app's first render sees a window of no size, and only a later resize
|
|
2365
2391
|
// corrects it. See core/WindowBoundsCache.cpp.
|
|
2366
|
-
basalt::notifyWindowBoundsChanged();
|
|
2392
|
+
basalt::notifyWindowBoundsChanged(kSurfaceId);
|
|
2367
2393
|
|
|
2368
2394
|
// And the display list, for the same reason and off the same seam: an app
|
|
2369
2395
|
// asking which screens exist before anything has been plugged or unplugged
|
|
@@ -2529,7 +2555,10 @@ int main(int argc, char **argv) {
|
|
|
2529
2555
|
if (gHost.moduleName.empty()) {
|
|
2530
2556
|
std::fprintf(stderr, "--- committing tree 1 from JS ---\n");
|
|
2531
2557
|
callRenderFunction(1);
|
|
2532
|
-
|
|
2558
|
+
basalt::scheduleUiTimer(2000, false, [] {
|
|
2559
|
+
std::fprintf(stderr, "--- committing tree 2 from JS ---\n");
|
|
2560
|
+
callRenderFunction(2);
|
|
2561
|
+
});
|
|
2533
2562
|
}
|
|
2534
2563
|
|
|
2535
2564
|
UINT scriptedDelayMs = 1500;
|
|
@@ -2643,21 +2672,20 @@ int main(int argc, char **argv) {
|
|
|
2643
2672
|
// clicking anything. The same escape hatch both other hosts have.
|
|
2644
2673
|
if (const char *quitAfter = std::getenv("BASALT_QUIT_AFTER_MS")) {
|
|
2645
2674
|
const UINT delay = static_cast<UINT>(std::strtoul(quitAfter, nullptr, 10));
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
});
|
|
2675
|
+
HWND window = gHost.main().window;
|
|
2676
|
+
basalt::scheduleUiTimer(delay, false, [window] {
|
|
2677
|
+
// The same line the other two hosts log, so a person reading three
|
|
2678
|
+
// transcripts side by side sees the same shutdown in each. This
|
|
2679
|
+
// host was silent about it, which is how a scenario came to assert
|
|
2680
|
+
// on a string only two of them print.
|
|
2681
|
+
std::fprintf(stderr, "BASALT_QUIT_AFTER_MS elapsed; quitting\n");
|
|
2682
|
+
// What WM_CLOSE does, without going through WM_CLOSE. This is the
|
|
2683
|
+
// harness ending the run, not a person closing a window, and an app
|
|
2684
|
+
// that intercepts its own close would otherwise refuse it -- a test
|
|
2685
|
+
// that asks "does refusing work" by never exiting.
|
|
2686
|
+
captureBeforeTeardown();
|
|
2687
|
+
DestroyWindow(window);
|
|
2688
|
+
});
|
|
2661
2689
|
}
|
|
2662
2690
|
|
|
2663
2691
|
// BASALT_TEST_QUIT_FILE: the same shutdown, at a moment the harness picks
|
|
@@ -2671,26 +2699,25 @@ int main(int argc, char **argv) {
|
|
|
2671
2699
|
//
|
|
2672
2700
|
// Two instruments, one timer, because they want the same thing at different
|
|
2673
2701
|
// moments: the quit file is the harness deciding, BASALT_QUIT_WHEN_SETTLED is
|
|
2674
|
-
// the app noticing it has nothing left to do.
|
|
2675
|
-
// SetTimer replaces silently on a collision. See core/TestSettle.h.
|
|
2702
|
+
// the app noticing it has nothing left to do. See core/TestSettle.h.
|
|
2676
2703
|
if (basalt::testQuitFilePath().has_value() || basalt::quitWhenSettledMs().has_value()) {
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2704
|
+
HWND window = gHost.main().window;
|
|
2705
|
+
static basalt::UiTimerId poll = 0;
|
|
2706
|
+
poll = basalt::scheduleUiTimer(basalt::kTestQuitFilePollMs, true, [window] {
|
|
2707
|
+
const char *why = nullptr;
|
|
2708
|
+
if (basalt::testQuitFileAppeared()) {
|
|
2709
|
+
why = basalt::kTestQuitFileMessage;
|
|
2710
|
+
} else if (basalt::hasSettled()) {
|
|
2711
|
+
why = basalt::kQuitWhenSettledMessage;
|
|
2712
|
+
} else {
|
|
2713
|
+
return;
|
|
2714
|
+
}
|
|
2715
|
+
basalt::cancelUiTimer(poll);
|
|
2716
|
+
poll = 0;
|
|
2717
|
+
std::fprintf(stderr, "%s\n", why);
|
|
2718
|
+
captureBeforeTeardown();
|
|
2719
|
+
DestroyWindow(window);
|
|
2720
|
+
});
|
|
2694
2721
|
}
|
|
2695
2722
|
|
|
2696
2723
|
// Not a plain GetMessage loop: the event beat has to be induced each time the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "basalt-win32",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "The Windows view layer for basalt-core: a Win32 and Direct2D 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.2.
|
|
25
|
+
"basalt-core": "0.2.3"
|
|
26
26
|
}
|
|
27
27
|
}
|