Skip to content

Commit 0f6bdf3

Browse files
authored
Adds option to allow ViewManagers to capture pointer (#8969)
* Adds option to allow ViewManagers to capture pointer Adds property to ReactPointerEventArgs to allow view managers to capture the pointer while still allowing RN to emit events to JS. XAML only allows capturing the pointer on PointerPressed, so this would allow, for example, a view manager that supports custom native drag behaviors that have a threshold for action (and when that threshold is not exceeded, the gesture is handled by RN). * Change files
1 parent b87abc8 commit 0f6bdf3

File tree

5 files changed

+32
-1
lines changed

5 files changed

+32
-1
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "prerelease",
3+
"comment": "applying package updates ***NO_CI***",
4+
"packageName": "react-native-windows",
5+
"email": "[email protected]",
6+
"dependentChangeType": "patch"
7+
}

vnext/Microsoft.ReactNative/ReactPointerEventArgs.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ void ReactPointerEventArgs::Target(winrt::IInspectable const &target) noexcept {
3939
m_target = target;
4040
}
4141

42+
bool ReactPointerEventArgs::AllowUncaptured() const noexcept {
43+
return m_allowUncaptured;
44+
}
45+
46+
void ReactPointerEventArgs::AllowUncaptured(bool allowUncaptured) noexcept {
47+
m_allowUncaptured = allowUncaptured;
48+
}
49+
4250
ReactPointerEventArgs::ReactPointerEventArgs(
4351
PointerEventKind kind,
4452
xaml::Input::PointerRoutedEventArgs const &args) noexcept

vnext/Microsoft.ReactNative/ReactPointerEventArgs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,17 @@ struct ReactPointerEventArgs : ReactPointerEventArgsT<ReactPointerEventArgs> {
1616
winrt::IInspectable Target() const noexcept;
1717
void Target(winrt::IInspectable const &target) noexcept;
1818

19+
bool AllowUncaptured() const noexcept;
20+
void AllowUncaptured(bool allowUncaptured) noexcept;
21+
1922
// Internal use
2023
ReactPointerEventArgs(PointerEventKind kind, xaml::Input::PointerRoutedEventArgs const &args) noexcept;
2124

2225
private:
2326
PointerEventKind m_kind;
2427
xaml::Input::PointerRoutedEventArgs const &m_args;
2528
winrt::IInspectable m_target{nullptr};
29+
bool m_allowUncaptured{false};
2630
};
2731

2832
} // namespace winrt::Microsoft::ReactNative::implementation

vnext/Microsoft.ReactNative/ReactPointerEventArgs.idl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,17 @@ namespace Microsoft.ReactNative {
6363
get;
6464
set;
6565
};
66+
DOC_STRING(
67+
"Gets or sets a flag that allows the ReactRootView to handle pointer "
68+
"events even when it does not capture the pointer. This is particularly "
69+
"useful for view managers that seek to capture the pointer to handle "
70+
"move events for a gesture (e.g., dragging), but conditionally may "
71+
"allow the ReactRootView to emit events (e.g., if the "
72+
"@PointerEventKind.End event is received before a drag threshold is hit."
73+
)
74+
Boolean AllowUncaptured {
75+
get;
76+
set;
77+
};
6678
}
6779
} // namespace Microsoft.ReactNative

vnext/Microsoft.ReactNative/Views/TouchEventHandler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ void TouchEventHandler::OnPointerPressed(
119119
return;
120120
}
121121

122-
if (m_xamlView.as<xaml::FrameworkElement>().CapturePointer(args.Pointer())) {
122+
if (reactArgs.AllowUncaptured() || m_xamlView.as<xaml::FrameworkElement>().CapturePointer(args.Pointer())) {
123123
assert(!tagsForBranch.empty());
124124
const auto tag = tagsForBranch.front();
125125

0 commit comments

Comments
 (0)