Skip to content

Commit 1a26117

Browse files
committed
refactor: implement mouse events with PointerEvents API
1 parent 2a451d2 commit 1a26117

File tree

4 files changed

+86
-179
lines changed

4 files changed

+86
-179
lines changed

src/Runtime/Runtime/System.Windows.input/InputManager.cs

Lines changed: 23 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,21 @@ internal sealed class InputManager
2626
// Make sure to change both files if you update this !
2727
private enum EVENTS
2828
{
29-
MOUSE_MOVE = 0,
30-
MOUSE_LEFT_DOWN = 1,
31-
MOUSE_LEFT_UP = 2,
32-
MOUSE_RIGHT_DOWN = 3,
33-
MOUSE_RIGHT_UP = 4,
34-
MOUSE_ENTER = 5,
35-
MOUSE_LEAVE = 6,
29+
POINTER_MOVE = 0,
30+
POINTER_LEFT_DOWN = 1,
31+
POINTER_LEFT_UP = 2,
32+
POINTER_RIGHT_DOWN = 3,
33+
POINTER_RIGHT_UP = 4,
34+
POINTER_ENTER = 5,
35+
POINTER_LEAVE = 6,
3636
WHEEL = 7,
3737
KEYDOWN = 8,
3838
KEYUP = 9,
3939
KEYPRESS = 10,
40-
TOUCH_START = 11,
41-
TOUCH_END = 12,
42-
TOUCH_MOVE = 13,
43-
FOCUS_MANAGED = 14,
44-
FOCUS_UNMANAGED = 15,
45-
WINDOW_FOCUS = 16,
46-
WINDOW_BLUR = 17,
40+
FOCUS_MANAGED = 11,
41+
FOCUS_UNMANAGED = 12,
42+
WINDOW_FOCUS = 13,
43+
WINDOW_BLUR = 14,
4744
}
4845

4946
private enum MouseButton
@@ -179,7 +176,7 @@ internal bool CaptureMouse(UIElement uie)
179176
Pointer.Captured = uie;
180177

181178
string sDiv = OpenSilver.Interop.GetVariableStringForJS(uie.OuterDiv);
182-
OpenSilver.Interop.ExecuteJavaScriptVoid($"document.inputManager.captureMouse({sDiv});");
179+
OpenSilver.Interop.ExecuteJavaScriptVoid($"document.inputManager.capturePointer({sDiv})");
183180

