Skip to content

Allow pointer events on selectable Text#7813

Merged
NickGerleman merged 6 commits into
microsoft:mainfrom
rozele:issue7812
Oct 8, 2021
Merged

Allow pointer events on selectable Text#7813
NickGerleman merged 6 commits into
microsoft:mainfrom
rozele:issue7812

Conversation

@rozele
Copy link
Copy Markdown
Contributor

@rozele rozele commented May 20, 2021

When TextBlock::IsTextSelectionEnabled is set to true, pointer events are canceled because the events are always marked as handled by the TextBlock, thus the events never reach the React Native root view. This change subscribes a TouchEventHandler to Text when the selectable prop is set to true, and also modifies the TouchEventHandler to conditionally fire onTouchCancel event only when text is selected as a result of the pointer events (e.g., click-and-drag or the second click of a double click). This allows us to create onPress callbacks that mimic the behavior of the XAML hyperlink component. In order for the correct page layout dimensions to be reported, we also need to walk the tree to find the root XAML view. This was set up conditionally for only selectable Text as walking the tree to the root for Flyout (which also subscribes it's own TouchEventHandler) seems to break press events.

Fixes #7812

Microsoft Reviewers: Open in CodeFlow

@rozele rozele requested a review from a team as a code owner May 20, 2021 16:22
@rozele
Copy link
Copy Markdown
Contributor Author

rozele commented May 20, 2021

Here is a recording of the example added to RNTester:

playground.2021-05-20.12-27-16.mp4

See the issue for "before".

Comment thread vnext/Microsoft.ReactNative/Views/TextViewManager.cpp Outdated
Comment thread vnext/Microsoft.ReactNative/Views/TextViewManager.cpp Outdated
Comment thread vnext/Microsoft.ReactNative/Views/TextViewManager.cpp Outdated
Comment thread vnext/Microsoft.ReactNative/Views/TouchEventHandler.cpp Outdated
Comment thread vnext/Microsoft.ReactNative/Views/TextViewManager.cpp
@rozele rozele force-pushed the issue7812 branch 2 times, most recently from bc1ef3a to 86dfb2d Compare July 3, 2021 20:04
@NickGerleman
Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines
Copy link
Copy Markdown
Contributor

Azure Pipelines successfully started running 1 pipeline(s).

rozele added a commit to rozele/react-native-windows that referenced this pull request Jul 29, 2021
We had previously created a custom component called
HyperlinkTextViewManager that derived from VirtualTextViewManager to
enable focus on pressable text, get the correct cursor behavior for
pressable text, and to work around the issue with text hit testing that
is being addressed in microsoft#7553). Rather than adding a new component that
has no meaning on other platforms, we can use Hyperlink when virtual
text meets certain conditions.

This is really just a proposal for now, we should discuss if this change
is warranted and, if so, under what conditions the Span should be
swapped out for a Hyperlink.

Please note this diff is dependent on microsoft#7553 and microsoft#7813 as we want to use
the TouchEventHandler implementation to handle clicks in a way that they
leverage the existing bubble / capture mechanisms of React Native. Also,
the Hyperlink::Click event does not given you important details like the
pointer position (see
microsoft/microsoft-ui-xaml#4730).

Remaining TODOs are:
1. Enable handled keyboard events on Hyperlink to flow so
`usePressability` can handle keyboard invocation events.
2. Decide under what conditions we want to swap Span with Hyperlink.
This PR uses `accessibilityRole` settings as an example, but we could
also send an `isPressable` prop.
3. Add focus-related props to virtual text, so Hyperlink can set
properties like TabIndex, TabStop, and UseSystemFocusVisuals.
One remaining bit is how to enable "handled" keyboard events (as the
`Enter` and `Space` keys are handled by Hyperlink component
@rozele rozele force-pushed the issue7812 branch 2 times, most recently from f7051a5 to 04ae3d0 Compare August 3, 2021 17:32
rozele added a commit to rozele/react-native-windows that referenced this pull request Aug 3, 2021
We had previously created a custom component called
HyperlinkTextViewManager that derived from VirtualTextViewManager to
enable focus on pressable text, get the correct cursor behavior for
pressable text, and to work around the issue with text hit testing that
is being addressed in microsoft#7553). Rather than adding a new component that
has no meaning on other platforms, we can use Hyperlink when virtual
text meets certain conditions.

This is really just a proposal for now, we should discuss if this change
is warranted and, if so, under what conditions the Span should be
swapped out for a Hyperlink.

Please note this diff is dependent on microsoft#7553 and microsoft#7813 as we want to use
the TouchEventHandler implementation to handle clicks in a way that they
leverage the existing bubble / capture mechanisms of React Native. Also,
the Hyperlink::Click event does not given you important details like the
pointer position (see
microsoft/microsoft-ui-xaml#4730).

Remaining TODOs are:
1. Enable handled keyboard events on Hyperlink to flow so
`usePressability` can handle keyboard invocation events.
2. Decide under what conditions we want to swap Span with Hyperlink.
This PR uses `accessibilityRole` settings as an example, but we could
also send an `isPressable` prop.
3. Add focus-related props to virtual text, so Hyperlink can set
properties like TabIndex, TabStop, and UseSystemFocusVisuals.
One remaining bit is how to enable "handled" keyboard events (as the
`Enter` and `Space` keys are handled by Hyperlink component
@rozele rozele force-pushed the issue7812 branch 2 times, most recently from 9281d08 to 92624a0 Compare August 3, 2021 21:33
Comment thread vnext/Microsoft.ReactNative/Views/TouchEventHandler.cpp
@rozele
Copy link
Copy Markdown
Contributor Author

rozele commented Aug 28, 2021

Wait on this until #8495 lands, so we can use the OnPointerCaptureLost virtual method on ViewManagerBase to prevent cancellation due to PointerCaptureLost event.

@rozele rozele marked this pull request as draft August 31, 2021 21:20
@rozele rozele force-pushed the issue7812 branch 3 times, most recently from 325df7a to 90cde04 Compare September 9, 2021 01:56
@rozele rozele force-pushed the issue7812 branch 2 times, most recently from 87e160c to ce4bde0 Compare September 30, 2021 15:00
@rozele rozele marked this pull request as ready for review September 30, 2021 15:02
@rozele rozele force-pushed the issue7812 branch 2 times, most recently from 56e1527 to 3034986 Compare September 30, 2021 15:07
When TextBlock::IsTextSelectionEnabled is set to true, pointer events
are canceled because the events are always marked as handled by the
TextBlock, thus the events never reach the React Native root view. This
change subscribes a TouchEventHandler to Text when the `selectable` prop
is set to true, and also conditionally fires the `onTouchEnd` event when
PointerCaptureLost fires when text is *not* selected as a result of the
pointer events (e.g., click-and-drag or the second click of a double
click). This allows us to create `onPress` callbacks that mimic the
behavior of the XAML hyperlink component. In order for the correct
page layout dimensions to be reported, we also need to provide the root
view to TouchEventHandler.

Fixes microsoft#7812
@NickGerleman
Copy link
Copy Markdown
Contributor

Fixes #7954

@NickGerleman NickGerleman linked an issue Oct 8, 2021 that may be closed by this pull request
@NickGerleman
Copy link
Copy Markdown
Contributor

@rozele would you like me to rebase this?

@NickGerleman NickGerleman merged commit e7735a8 into microsoft:main Oct 8, 2021
@rozele
Copy link
Copy Markdown
Contributor Author

rozele commented Oct 9, 2021

Thanks for rebasing @NickGerleman! Are you sure this fixes #7954? This didn't add anything to support onPressIn/onPressOut, just made it so selectable text could respond to pointer events.

@asklar
Copy link
Copy Markdown
Member

asklar commented Oct 12, 2021

@rozele @NickGerleman was this prematurely merged/closed?

@epletcher72
Copy link
Copy Markdown

It does look like this was prematurely merged/closed. As of right now, onpressin/out is still not supported.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Text.onPressIn|Out Selectable text is not pressable

5 participants