Skip to content

Commit

Permalink
Adds option to allow ViewManagers to capture pointer (#8969)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
rozele committed Nov 8, 2023
1 parent b87abc8 commit 0f6bdf3
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "applying package updates ***NO_CI***",
"packageName": "react-native-windows",
"email": "erozell@outlook.com",
"dependentChangeType": "patch"
}
8 changes: 8 additions & 0 deletions vnext/Microsoft.ReactNative/ReactPointerEventArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ void ReactPointerEventArgs::Target(winrt::IInspectable const &target) noexcept {
m_target = target;
}

bool ReactPointerEventArgs::AllowUncaptured() const noexcept {
return m_allowUncaptured;
}

void ReactPointerEventArgs::AllowUncaptured(bool allowUncaptured) noexcept {
m_allowUncaptured = allowUncaptured;
}

ReactPointerEventArgs::ReactPointerEventArgs(
PointerEventKind kind,
xaml::Input::PointerRoutedEventArgs const &args) noexcept
Expand Down
4 changes: 4 additions & 0 deletions vnext/Microsoft.ReactNative/ReactPointerEventArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@ struct ReactPointerEventArgs : ReactPointerEventArgsT<ReactPointerEventArgs> {
winrt::IInspectable Target() const noexcept;
void Target(winrt::IInspectable const &target) noexcept;

bool AllowUncaptured() const noexcept;
void AllowUncaptured(bool allowUncaptured) noexcept;

// Internal use
ReactPointerEventArgs(PointerEventKind kind, xaml::Input::PointerRoutedEventArgs const &args) noexcept;

private:
PointerEventKind m_kind;
xaml::Input::PointerRoutedEventArgs const &m_args;
winrt::IInspectable m_target{nullptr};
bool m_allowUncaptured{false};
};

} // namespace winrt::Microsoft::ReactNative::implementation
12 changes: 12 additions & 0 deletions vnext/Microsoft.ReactNative/ReactPointerEventArgs.idl
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,17 @@ namespace Microsoft.ReactNative {
get;
set;
};
DOC_STRING(
"Gets or sets a flag that allows the ReactRootView to handle pointer "
"events even when it does not capture the pointer. This is particularly "
"useful for view managers that seek to capture the pointer to handle "
"move events for a gesture (e.g., dragging), but conditionally may "
"allow the ReactRootView to emit events (e.g., if the "
"@PointerEventKind.End event is received before a drag threshold is hit."
)
Boolean AllowUncaptured {
get;
set;
};
}
} // namespace Microsoft.ReactNative
2 changes: 1 addition & 1 deletion vnext/Microsoft.ReactNative/Views/TouchEventHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ void TouchEventHandler::OnPointerPressed(
return;
}

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

Expand Down

0 comments on commit 0f6bdf3

Please sign in to comment.