Skip to content

Commit

Permalink
asd
Browse files Browse the repository at this point in the history
  • Loading branch information
ramezgerges committed Aug 12, 2024
1 parent 859241f commit 440cc99
Show file tree
Hide file tree
Showing 12 changed files with 1,288 additions and 154 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,7 @@ private void UseDevice(PointerPoint pointer, Gdk.Device device)
properties.IsRightButtonPressed = IsPressed(state, ModifierType.Button3Mask, properties.PointerUpdateKind, RightButtonPressed, RightButtonReleased);
properties.IsXButton1Pressed = IsPressed(state, ModifierType.Button4Mask, properties.PointerUpdateKind, XButton1Pressed, XButton1Released);
properties.IsXButton2Pressed = IsPressed(state, ModifierType.Button5Mask, properties.PointerUpdateKind, XButton1Pressed, XButton2Released);
properties.IsTouchPad = dev.Source == InputSource.Touchpad;
break;

case PointerDeviceType.Pen:
Expand Down
142 changes: 142 additions & 0 deletions src/Uno.UI.Runtime.Skia.X11/X11PointerInputSource.CoreProtocol.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
using System;
using Windows.Devices.Input;
using Windows.Foundation;
using Windows.UI.Core;
using Windows.UI.Input;
using Microsoft.UI.Xaml.Controls;
using Uno.UI.Hosting;

namespace Uno.WinUI.Runtime.Skia.X11;

internal partial class X11PointerInputSource
{
private const int LEFT = 1;
private const int MIDDLE = 2;
private const int RIGHT = 3;
private const int SCROLL_UP = 4;
private const int SCROLL_DOWN = 5;
private const int SCROLL_LEFT = 6;
private const int SCROLL_RIGHT = 7;
private const int XButton1 = 8;
private const int XButton2 = 9;

private Point _mousePosition;
private int _pressedButtons; // // bit 0 is not used

public void ProcessLeaveEvent(XCrossingEvent ev)
{
_mousePosition = new Point(ev.x, ev.y);

var point = CreatePointFromCurrentState(ev.time);
var modifiers = X11XamlRootHost.XModifierMaskToVirtualKeyModifiers(ev.state);

var args = new PointerEventArgs(point, modifiers);

CreatePointFromCurrentState(ev.time);
X11XamlRootHost.QueueAction(_host, () => RaisePointerExited(args));
}

public void ProcessEnterEvent(XCrossingEvent ev)
{
_mousePosition = new Point(ev.x, ev.y);

var args = CreatePointerEventArgsFromCurrentState(ev.time, ev.state);
X11XamlRootHost.QueueAction(_host, () => RaisePointerEntered(args));
}

public void ProcessMotionNotifyEvent(XMotionEvent ev)
{
_mousePosition = new Point(ev.x, ev.y);

var args = CreatePointerEventArgsFromCurrentState(ev.time, ev.state);
X11XamlRootHost.QueueAction(_host, () => RaisePointerMoved(args));
}

public void ProcessButtonPressedEvent(XButtonEvent ev)
{
_mousePosition = new Point(ev.x, ev.y);
_pressedButtons = (byte)(_pressedButtons | 1 << ev.button);

var args = CreatePointerEventArgsFromCurrentState(ev.time, ev.state);

if (ev.button is SCROLL_LEFT or SCROLL_RIGHT or SCROLL_UP or SCROLL_DOWN)
{
// These scrolling events are shown as a ButtonPressed with a corresponding ButtonReleased in succession.
// We arbitrarily choose to handle this on the Pressed side and ignore the Released side.
// Note that this makes scrolling discrete, i.e. there is no Scrolling delta. Instead, we get a separate
// Pressed/Released pair for each scroll wheel "detent".

var props = args.CurrentPoint.Properties;
props.IsHorizontalMouseWheel = ev.button is SCROLL_LEFT or SCROLL_RIGHT;
props.MouseWheelDelta = ev.button is SCROLL_LEFT or SCROLL_UP ?
ScrollContentPresenter.ScrollViewerDefaultMouseWheelDelta :
-ScrollContentPresenter.ScrollViewerDefaultMouseWheelDelta;

X11XamlRootHost.QueueAction(_host, () => RaisePointerWheelChanged(args));
}
else
{
X11XamlRootHost.QueueAction(_host, () => RaisePointerPressed(args));
}
}

// Note about removing devices: the server emits a ButtonRelease if a device is removed
// while a button is held.
public void ProcessButtonReleasedEvent(XButtonEvent ev)
{
// TODO: what if button released when not same_screen?
if (ev.button is SCROLL_LEFT or SCROLL_RIGHT or SCROLL_UP or SCROLL_DOWN)
{
// Scroll events are already handled in ProcessButtonPressedEvent
return;
}

_mousePosition = new Point(ev.x, ev.y);
_pressedButtons = (byte)(_pressedButtons & ~(1 << ev.button));

var args = CreatePointerEventArgsFromCurrentState(ev.time, ev.state);
X11XamlRootHost.QueueAction(_host, () => RaisePointerReleased(args));
}

private PointerEventArgs CreatePointerEventArgsFromCurrentState(IntPtr time, XModifierMask state)
{
var point = CreatePointFromCurrentState(time);
var modifiers = X11XamlRootHost.XModifierMaskToVirtualKeyModifiers(state);

return new PointerEventArgs(point, modifiers);
}

/// <summary>
/// Create a new PointerPoint from the current state of the PointerInputSource
/// </summary>
private PointerPoint CreatePointFromCurrentState(IntPtr time)
{
var properties = new PointerPointProperties
{
// TODO: fill this comprehensively
IsLeftButtonPressed = (_pressedButtons & (1 << LEFT)) != 0,
IsMiddleButtonPressed = (_pressedButtons & (1 << MIDDLE)) != 0,
IsRightButtonPressed = (_pressedButtons & (1 << RIGHT)) != 0
};

var scale = ((IXamlRootHost)_host).RootElement?.XamlRoot is { } root
? root.RasterizationScale
: 1;

// Time is given in milliseconds since system boot
// This doesn't match the format of WinUI. See also: https://github.com/unoplatform/uno/issues/14535
var point = new PointerPoint(
frameId: (uint)time, // UNO TODO: How should set the frame, timestamp may overflow.
timestamp: (uint)time,
PointerDevice.For(PointerDeviceType.Mouse),
0, // TODO: XInput
new Point(_mousePosition.X / scale, _mousePosition.Y / scale),
new Point(_mousePosition.X / scale, _mousePosition.Y / scale),
// TODO: is isInContact correct?
properties.HasPressedButton,
properties
);

return point;
}
}
70 changes: 0 additions & 70 deletions src/Uno.UI.Runtime.Skia.X11/X11PointerInputSource.Mouse.cs

This file was deleted.

Loading

0 comments on commit 440cc99

Please sign in to comment.