Repository: unoplatform/uno
File: src/Uno.UI/UI/Xaml/UIElement.Pointers.cs (C#)

Code before:

			that.SafeRaiseEvent(ManipulationInertiaStartingEvent, new ManipulationInertiaStartingRoutedEventArgs(src, that, args));
		};

		private static readonly TypedEventHandler<GestureRecognizer, ManipulationCompletedEventArgs> OnRecognizerManipulationCompleted = (sender, args) =>
		{
			var that = (UIElement)sender.Owner;
			var src = PointerRoutedEventArgs.LastPointerEvent?.OriginalSource as UIElement ?? that;

#if !HAS_NATIVE_IMPLICIT_POINTER_CAPTURE
			foreach (var pointer in args.Pointers)
			{
				that.ReleasePointerCapture(pointer, muteEvent: true, PointerCaptureKind.Implicit);
			}
#endif

			that.SafeRaiseEvent(ManipulationCompletedEvent, new ManipulationCompletedRoutedEventArgs(src, that, args));

#if UNO_HAS_MANAGED_POINTERS
			that.XamlRoot?.VisualTree.ContentRoot.InputManager.Pointers.UnregisterUiElementManipulationRecognizer(args.Pointers, sender);
#endif
		};

		private static readonly TypedEventHandler<GestureRecognizer, TappedEventArgs> OnRecognizerTapped = (sender, args) =>
		{
			var src = (UIElement)sender.Owner;

			if (args.TapCount == 1)
			{
				src.SafeRaiseEvent(TappedEvent, new TappedRoutedEventArgs(src, args));
			}
			else // i.e. args.TapCount == 2
			{
				src.SafeRaiseEvent(DoubleTappedEvent, new DoubleTappedRoutedEventArgs(src, args));
			}
		};

		private static readonly TypedEventHandler<GestureRecognizer, RightTappedEventArgs> OnRecognizerRightTapped = (sender, args) =>
		{
			var that = (UIElement)sender.Owner;
			var src = PointerRoutedEventArgs.LastPointerEvent?.OriginalSource as UIElement ?? that;

			that.SafeRaiseEvent(RightTappedEvent, new RightTappedRoutedEventArgs(src, args));
		};

		private static readonly TypedEventHandler<GestureRecognizer, HoldingEventArgs> OnRecognizerHolding = (sender, args) =>
		{
			var that = (UIElement)sender.Owner;
			var src = PointerRoutedEventArgs.LastPointerEvent?.OriginalSource as UIElement ?? that;

			that.SafeRaiseEvent(HoldingEvent, new HoldingRoutedEventArgs(src, args));

Review comment (suggestion):
Humm, we should validate the behavior on windows. I think that the `OriginalSource` should still be the `inner` in your test.

Code after:

			that.SafeRaiseEvent(ManipulationInertiaStartingEvent, new ManipulationInertiaStartingRoutedEventArgs(src, that, args));
		};

		private static readonly TypedEventHandler<GestureRecognizer, ManipulationCompletedEventArgs> OnRecognizerManipulationCompleted = (sender, args) =>
		{
			var that = (UIElement)sender.Owner;
			var src = PointerRoutedEventArgs.LastPointerEvent?.OriginalSource as UIElement ?? that;

#if !HAS_NATIVE_IMPLICIT_POINTER_CAPTURE
			foreach (var pointer in args.Pointers)
			{
				that.ReleasePointerCapture(pointer, muteEvent: true, PointerCaptureKind.Implicit);
			}
#endif

			that.SafeRaiseEvent(ManipulationCompletedEvent, new ManipulationCompletedRoutedEventArgs(src, that, args));

#if UNO_HAS_MANAGED_POINTERS
			that.XamlRoot?.VisualTree.ContentRoot.InputManager.Pointers.UnregisterUiElementManipulationRecognizer(args.Pointers, sender);
#endif
		};

		private static readonly TypedEventHandler<GestureRecognizer, TappedEventArgs> OnRecognizerTapped = (sender, args) =>
		{
			var that = (UIElement)sender.Owner;
			var src = PointerRoutedEventArgs.LastPointerEvent?.OriginalSource as UIElement ?? that;

			if (args.TapCount == 1)
			{
				that.SafeRaiseEvent(TappedEvent, new TappedRoutedEventArgs(src, args, that));
			}
			else // i.e. args.TapCount == 2
			{
				that.SafeRaiseEvent(DoubleTappedEvent, new DoubleTappedRoutedEventArgs(src, args, that));
			}
		};

		private static readonly TypedEventHandler<GestureRecognizer, RightTappedEventArgs> OnRecognizerRightTapped = (sender, args) =>
		{
			var that = (UIElement)sender.Owner;
			var src = PointerRoutedEventArgs.LastPointerEvent?.OriginalSource as UIElement ?? that;

			that.SafeRaiseEvent(RightTappedEvent, new RightTappedRoutedEventArgs(src, args, that));
		};

		private static readonly TypedEventHandler<GestureRecognizer, HoldingEventArgs> OnRecognizerHolding = (sender, args) =>
		{
			var that = (UIElement)sender.Owner;
			var src = PointerRoutedEventArgs.LastPointerEvent?.OriginalSource as UIElement ?? that;