184181
return true;
185182
}
@@ -192,7 +189,7 @@ internal void ReleaseMouseCapture(UIElement uie)
192189
if (Pointer.Captured == uie)
193190
{
194191
Pointer.Captured = null;
195-
OpenSilver.Interop.ExecuteJavaScriptVoid($"document.inputManager.releaseMouseCapture();");
192+
OpenSilver.Interop.ExecuteJavaScriptVoid($"document.inputManager.releasePointerCapture()");
196193

197194
RaiseUserInitiatedEvent(uie, new MouseEventArgs
198195
{
@@ -326,16 +323,16 @@ private void ProcessEvent(EVENTS eventType, object jsEventArg)
326323
{
327324
switch (eventType)
328325
{
329-
case EVENTS.MOUSE_LEFT_DOWN:
326+
case EVENTS.POINTER_LEFT_DOWN:
330327
_mouseLeftDown = true;
331328
RefreshClickCount(null, MouseButton.Left, Environment.TickCount, new Point());
332329
break;
333330

334-
case EVENTS.MOUSE_RIGHT_DOWN:
331+
case EVENTS.POINTER_RIGHT_DOWN:
335332
RefreshClickCount(null, MouseButton.Right, Environment.TickCount, new Point());
336333
break;
337334

338-
case EVENTS.MOUSE_LEFT_UP:
335+
case EVENTS.POINTER_LEFT_UP:
339336
_mouseLeftDown = false;
340337
ReleaseMouseCapture();
341338
break;
@@ -425,35 +422,33 @@ private void DispatchEvent(UIElement uie, EVENTS eventType, object jsEventArg)
425422
{
426423
switch (eventType)
427424
{
428-
case EVENTS.MOUSE_MOVE:
429-
case EVENTS.TOUCH_MOVE:
425+
case EVENTS.POINTER_MOVE:
430426
ProcessOnMouseMove(uie, jsEventArg);
431427
break;
432428

433-
case EVENTS.MOUSE_LEFT_DOWN:
434-
case EVENTS.TOUCH_START:
429+
case EVENTS.POINTER_LEFT_DOWN:
435430
_mouseLeftDown = true;
436431
ProcessOnMouseLeftButtonDown(uie, jsEventArg);
437432
break;
438433

439-
case EVENTS.MOUSE_LEFT_UP:
434+
case EVENTS.POINTER_LEFT_UP:
440435
_mouseLeftDown = false;
441436
ProcessOnMouseLeftButtonUp(uie, jsEventArg);
442437
break;
443438

444-
case EVENTS.MOUSE_RIGHT_DOWN:
439+
case EVENTS.POINTER_RIGHT_DOWN:
445440
ProcessOnMouseRightButtonDown(uie, jsEventArg);
446441
break;
447442

448-
case EVENTS.MOUSE_RIGHT_UP:
443+
case EVENTS.POINTER_RIGHT_UP:
449444
ProcessOnMouseRightButtonUp(uie, jsEventArg);
450445
break;
451446

452-
case EVENTS.MOUSE_ENTER:
447+
case EVENTS.POINTER_ENTER:
453448
ProcessOnMouseEnter(uie, jsEventArg);
454449
break;
455450

456-
case EVENTS.MOUSE_LEAVE:
451+
case EVENTS.POINTER_LEAVE:
457452
ProcessOnMouseLeave(uie, jsEventArg);
458453
break;
459454

@@ -473,10 +468,6 @@ private void DispatchEvent(UIElement uie, EVENTS eventType, object jsEventArg)
473468
ProcessOnKeyPress(uie, jsEventArg);
474469
break;
475470

476-
case EVENTS.TOUCH_END:
477-
ProcessOnTouchEndEvent(uie, jsEventArg);
478-
break;
479-
480471
case EVENTS.FOCUS_UNMANAGED:
481472
ProcessOnFocusUnmanaged(uie, jsEventArg);
482473
break;
@@ -765,22 +756,6 @@ private void ProcessPointerEvent(UIElement uie, object jsEventArg, RoutedEvent r
765756
RaiseUserInitiatedEvent(uie, e);
766757
}
767758

768-
private void ProcessOnTouchEndEvent(
769-
UIElement uie,
770-
object jsEventArg)
771-
{
772-
var e = new MouseButtonEventArgs()
773-
{
774-
RoutedEvent = UIElement.MouseLeftButtonUpEvent,
775-
OriginalSource = uie,
776-
UIEventArg = jsEventArg,
777-
};
778-
779-
e.FillEventArgs(uie, jsEventArg);
780-
781-
RaiseUserInitiatedEvent(uie, e);
782-
}
783-
784759
private bool ProcessMouseButtonEvent(
785760
UIElement uie,
786761
object jsEventArg,

src/Runtime/Runtime/System.Windows.input/MouseEventArgs.cs

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
\*====================================================================================*/
1313

1414
using System.ComponentModel;
15-
using System.Globalization;
1615
using System.Windows.Controls.Primitives;
1716
using CSHTML5.Internal;
1817
using OpenSilver.Internal;
@@ -80,51 +79,22 @@ internal void FillEventArgs(UIElement element, object jsEventArg)
8079

8180
protected internal void SetPointerAbsolutePosition(object jsEventArg, Window window)
8281
{
83-
{
84-
// Hack to improve the Simulator performance by making only one interop call rather than two:
85-
string sEvent = OpenSilver.Interop.GetVariableStringForJS(jsEventArg);
86-
string type = OpenSilver.Interop.ExecuteJavaScriptString($"{sEvent}.type");
87-
IsTouchEvent = type.StartsWith("touch");
88-
string concatenated = IsTouchEvent ? OpenSilver.Interop.ExecuteJavaScriptString($"{sEvent}.changedTouches[0].pageX + '|' + {sEvent}.changedTouches[0].pageY")
89-
: OpenSilver.Interop.ExecuteJavaScriptString($"{sEvent}.pageX + '|' + {sEvent}.pageY");
90-
int sepIndex = concatenated.IndexOf('|');
91-
string pointerAbsoluteXAsString = concatenated.Substring(0, sepIndex);
92-
string pointerAbsoluteYAsString = concatenated.Substring(sepIndex + 1);
93-
_pointerAbsoluteX = double.Parse(pointerAbsoluteXAsString, CultureInfo.InvariantCulture); //todo: verify that the locale is OK. I think that JS by default always produces numbers in invariant culture (with "." separator).
94-
_pointerAbsoluteY = double.Parse(pointerAbsoluteYAsString, CultureInfo.InvariantCulture); //todo: read note above
95-
}
82+
string sEvent = OpenSilver.Interop.GetVariableStringForJS(jsEventArg);
83+
IsTouchEvent = OpenSilver.Interop.ExecuteJavaScriptBoolean($"{sEvent}.pointerType === 'touch'", false);
84+
_pointerAbsoluteX = OpenSilver.Interop.ExecuteJavaScriptDouble($"{sEvent}.pageX", false);
85+
_pointerAbsoluteY = OpenSilver.Interop.ExecuteJavaScriptDouble($"{sEvent}.pageY", false);
9686

9787
//---------------------------------------
9888
// Adjust the absolute coordinates to take into account the fact that the XAML Window is not necessary un the top-left corner of the HTML page:
9989
//---------------------------------------
10090
if (window != null)
10191
{
102-
// Get the XAML Window root position relative to the page:
92+
// Get the XAML Window root position relative to the page and substracts it
10393
string sElement = OpenSilver.Interop.GetVariableStringForJS(window.OuterDiv);
104-
105-
double windowRootLeft;
106-
double windowRootTop;
107-
108-
// Hack to improve the Simulator performance by making only one interop call rather than two:
109-
string concatenated = OpenSilver.Interop.ExecuteJavaScriptString(
110-
$"({sElement}.getBoundingClientRect().left - document.body.getBoundingClientRect().left) + '|' + ({sElement}.getBoundingClientRect().top - document.body.getBoundingClientRect().top)");
111-
int sepIndex = concatenated.IndexOf('|');
112-
if (sepIndex > -1)
113-
{
114-
string windowRootLeftAsString = concatenated.Substring(0, sepIndex);
115-
string windowRootTopAsString = concatenated.Substring(sepIndex + 1);
116-
windowRootLeft = double.Parse(windowRootLeftAsString, CultureInfo.InvariantCulture);
117-
windowRootTop = double.Parse(windowRootTopAsString, CultureInfo.InvariantCulture);
118-
}
119-
else
120-
{
121-
windowRootLeft = Double.NaN;
122-
windowRootTop = Double.NaN;
123-
}
124-
125-
// Substract the XAML Window position, to get the pointer position relative to the XAML Window root:
126-
_pointerAbsoluteX -= windowRootLeft;
127-
_pointerAbsoluteY -= windowRootTop;
94+
_pointerAbsoluteX -= OpenSilver.Interop.ExecuteJavaScriptDouble(
95+
$"{sElement}.getBoundingClientRect().left - document.body.getBoundingClientRect().left", false);
96+
_pointerAbsoluteY -= OpenSilver.Interop.ExecuteJavaScriptDouble(
97+
$"{sElement}.getBoundingClientRect().top - document.body.getBoundingClientRect().top", false);
12898
}
12999
}
130100

src/Runtime/Scripts/cshtml5.css

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,17 @@ body {
3838
-webkit-user-select: text; /* 'none' prevents copy paste. 'text' allows it. */
3939
}
4040

41-
.opensilver-mouse-captured {
41+
.opensilver-pointer-captured {
4242
-moz-user-select: none; /* Firefox */
4343
-webkit-user-select: none; /* Chrome, Safari, and Opera */
4444
-ms-user-select: none; /* Internet Explorer/Edge */
4545
user-select: none;
4646
}
4747

48+
.opensilver-root-element {
49+
touch-action: none; /* prevents the browser from cancelling pointermove events */
50+
}
51+
4852
.uielement-collapsed {
4953
display: none !important;
5054
}

0 commit comments

Comments
 (0)