Browse Source

Fix the known valuator do not update. (#17321)

* Fix the known valuator do not update.

Before this change, the properties Pressure, Touch Major, and Touch Minor would not update when the device changed.

After this change, the properties Pressure, Touch Major, and Touch Minor will refresh their values in response to device changes.

* Fix to not setting a value to null when a property could not be found
pull/17605/head
lindexi 2 years ago
committed by GitHub
parent
commit
f977d2228e
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 97
      src/Avalonia.X11/XI2Manager.cs

97
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<XIValuatorClassInfo>();
var scrollers = new List<XIScrollClassInfo>();
@ -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))
{

Loading…
Cancel
Save