Skip to content

Commit 04c392a

Browse files
authored
Merge pull request #21321 from unoplatform/dev/dr/cancelDIrectManip
feat: Add support for ManipulationMode=None
2 parents f13ac3c + d72aee1 commit 04c392a

File tree

5 files changed

+64
-10
lines changed

5 files changed

+64
-10
lines changed

src/Uno.UI.RuntimeTests/Tests/Uno_UI_Xaml_Core/Given_InputManager.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,6 +1323,57 @@ public async Task When_DirectManipulationMixedWithUIElementManipulation_Then_Top
13231323
completed.Should().Be(0);
13241324
}
13251325

1326+
[TestMethod]
1327+
#if __WASM__
1328+
[Ignore("Scrolling is handled by native code and InputInjector is not yet able to inject native pointers.")]
1329+
#elif !HAS_INPUT_INJECTOR
1330+
[Ignore("InputInjector is not supported on this platform.")]
1331+
#endif
1332+
[DataRow(ManipulationModes.None)]
1333+
[DataRow(ManipulationModes.TranslateX)]
1334+
[DataRow(ManipulationModes.TranslateY)]
1335+
[DataRow(ManipulationModes.TranslateRailsX)]
1336+
[DataRow(ManipulationModes.TranslateRailsY)]
1337+
[DataRow(ManipulationModes.TranslateInertia)]
1338+
[DataRow(ManipulationModes.All)] // Does **NOT** include System
1339+
public async Task When_DirectManipulationDisabled(ManipulationModes mode)
1340+
{
1341+
ScrollViewer sv;
1342+
var ui = new Grid
1343+
{
1344+
Width = 200,
1345+
Height = 200,
1346+
Children =
1347+
{
1348+
(sv = new ScrollViewer
1349+
{
1350+
UpdatesMode = Uno.UI.Xaml.Controls.ScrollViewerUpdatesMode.Synchronous,
1351+
IsScrollInertiaEnabled = false,
1352+
Background = new SolidColorBrush(Colors.DeepPink),
1353+
Content = new Border
1354+
{
1355+
ManipulationMode = mode,
1356+
Background = new SolidColorBrush(Colors.DeepSkyBlue),
1357+
Margin = new Thickness(10),
1358+
Width = 800,
1359+
Height = 800,
1360+
}
1361+
}),
1362+
}
1363+
};
1364+
1365+
var bounds = await UITestHelper.Load(ui);
1366+
1367+
var injector = InputInjector.TryCreate() ?? throw new InvalidOperationException("Failed to init the InputInjector");
1368+
using var finger = injector.GetFinger();
1369+
1370+
finger.Drag(from: bounds.GetCenter(), to: bounds.GetCenter().Offset(y: -8000));
1371+
1372+
await UITestHelper.WaitForIdle();
1373+
1374+
sv.VerticalOffset.Should().Be(0);
1375+
}
1376+
13261377
private CoreCursorType? GetCursorShape()
13271378
{
13281379
var cursor = TestServices.WindowHelper

src/Uno.UI/UI/Xaml/Internal/InputManager.Pointers.ManagedDirectManip.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,16 @@ internal bool CancelDirectManipulations(UIElement requestingElement)
129129
var cancelled = false;
130130
foreach (var manipulation in _directManipulations)
131131
{
132-
if (manipulation.Handlers.Any(handler => handler.Owner == requestingElement))
132+
if (manipulation.Handlers.Any(IsForParentOfRequestingElement))
133133
{
134134
cancelled |= manipulation.Cancel();
135135
}
136136
}
137137

138138
return cancelled;
139+
140+
bool IsForParentOfRequestingElement(IDirectManipulationHandler handler)
141+
=> handler.Owner is DependencyObject owner && requestingElement.GetAllParents(includeCurrent: true).Contains(owner);
139142
}
140143

141144
private bool IsRedirectedToManipulations(PointerIdentifier pointerId)

src/Uno.UI/UI/Xaml/Internal/PointerCaptureOptions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ internal enum PointerCaptureOptions : byte
1010
None = 0,
1111

1212
/// <summary>
13+
/// DEPRECATED: Setting ManipulationMode=None is equivalent to setting this option.
14+
///
1315
/// Indicates that the pointer capture should prevent the "direct manipulation" (a.k.a. OS steal) which would takes over the capture (mainly for scrolling using touch and pen).
1416
/// This applies for:
1517
/// * iOS and Android, where we configure the OS to forbid it to steal the pointer when it detects a scroll gesture.

src/Uno.UI/UI/Xaml/UIElement.FocusMixins.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@
77

88
namespace Microsoft.UI.Xaml
99
{
10-
/// <summary>
11-
/// This contains focus-related mixins that belong either in UIElement or in Control depending whether
12-
/// targeting UWP or WinUI. When WinUI becomes the "standard", we can move this in UIElement directly.
13-
/// </summary>
10+
// This file contains focus-related mixins that belong either in UIElement or in Control depending whether
11+
// targeting UWP or WinUI. When WinUI becomes the "standard", we can move this in UIElement directly.
12+
1413
public partial class UIElement
1514
{
1615
public FocusState FocusState

src/Uno.UI/UI/Xaml/UIElement.Pointers.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,11 +1042,10 @@ internal bool OnPointerDown(PointerRoutedEventArgs args, BubblingContext ctx = d
10421042
#endif
10431043
}
10441044

1045-
// TODO
1046-
//if (!ManipulationMode.HasFlag(ManipulationModes.System))
1047-
//{
1048-
// Cancel[ALL]DirectManipulation()
1049-
//}
1045+
if (!ManipulationMode.HasFlag(ManipulationModes.System))
1046+
{
1047+
CancelDirectManipulations();
1048+
}
10501049

10511050
return handledInManaged;
10521051
}

0 commit comments

Comments
 (0)