Skip to content

Commit

Permalink
Fix bug when blur command received on node without XamlRoot (#12051)
Browse files Browse the repository at this point in the history
## Description

### Type of Change
_Erase all that don't apply._
- Bug fix (non-breaking change which fixes an issue)

### Why
We are seeing crashes on quit when the blur command is called roughly around the same time that the React instance is being shut down. It's likely because the result of tryGetXamlRoot is null.

### What
This change falls back on the GetFocusedElement() overload without any parameters if the XamlRoot is null, as supplying a null parameter will result in a NPE.

## Testing
It's a tricky race condition to repro, but I did validate that passing a null XamlRoot value to `FocusManager::GetFocusedElement(XamlRoot)` will throw an exception.

## Changelog
Should this change be included in the release notes: _yes_

Fix for NPE when blur command is received while React instance is shutting down.
  • Loading branch information
rozele committed Aug 29, 2023
1 parent 8cc5e9d commit 97a386c
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Fix bug when blur command received on node without XamlRoot",
"packageName": "react-native-windows",
"email": "erozell@outlook.com",
"dependentChangeType": "patch"
}
4 changes: 3 additions & 1 deletion vnext/Microsoft.ReactNative/Modules/NativeUIManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1171,7 +1171,9 @@ void NativeUIManager::blur(int64_t reactTag) {
if (auto shadowNode = static_cast<ShadowNodeBase *>(m_host->FindShadowNodeForTag(reactTag))) {
// Only blur if current UI is focused to avoid problem described in PR #2687
const auto xamlRoot = tryGetXamlRoot(shadowNode->m_rootTag);
if (shadowNode->GetView() == xaml::Input::FocusManager::GetFocusedElement(xamlRoot)) {
const auto focusedElement = xamlRoot ? xaml::Input::FocusManager::GetFocusedElement(xamlRoot)
: xaml::Input::FocusManager::GetFocusedElement();
if (shadowNode->GetView() == focusedElement) {
if (auto reactControl = GetParentXamlReactControl(reactTag).get()) {
reactControl.as<winrt::Microsoft::ReactNative::implementation::ReactRootView>()->blur(shadowNode->GetView());
} else {
Expand Down

0 comments on commit 97a386c

Please sign in to comment.