diff --git a/src/Avalonia.X11/XI2Manager.cs b/src/Avalonia.X11/XI2Manager.cs index d105fbaaad..0f7c71eb55 100644 --- a/src/Avalonia.X11/XI2Manager.cs +++ b/src/Avalonia.X11/XI2Manager.cs @@ -42,10 +42,15 @@ namespace Avalonia.X11 public DeviceInfo(XIDeviceInfo info) { Id = info.Deviceid; - Update(info.Classes, info.NumClasses); + UpdateCore(info.Classes, info.NumClasses); } public virtual void Update(XIAnyClassInfo** classes, int num) + { + UpdateCore(classes, num); + } + + private void UpdateCore(XIAnyClassInfo** classes, int num) { var valuators = new List(); var scrollers = new List(); @@ -73,8 +78,49 @@ namespace Avalonia.X11 private class PointerDeviceInfo : DeviceInfo { - public PointerDeviceInfo(XIDeviceInfo info) : base(info) + public PointerDeviceInfo(XIDeviceInfo info, X11Info x11Info) : base(info) + { + _x11 = x11Info; + + UpdateKnownValuator(); + } + + private readonly X11Info _x11; + + private void UpdateKnownValuator() + { + // ABS_MT_TOUCH_MAJOR ABS_MT_TOUCH_MINOR + // https://www.kernel.org/doc/html/latest/input/multi-touch-protocol.html + var touchMajorAtom = XInternAtom(_x11.Display, "Abs MT Touch Major", false); + var touchMinorAtom = XInternAtom(_x11.Display, "Abs MT Touch Minor", false); + + var pressureAtom = XInternAtom(_x11.Display, "Abs MT Pressure", false); + + PressureXIValuatorClassInfo = null; + TouchMajorXIValuatorClassInfo = null; + TouchMinorXIValuatorClassInfo = null; + + foreach (var xiValuatorClassInfo in Valuators) + { + if (xiValuatorClassInfo.Label == pressureAtom) + { + PressureXIValuatorClassInfo = xiValuatorClassInfo; + } + else if (xiValuatorClassInfo.Label == touchMajorAtom) + { + TouchMajorXIValuatorClassInfo = xiValuatorClassInfo; + } + else if (xiValuatorClassInfo.Label == touchMinorAtom) + { + TouchMinorXIValuatorClassInfo = xiValuatorClassInfo; + } + } + } + + public override void Update(XIAnyClassInfo** classes, int num) { + base.Update(classes, num); + UpdateKnownValuator(); } public bool HasScroll(ParsedDeviceEvent ev) @@ -94,16 +140,15 @@ namespace Avalonia.X11 return false; } - + + public XIValuatorClassInfo? PressureXIValuatorClassInfo { get; private set; } + public XIValuatorClassInfo? TouchMajorXIValuatorClassInfo { get; private set; } + public XIValuatorClassInfo? TouchMinorXIValuatorClassInfo { get; private set; } } private PointerDeviceInfo _pointerDevice; private AvaloniaX11Platform _platform; - private XIValuatorClassInfo? _pressureXIValuatorClassInfo; - private XIValuatorClassInfo? _touchMajorXIValuatorClassInfo; - private XIValuatorClassInfo? _touchMinorXIValuatorClassInfo; - public bool Init(AvaloniaX11Platform platform) { _platform = platform; @@ -115,42 +160,12 @@ namespace Avalonia.X11 { if (devices[c].Use == XiDeviceType.XIMasterPointer) { - _pointerDevice = new PointerDeviceInfo(devices[c]); + _pointerDevice = new PointerDeviceInfo(devices[c], _x11); break; } } if(_pointerDevice == null) return false; - - if (_multitouch) - { - // ABS_MT_TOUCH_MAJOR ABS_MT_TOUCH_MINOR - // https://www.kernel.org/doc/html/latest/input/multi-touch-protocol.html - var touchMajorAtom = XInternAtom(_x11.Display, "Abs MT Touch Major", false); - var touchMinorAtom = XInternAtom(_x11.Display, "Abs MT Touch Minor", false); - - var pressureAtom = XInternAtom(_x11.Display, "Abs MT Pressure", false); - - var pressureXIValuatorClassInfo = _pointerDevice.Valuators.FirstOrDefault(t => t.Label == pressureAtom); - if (pressureXIValuatorClassInfo.Label == pressureAtom) - { - // Why check twice? The XIValuatorClassInfo is struct, so the FirstOrDefault will return the default struct when not found. - _pressureXIValuatorClassInfo = pressureXIValuatorClassInfo; - } - - var touchMajorXIValuatorClassInfo = _pointerDevice.Valuators.FirstOrDefault(t => t.Label == touchMajorAtom); - if (touchMajorXIValuatorClassInfo.Label == touchMajorAtom) - { - _touchMajorXIValuatorClassInfo = touchMajorXIValuatorClassInfo; - } - - var touchMinorXIValuatorClassInfo = _pointerDevice.Valuators.FirstOrDefault(t => t.Label == touchMinorAtom); - if (touchMinorXIValuatorClassInfo.Label == touchMinorAtom) - { - _touchMinorXIValuatorClassInfo = touchMinorXIValuatorClassInfo; - } - } - /* int mask = 0; @@ -275,7 +290,7 @@ namespace Avalonia.X11 Position = ev.Position }; - if (_pressureXIValuatorClassInfo is {} valuatorClassInfo) + if (_pointerDevice.PressureXIValuatorClassInfo is {} valuatorClassInfo) { if (ev.Valuators.TryGetValue(valuatorClassInfo.Number, out var pressureValue)) { @@ -285,7 +300,7 @@ namespace Avalonia.X11 } } - if(_touchMajorXIValuatorClassInfo is {} touchMajorXIValuatorClassInfo) + if(_pointerDevice.TouchMajorXIValuatorClassInfo is {} touchMajorXIValuatorClassInfo) { double? touchMajor = null; double? touchMinor = null; @@ -308,7 +323,7 @@ namespace Avalonia.X11 if (touchMajor != null) { - if(_touchMinorXIValuatorClassInfo is {} touchMinorXIValuatorClassInfo) + if(_pointerDevice.TouchMinorXIValuatorClassInfo is {} touchMinorXIValuatorClassInfo) { if (ev.Valuators.TryGetValue(touchMinorXIValuatorClassInfo.Number, out var touchMinorValue)) {