Skip to content

Commit

Permalink
fix(reg): Fix pointer sequence
Browse files Browse the repository at this point in the history
  • Loading branch information
dr1rrb committed Feb 2, 2022
1 parent ddfd717 commit 8ecfc1e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 18 deletions.
41 changes: 25 additions & 16 deletions src/Uno.UI/UI/Xaml/Internal/RootVisual.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,12 @@ public RootVisual(CoreServices coreServices)
#if __ANDROID__
AddHandler(
PointerReleasedEvent,
new PointerEventHandler((snd, args) =>
{
// On Android we use the RootVisual to raise the UWP only exit event (in managed only)
if (args.Pointer.PointerDeviceType is PointerDeviceType.Touch && args.OriginalSource is UIElement src)
{
// It's acceptable to use only the OriginalSource on Android:
// since the platform has "implicit capture" and captures are propagated to the OS,
// the OriginalSource will be the element that has capture (if any).
src.RedispatchPointerExited(args.Reset(canBubbleNatively: false));
}
ReleaseCaptures(args.Reset(canBubbleNatively: false));
}),
handledEventsToo: true);
new PointerEventHandler((snd, args) => ProcessPointerUp(args)),
// We don't want handled events, they are forwarded directly by the element that has handled it,
// but only ** AFTER ** the up has been fully processed.
// This is required to be sure that element process gestures and manipulations before we raise the exit
// (e.g. the 'tapped' event on a Button would be fired after the 'exit').
handledEventsToo: false);
#endif

PointerPressed += RootVisual_PointerPressed;
Expand Down Expand Up @@ -168,7 +159,24 @@ private void RootVisual_PointerCanceled(object sender, PointerRoutedEventArgs e)
_isLeftButtonPressed = false;
}
#endif
private void ReleaseCaptures(PointerRoutedEventArgs routedArgs)

#if __ANDROID__
internal static void ProcessPointerUp(PointerRoutedEventArgs args)
{
// On Android we use the RootVisual to raise the UWP only exit event (in managed only)
if (args.Pointer.PointerDeviceType is PointerDeviceType.Touch && args.OriginalSource is UIElement src)
{
// It's acceptable to use only the OriginalSource on Android:
// since the platform has "implicit capture" and captures are propagated to the OS,
// the OriginalSource will be the element that has capture (if any).

src.RedispatchPointerExited(args.Reset(canBubbleNatively: false));
}

ReleaseCaptures(args.Reset(canBubbleNatively: false));
}

private static void ReleaseCaptures(PointerRoutedEventArgs routedArgs)
{
if (PointerCapture.TryGet(routedArgs.Pointer, out var capture))
{
Expand All @@ -178,5 +186,6 @@ private void ReleaseCaptures(PointerRoutedEventArgs routedArgs)
}
}
}
#endif
}
}
16 changes: 14 additions & 2 deletions src/Uno.UI/UI/Xaml/UIElement.Pointers.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,22 @@ private bool OnNativeMotionEvent(MotionEvent nativeEvent, PointerRoutedEventArgs
case MotionEventActions.Down:
case MotionEventActions.PointerDown:
return OnNativePointerDown(args);
case MotionEventActions.Up when args.Pointer.PointerDeviceType == PointerDeviceType.Touch:
case MotionEventActions.PointerUp when args.Pointer.PointerDeviceType == PointerDeviceType.Touch:
// For touch pointer, in the RootVisual we will redispatch this event to raise exit,
// but if the event has been handled, we need to raise it after the 'up' has been processed.
if (OnNativePointerUp(args))
{
Uno.UI.Xaml.Core.RootVisual.ProcessPointerUp(args);
return true;
}
else
{
return false;
}
case PointerRoutedEventArgs.StylusWithBarrelUp:
case MotionEventActions.Up:
case MotionEventActions.PointerUp:
// Note: for touch pointer, in the RootVisual we will redispatch this event to raise exit
return OnNativePointerUp(args);

// We get ACTION_DOWN and ACTION_UP only for "left" button, and instead we get a HOVER_MOVE when pressing/releasing the right button of the mouse.
Expand Down Expand Up @@ -175,7 +187,7 @@ private bool OnNativeMotionEvent(MotionEvent nativeEvent, PointerRoutedEventArgs
/// </summary>
/// <param name="args"></param>
internal void RedispatchPointerExited(PointerRoutedEventArgs args)
=> OnNativePointerExited(args);
=> OnNativePointerExited(args.Reset(canBubbleNatively: false));

partial void OnManipulationModeChanged(ManipulationModes oldMode, ManipulationModes newMode)
=> IsNativeMotionEventsInterceptForbidden = newMode == ManipulationModes.None;
Expand Down

0 comments on commit 8ecfc1e

Please sign in to comment.