microsoft / react-native-windows

A framework for building native Windows apps with React.
https://microsoft.github.io/react-native-windows/
Other
16.26k stars 1.14k forks source link

KeyboardEventHandler behaves differently on UWP and XAML Islands #7523

Open rozele opened 3 years ago

rozele commented 3 years ago

Steps To Reproduce

Provide a detailed list of steps that reproduce the issue.

  1. Open RNTester from playground-win32.sln
  2. Load the Text Input component example
  3. For any of the examples, add keyDownEvents for a key that would result in text changing in the TextBox (e.g., keyDownEvents={[{code: 'KeyC'}]}
  4. Try to type that character in the Win32 XAML Islands Playground, the TextBox will not receive the character.

Expected Results

On a UWP app, you can prevent a key from changing the TextBox text by setting the event as Handled in the PreviewKeyDown event. Setting the event as Handled in the KeyDown event does not prevent the key from changing the tetx.

However, it appears that on XAML Islands, setting the event as Handled on the KeyDown event also prevents it from changing the text box. Perhaps this is a bug that we want to report for XAML Islands, but I also think we should come up with a workaround in KeyboardEventHandler that provides consistent behavior for keyDownEvents on both UWP and XAML Islands.

Snack, code example, screenshot, or link to a repository:

In the video below, I set keyDownEvents={[{code: 'KeyC'}]} on the Auto-focus example in RNTester, and attempt to type 'abc' in the TextBox for both win32 and UWP:

https://user-images.githubusercontent.com/1106239/113482190-6a412d80-946b-11eb-8182-a14d51fb7ff5.mp4

asklar commented 3 years ago

Made a self-contained repro of both UWP and Islands without RNW involved: https://github.com/asklar/kbdIslands

Bug is likely going to be either in TSF/IXP, or on the xaml side; regardless, RNW will need to have a workaround since any OS fixes wouldn't help downlevel customers. Still, it would be good to track this in xaml for WinUI 3. https://github.com/microsoft/microsoft-ui-xaml/issues/4763

rectified95 commented 3 years ago

Bringing in context from offline discussions:

For a work around, I’m not so certain we need to mark events as handled at the view level. With pointer events, we do tree-walks to find the relevant React tag. What if we only subscribed PreviewKeyUp/Down and KeyUp/Down at the root, enumerated all nodes from OriginalSource to root, and marked the event as handled only if something in the path from root to OriginalSource has set the relevant keyDown/UpEvent prop and phase?

I don’t think we can take the approach I suggested because someone may have a custom view that has key event logic and might want the ability to prevent bubbling even within the React tree. My suggestion would have only prevented events from escaping the React root view. I suspect there’s not really a workaround for this other than documenting the difference. On XAML Islands apps we’ll just have to pick a parent component of the controls we want to stop bubbling on to mark the event as Handled.

lyahdav commented 2 years ago

I confirmed that WinUI 3 + RNW behaves like UWP + RNW:

https://user-images.githubusercontent.com/359157/191141422-e1b71afc-a987-4e48-a8b9-19c00b038b0b.mov