Skip to content
Closed
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": "Remove usage of JSDispatcher in various built-in modules",
"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 @@ -22,12 +22,11 @@ void AccessibilityInfo::Initialize(winrt::Microsoft::ReactNative::ReactContext c
}

void AccessibilityInfo::isReduceMotionEnabled(std::function<void(bool)> const &onSuccess) noexcept {
auto jsDispatcher = m_context.JSDispatcher();
m_context.UIDispatcher().Post([weakThis = weak_from_this(), jsDispatcher, onSuccess] {
m_context.UIDispatcher().Post([weakThis = weak_from_this(), onSuccess] {
if (auto strongThis = weakThis.lock()) {
winrt::Windows::UI::ViewManagement::UISettings uiSettings;
auto animationsEnabled = uiSettings.AnimationsEnabled();
jsDispatcher.Post([animationsEnabled, onSuccess] { onSuccess(!animationsEnabled); });
onSuccess(!animationsEnabled);
}
});
}
Expand Down
19 changes: 7 additions & 12 deletions vnext/Microsoft.ReactNative/Modules/AlertModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ void Alert::ProcessPendingAlertRequestsXaml() noexcept {
const auto &pendingAlert = pendingAlerts.front();
const auto &args = pendingAlert.args;
const auto &result = pendingAlert.result;
auto jsDispatcher = m_context.JSDispatcher();

xaml::Controls::ContentDialog dialog{};
xaml::Controls::TextBlock titleTextBlock;
Expand Down Expand Up @@ -110,7 +109,7 @@ void Alert::ProcessPendingAlertRequestsXaml() noexcept {
} else if (IsXamlIsland()) {
// We cannot show a ContentDialog in a XAML Island unless it is assigned a
// XamlRoot instance. In such cases, we just treat the alert as dismissed.
jsDispatcher.Post([result, this] { result(m_constants.dismissed, m_constants.buttonNeutral); });
result(m_constants.dismissed, m_constants.buttonNeutral);
pendingAlerts.pop();
ProcessPendingAlertRequests();
return;
Expand Down Expand Up @@ -138,19 +137,17 @@ void Alert::ProcessPendingAlertRequestsXaml() noexcept {
const auto hasCloseButton = dialog.CloseButtonText().size() > 0;
auto asyncOp = dialog.ShowAsync();
asyncOp.Completed(
[hasCloseButton, jsDispatcher, result, this](
[hasCloseButton, result, this](
const winrt::IAsyncOperation<xaml::Controls::ContentDialogResult> &asyncOp, winrt::AsyncStatus status) {
switch (asyncOp.GetResults()) {
case xaml::Controls::ContentDialogResult::Primary:
jsDispatcher.Post([result, this] { result(m_constants.buttonClicked, m_constants.buttonPositive); });
result(m_constants.buttonClicked, m_constants.buttonPositive);
break;
case xaml::Controls::ContentDialogResult::Secondary:
jsDispatcher.Post([result, this] { result(m_constants.buttonClicked, m_constants.buttonNegative); });
result(m_constants.buttonClicked, m_constants.buttonNegative);
break;
case xaml::Controls::ContentDialogResult::None:
jsDispatcher.Post([hasCloseButton, result, this] {
result(hasCloseButton ? m_constants.buttonClicked : m_constants.dismissed, m_constants.buttonNeutral);
});
result(hasCloseButton ? m_constants.buttonClicked : m_constants.dismissed, m_constants.buttonNeutral);
break;
default:
break;
Expand All @@ -164,7 +161,6 @@ void Alert::ProcessPendingAlertRequestsMessageDialog() noexcept {
const auto &pendingAlert = pendingAlerts.front();
const auto &args = pendingAlert.args;
const auto &result = pendingAlert.result;
auto jsDispatcher = m_context.JSDispatcher();

auto cancelable = args.cancelable.value_or(true);
auto messageDialog = winrt::Windows::UI::Popups::MessageDialog(
Expand Down Expand Up @@ -208,11 +204,10 @@ void Alert::ProcessPendingAlertRequestsMessageDialog() noexcept {

auto asyncOp = messageDialog.ShowAsync();
asyncOp.Completed(
[jsDispatcher, result, this](
[result, this](
const winrt::IAsyncOperation<winrt::Windows::UI::Popups::IUICommand> &asyncOp, winrt::AsyncStatus status) {
auto uicommand = asyncOp.GetResults();
jsDispatcher.Post(
[id = uicommand.Id(), result, this] { result(m_constants.buttonClicked, winrt::unbox_value<int>(id)); });
result(m_constants.buttonClicked, winrt::unbox_value<int>(uicommand.Id()));
pendingAlerts.pop();
ProcessPendingAlertRequests();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,7 @@ void NativeAnimatedModule::getValue(double tag, std::function<void(double)> cons
callback = std::move(saveValueCallback)]() {
if (auto pThis = wkThis.lock()) {
pThis->m_nodesManager->GetValue(
tag, [context = pThis->m_context, callback = std::move(callback)](double value) {
context.JSDispatcher().Post([callback = std::move(callback), value]() { callback(value); });
});
tag, [context = pThis->m_context, callback = std::move(callback)](double value) { callback(value); });
}
});
}
Expand Down Expand Up @@ -131,11 +129,9 @@ void NativeAnimatedModule::startAnimatingNode(
nodeTag,
animationConfig.AsObject(),
[context = pThis->m_context, endCallback = std::move(endCallback)](bool finished) {
context.JSDispatcher().Post([finished, endCallback = std::move(endCallback)]() {
ReactNativeSpecs::AnimatedModuleSpec_EndResult result;
result.finished = finished;
endCallback(std::move(result));
});
ReactNativeSpecs::AnimatedModuleSpec_EndResult result;
result.finished = finished;
endCallback(std::move(result));
},
pThis->m_nodesManager);
}
Expand Down
4 changes: 2 additions & 2 deletions vnext/Microsoft.ReactNative/Modules/AppStateModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,13 @@ void AppState::SetDeactivated(bool deactivated) noexcept {
if (winrt::Microsoft::ReactNative::implementation::QuirkSettings::GetMapWindowDeactivatedToAppStateInactive(
m_context.Properties())) {
m_deactivated = deactivated;
m_context.JSDispatcher().Post([this]() { AppStateDidChange({GetAppState()}); });
AppStateDidChange({GetAppState()});
}
}

void AppState::SetEnteredBackground(bool enteredBackground) noexcept {
m_enteredBackground = enteredBackground;
m_context.JSDispatcher().Post([this]() { AppStateDidChange({GetAppState()}); });
AppStateDidChange({GetAppState()});
}

std::string AppState::GetAppState() noexcept {
Expand Down
12 changes: 5 additions & 7 deletions vnext/Microsoft.ReactNative/Modules/ClipboardModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,25 @@ void Clipboard::Initialize(winrt::Microsoft::ReactNative::ReactContext const &re
}

void Clipboard::getString(React::ReactPromise<std::string> result) noexcept {
auto jsDispatcher = m_reactContext.JSDispatcher();
m_reactContext.UIDispatcher().Post([jsDispatcher, result] {
m_reactContext.UIDispatcher().Post([result] {
auto data = DataTransfer::Clipboard::GetContent();
auto asyncOp = data.GetTextAsync();
// unfortunately, lambda captures doesn't work well with winrt::fire_and_forget and co_await here
// call asyncOp.Completed explicitly
asyncOp.Completed([jsDispatcher, result](const IAsyncOperation<winrt::hstring> &asyncOp, AsyncStatus status) {
asyncOp.Completed([result](const IAsyncOperation<winrt::hstring> &asyncOp, AsyncStatus status) {
switch (status) {
case AsyncStatus::Completed: {
auto text = std::wstring(asyncOp.GetResults());
jsDispatcher.Post(
[result, text] { result.Resolve(std::string{Microsoft::Common::Unicode::Utf16ToUtf8(text)}); });
result.Resolve(std::string{Microsoft::Common::Unicode::Utf16ToUtf8(text)});
break;
}
case AsyncStatus::Canceled: {
jsDispatcher.Post([result] { result.Reject(React::ReactError()); });
result.Reject(React::ReactError());
break;
}
case AsyncStatus::Error: {
auto message = std::wstring(winrt::hresult_error(asyncOp.ErrorCode()).message());
jsDispatcher.Post([result, message] { result.Reject(message.c_str()); });
result.Reject(message.c_str());
break;
}
case AsyncStatus::Started: {
Expand Down
21 changes: 6 additions & 15 deletions vnext/Microsoft.ReactNative/Modules/ImageViewManagerModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,10 @@ void ImageLoader::getSize(std::string uri, React::ReactPromise<std::vector<doubl
context.Properties().Handle(),
std::move(uri),
{},
[result, context](double width, double height) noexcept {
context.JSDispatcher().Post([result = std::move(result), width, height]() noexcept {
result.Resolve(std::vector<double>{width, height});
});
[result](double width, double height) noexcept {
result.Resolve(std::vector<double>{width, height});
},
[result, context]() noexcept {
context.JSDispatcher().Post([result = std::move(result)]() noexcept { result.Reject("Failed"); });
}
[result]() noexcept { result.Reject("Failed"); }
#ifdef USE_FABRIC
,
IsFabricEnabled(context.Properties().Handle())
Expand All @@ -138,15 +134,10 @@ void ImageLoader::getSizeWithHeaders(
context.Properties().Handle(),
std::move(uri),
std::move(headers),
[result, context](double width, double height) noexcept {
context.JSDispatcher().Post([result = std::move(result), width, height]() noexcept {
result.Resolve(
Microsoft::ReactNativeSpecs::ImageLoaderIOSSpec_getSizeWithHeaders_returnType{width, height});
});
[result](double width, double height) noexcept {
result.Resolve(Microsoft::ReactNativeSpecs::ImageLoaderIOSSpec_getSizeWithHeaders_returnType{width, height});
},
[result, context]() noexcept {
context.JSDispatcher().Post([result = std::move(result)]() noexcept { result.Reject("Failed"); });
}
[result]() noexcept { result.Reject("Failed"); }
#ifdef USE_FABRIC
,
IsFabricEnabled(context.Properties().Handle())
Expand Down
37 changes: 13 additions & 24 deletions vnext/Microsoft.ReactNative/Modules/NativeUIManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -998,14 +998,14 @@ void NativeUIManager::measure(

auto feView = view.try_as<xaml::FrameworkElement>();
if (feView == nullptr) {
m_context.JSDispatcher().Post([callback = std::move(callback)]() { callback(0, 0, 0, 0, 0, 0); });
callback(0, 0, 0, 0, 0, 0);
return;
}

// Retrieve the XAML element for the root view containing this view
auto feRootView = static_cast<ShadowNodeBase &>(shadowRoot).GetView().try_as<xaml::FrameworkElement>();
if (feRootView == nullptr) {
m_context.JSDispatcher().Post([callback = std::move(callback)]() { callback(0, 0, 0, 0, 0, 0); });
callback(0, 0, 0, 0, 0, 0);
return;
}

Expand All @@ -1015,9 +1015,7 @@ void NativeUIManager::measure(
// this is exactly, but it is not used anyway.
// Either codify this non-use or determine if and how we can send the needed
// data.
m_context.JSDispatcher().Post([callback = std::move(callback), react = rectInParentCoords]() {
callback(0, 0, react.Width, react.Height, react.X, react.Y);
});
callback(0, 0, rectInParentCoords.Width, rectInParentCoords.Height, rectInParentCoords.X, rectInParentCoords.Y);
}

void NativeUIManager::measureInWindow(
Expand All @@ -1033,14 +1031,11 @@ void NativeUIManager::measureInWindow(
auto windowTransform = view.TransformToVisual(nullptr);
auto positionInWindow = windowTransform.TransformPoint({0, 0});

m_context.JSDispatcher().Post(
[callback = std::move(callback), pos = positionInWindow, w = view.ActualWidth(), h = view.ActualHeight()]() {
callback(pos.X, pos.Y, w, h);
});
callback(positionInWindow.X, positionInWindow.Y, view.ActualWidth(), view.ActualHeight());
return;
}

m_context.JSDispatcher().Post([callback = std::move(callback)]() { callback(0, 0, 0, 0); });
callback(0, 0, 0, 0);
}

void NativeUIManager::measureLayout(
Expand All @@ -1060,15 +1055,11 @@ void NativeUIManager::measureLayout(
const auto height = static_cast<float>(targetElement.ActualHeight());
const auto transformedBounds = ancestorTransform.TransformBounds(winrt::Rect(0, 0, width, height));

m_context.JSDispatcher().Post([callback = std::move(callback), rect = transformedBounds]() {
callback(rect.X, rect.Y, rect.Width, rect.Height);
});
callback(transformedBounds.X, transformedBounds.Y, transformedBounds.Width, transformedBounds.Height);
} catch (winrt::hresult_error const &e) {
m_context.JSDispatcher().Post([errorCallback = std::move(errorCallback), msg = e.message()]() {
auto writer = React::MakeJSValueTreeWriter();
writer.WriteString(msg);
errorCallback(React::TakeJSValue(writer));
});
auto writer = React::MakeJSValueTreeWriter();
writer.WriteString(e.message());
errorCallback(React::TakeJSValue(writer));
}
}

Expand All @@ -1082,7 +1073,7 @@ void NativeUIManager::findSubviewIn(

auto rootUIView = view.try_as<xaml::UIElement>();
if (rootUIView == nullptr) {
m_context.JSDispatcher().Post([callback = std::move(callback)]() { callback(0, 0, 0, 0, 0); });
callback(0, 0, 0, 0, 0);
return;
}

Expand Down Expand Up @@ -1111,14 +1102,12 @@ void NativeUIManager::findSubviewIn(
}

if (foundElement == nullptr) {
m_context.JSDispatcher().Post([callback = std::move(callback)]() { callback(0, 0, 0, 0, 0); });
callback(0, 0, 0, 0, 0);
return;
}

m_context.JSDispatcher().Post(
[callback = std::move(callback), foundTag, box = GetRectOfElementInParentCoords(foundElement, rootUIView)]() {
callback(static_cast<double>(foundTag), box.X, box.Y, box.Width, box.Height);
});
auto box = GetRectOfElementInParentCoords(foundElement, rootUIView);
callback(static_cast<double>(foundTag), box.X, box.Y, box.Width, box.Height);
}

void NativeUIManager::focus(int64_t reactTag) {
Expand Down
Loading