Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "[Fabric] LogBox should destroy its window on instance shutdown",
"packageName": "react-native-windows",
"email": "30809111+acoates-ms@users.noreply.github.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,6 @@ struct CompositionReactViewInstance
void UpdateRootView() noexcept;
void UninitRootView() noexcept;

private:
template <class TAction>
Mso::Future<void> PostInUIQueue(TAction &&action) noexcept;

private:
winrt::weak_ref<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland> m_weakRootControl;
IReactDispatcher m_uiDispatcher{nullptr};
Expand Down Expand Up @@ -102,29 +98,6 @@ void CompositionReactViewInstance::UninitRootView() noexcept {
}
}

//===========================================================================
// ReactViewInstance inline implementation
//===========================================================================

template <class TAction>
inline Mso::Future<void> CompositionReactViewInstance::PostInUIQueue(TAction &&action) noexcept {
// ReactViewInstance has shorter lifetime than ReactRootControl. Thus, we capture this WeakPtr.
auto promise = Mso::Promise<void>();

m_uiDispatcher.Post([promise, weakThis{get_weak()}, action{std::forward<TAction>(action)}]() mutable {
if (auto strongThis = weakThis.get()) {
if (auto rootControl = strongThis->m_weakRootControl.get()) {
action(rootControl);
promise.SetValue();
return;
}
}
promise.TryCancel();
});

return promise.AsFuture();
}

void ApplyConstraints(
const winrt::Microsoft::ReactNative::LayoutConstraints &layoutConstraintsIn,
facebook::react::LayoutConstraints &layoutConstraintsOut) noexcept {
Expand Down
9 changes: 9 additions & 0 deletions vnext/Microsoft.ReactNative/Modules/LogBoxModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@

namespace Microsoft::ReactNative {

LogBox::~LogBox() {
#ifdef USE_FABRIC
if (m_hwnd) {
m_context.UIDispatcher().Post([hwnd = m_hwnd]() { DestroyWindow(hwnd); });
m_hwnd = nullptr;
}
#endif
}

#ifdef USE_FABRIC
constexpr PCWSTR c_logBoxWindowClassName = L"MS_REACTNATIVE_LOGBOX";
constexpr auto CompHostProperty = L"CompHost";
Expand Down
2 changes: 2 additions & 0 deletions vnext/Microsoft.ReactNative/Modules/LogBoxModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ REACT_MODULE(LogBox)
struct LogBox : public std::enable_shared_from_this<LogBox> {
using ModuleSpec = ReactNativeSpecs::LogBoxSpec;

~LogBox();

REACT_INIT(Initialize)
void Initialize(winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept;

Expand Down
7 changes: 0 additions & 7 deletions vnext/Microsoft.ReactNative/ReactHost/MsoReactContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,13 +170,6 @@ ReactContext::ReactContext(
m_properties{winrt::make<WeakRefPropertyBag>(properties)},
m_notifications{notifications} {}

void ReactContext::Destroy() noexcept {
if (auto notificationService =
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNotificationService>(m_notifications)) {
notificationService->UnsubscribeAll();
}
}

winrt::Microsoft::ReactNative::IReactPropertyBag ReactContext::Properties() const noexcept {
return m_properties;
}
Expand Down
5 changes: 0 additions & 5 deletions vnext/Microsoft.ReactNative/ReactHost/MsoReactContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,6 @@ class ReactContext final : public Mso::UnknownObject<IReactContext> {
winrt::Microsoft::ReactNative::IReactPropertyBag const &properties,
winrt::Microsoft::ReactNative::IReactNotificationService const &notifications) noexcept;

// ReactContext may have longer lifespan than ReactInstance.
// The ReactInstance uses the Destroy method to enforce the ReactContext cleanup
// when the ReactInstance is destroyed.
void Destroy() noexcept;

public: // IReactContext
winrt::Microsoft::ReactNative::IReactPropertyBag Properties() const noexcept override;
winrt::Microsoft::ReactNative::IReactNotificationService Notifications() const noexcept override;
Expand Down