Skip to content

Commit 997e851

Browse files
committed
Keep a touch pan with the scrollable that started it
- The browser backend remembers the element that scrolled for the pan and routes the rest of the gesture from it, so a list scrolled into the start point no longer takes the gesture over - The pin falls back to the point when it stops handling, which is how the gesture reaches an outer scrollable once the inner one runs out of room - The pin is dropped on a pointer press or cancel
1 parent b3e29e5 commit 997e851

2 files changed

Lines changed: 25 additions & 10 deletions

File tree

src/MewUI.Platform.Browser/BrowserWindowBackend.cs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ internal sealed class BrowserWindowBackend : IWindowBackend
99
private bool _disposed;
1010
private bool _shown;
1111
private bool _mouseCaptured;
12+
// Element that scrolled for the active touch pan, kept so the gesture cannot change owner.
13+
private UIElement? _panTarget;
1214
private readonly BrowserWindowSurface _surface = new();
1315

1416
internal BrowserWindowBackend(BrowserPlatformHost host, Window window)
@@ -86,6 +88,7 @@ internal bool PointerButton(double x, double y, double screenX, double screenY,
8688
bool isDown, int clickCount, ModifierKeys modifiers, PointerType pointerType)
8789
{
8890
if (!_shown || _disposed) return false;
91+
_panTarget = null;
8992
var mappedButton = button switch
9093
{
9194
1 => MouseButton.Middle,
@@ -147,15 +150,26 @@ internal void PointerPan(double x, double y, double screenX, double screenY,
147150

148151
// A notch is worth ScrollWheelStep DIPs, and notches may be fractional, so dividing the
149152
// finger delta by the step makes the content track the finger one to one.
150-
WindowInputRouter.MouseWheel(
151-
Window,
152-
new Point(x, y),
153-
new Point(screenX, screenY),
154-
new Vector(deltaXDip / step, deltaYDip / step),
155-
leftDown: false,
156-
rightDown: false,
157-
middleDown: false,
158-
modifiers);
153+
var delta = new Vector(deltaXDip / step, deltaYDip / step);
154+
var point = new Point(x, y);
155+
var screenPoint = new Point(screenX, screenY);
156+
157+
// The gesture stays with whatever first scrolled for it. Hit-testing the start point again
158+
// every move would hand the gesture to any other scrollable that the scrolling brought under
159+
// it. A pinned target that stops handling (it ran out of room, or it was virtualized away)
160+
// falls back to the point, which is also how the gesture reaches an outer scrollable.
161+
var handler = WindowInputRouter.MouseWheel(
162+
Window, point, screenPoint, delta, false, false, false, modifiers, _panTarget);
163+
if (handler == null && _panTarget != null)
164+
{
165+
handler = WindowInputRouter.MouseWheel(
166+
Window, point, screenPoint, delta, false, false, false, modifiers, routeFrom: null);
167+
}
168+
169+
if (handler != null)
170+
{
171+
_panTarget = handler;
172+
}
159173
}
160174

161175
internal void PointerLeave()
@@ -170,6 +184,7 @@ internal void PointerCancel()
170184
{
171185
if (_disposed) return;
172186
_mouseCaptured = false;
187+
_panTarget = null;
173188
Window.ReleaseMouseCapture();
174189
WindowInputRouter.UpdateMouseOver(Window, null);
175190
}

src/MewUI.Platform.Browser/Registration.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public static bool RenderFrame(double cssWidth, double cssHeight, double deviceP
3232
public static bool PointerMove(double x, double y, double screenX, double screenY, int buttons, ModifierKeys modifiers)
3333
=> BrowserPlatformHost.Active?.PointerMove(x, y, screenX, screenY, buttons, modifiers) == true;
3434

35-
/// <param name="pointerType">0 for a mouse, 1 for touch, 2 for a pen.</param>
35+
/// <summary>Routes a pointer press or release; pointerType is 0 for a mouse, 1 for touch, 2 for a pen.</summary>
3636
public static bool PointerButton(double x, double y, double screenX, double screenY, int button, int buttons,
3737
bool isDown, int clickCount, ModifierKeys modifiers, int pointerType)
3838
=> BrowserPlatformHost.Active?.PointerButton(

0 commit comments

Comments
 (0)