Browse Source

Merge branch 'master' into make-pointerpoint-to-be-a-struct

pull/8766/head
Dan Walmsley 4 years ago
committed by GitHub
parent
commit
c16494208a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      samples/ControlCatalog.NetCore/Program.cs
  2. 2
      samples/ControlCatalog/Pages/PointersPage.xaml.cs
  3. 12
      src/Android/Avalonia.Android/Platform/SkiaPlatform/InvalidationAwareSurfaceView.cs
  4. 17
      src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
  5. 251
      src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidMotionEventsHelper.cs
  6. 85
      src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs
  7. 4
      src/Avalonia.Base/Input/Raw/RawPointerEventArgs.cs
  8. 15
      src/Avalonia.Base/Media/KnownColors.cs
  9. 15
      src/Avalonia.Base/VisualTree/VisualExtensions.cs
  10. 1
      src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj
  11. 10
      src/Avalonia.Controls.DataGrid/Collections/DataGridSortDescription.cs
  12. 11
      src/Avalonia.Controls/Notifications/WindowNotificationManager.cs
  13. 3
      src/Avalonia.Dialogs/ManagedFileChooser.cs
  14. 319
      src/Avalonia.X11/X11Atoms.cs
  15. 8
      src/Avalonia.X11/X11CursorFactory.cs
  16. 15
      src/Avalonia.X11/X11Platform.cs
  17. 3
      src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs
  18. 8
      src/Shared/SourceGeneratorAttributes.cs
  19. 70
      src/Skia/Avalonia.Skia/Helpers/DrawingContextHelper.cs
  20. 9
      src/Windows/Avalonia.Win32/Win32Platform.cs
  21. 94
      src/tools/DevGenerators/EnumMemberDictionaryGenerator.cs
  22. 73
      src/tools/DevGenerators/X11AtomsGenerator.cs

4
samples/ControlCatalog.NetCore/Program.cs

@ -115,10 +115,6 @@ namespace ControlCatalog.NetCore
UseDBusMenu = true,
EnableIme = true
})
.With(new Win32PlatformOptions
{
EnableMultitouch = true
})
.UseSkia()
.AfterSetup(builder =>
{

2
samples/ControlCatalog/Pages/PointersPage.xaml.cs

@ -62,7 +62,7 @@ Position: ??? ???";
e.Pointer.Capture(null);
e.Handled = true;
}
else
else if (e.Pointer.Captured is not null)
{
throw new InvalidOperationException("How?");
}

12
src/Android/Avalonia.Android/Platform/SkiaPlatform/InvalidationAwareSurfaceView.cs

@ -47,18 +47,6 @@ namespace Avalonia.Android
}
}
[Obsolete("deprecated")]
public override void Invalidate(global::Android.Graphics.Rect dirty)
{
Invalidate();
}
[Obsolete("deprecated")]
public override void Invalidate(int l, int t, int r, int b)
{
Invalidate();
}
public void SurfaceChanged(ISurfaceHolder holder, Format format, int width, int height)
{
Log.Info("AVALONIA", "Surface Changed");

17
src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Android.Content;
using Android.Graphics;
using Android.Views;
@ -30,7 +31,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
private readonly IFramebufferPlatformSurface _framebuffer;
private readonly AndroidKeyboardEventsHelper<TopLevelImpl> _keyboardHelper;
private readonly AndroidTouchEventsHelper<TopLevelImpl> _touchHelper;
private readonly AndroidMotionEventsHelper _pointerHelper;
private readonly ITextInputMethodImpl _textInputMethod;
private ViewImpl _view;
@ -39,8 +40,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
_view = new ViewImpl(avaloniaView.Context, this, placeOnTop);
_textInputMethod = new AndroidInputMethod<ViewImpl>(_view);
_keyboardHelper = new AndroidKeyboardEventsHelper<TopLevelImpl>(this);
_touchHelper = new AndroidTouchEventsHelper<TopLevelImpl>(this, () => InputRoot,
GetAvaloniaPointFromEvent);
_pointerHelper = new AndroidMotionEventsHelper(this);
_gl = GlPlatformSurface.TryCreate(this);
_framebuffer = new FramebufferManager(this);
@ -160,10 +160,19 @@ namespace Avalonia.Android.Platform.SkiaPlatform
_tl.Draw();
}
protected override bool DispatchGenericPointerEvent(MotionEvent e)
{
bool callBase;
bool? result = _tl._pointerHelper.DispatchMotionEvent(e, out callBase);
bool baseResult = callBase ? base.DispatchGenericPointerEvent(e) : false;
return result != null ? result.Value : baseResult;
}
public override bool DispatchTouchEvent(MotionEvent e)
{
bool callBase;
bool? result = _tl._touchHelper.DispatchTouchEvent(e, out callBase);
bool? result = _tl._pointerHelper.DispatchMotionEvent(e, out callBase);
bool baseResult = callBase ? base.DispatchTouchEvent(e) : false;
return result != null ? result.Value : baseResult;

251
src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidMotionEventsHelper.cs

@ -0,0 +1,251 @@
using System;
using System.Collections.Generic;
using Android.Views;
using Avalonia.Android.Platform.SkiaPlatform;
using Avalonia.Collections.Pooled;
using Avalonia.Input;
using Avalonia.Input.Raw;
#nullable enable
namespace Avalonia.Android.Platform.Specific.Helpers
{
internal class AndroidMotionEventsHelper : IDisposable
{
private static readonly PooledList<RawPointerPoint> s_intermediatePointsPooledList = new(ClearMode.Never);
private static readonly float s_radiansToDegree = (float)(180f * Math.PI);
private readonly TouchDevice _touchDevice;
private readonly MouseDevice _mouseDevice;
private readonly PenDevice _penDevice;
private readonly TopLevelImpl _view;
private bool _disposed;
public AndroidMotionEventsHelper(TopLevelImpl view)
{
_touchDevice = new TouchDevice();
_penDevice = new PenDevice();
_mouseDevice = new MouseDevice();
_view = view;
}
public bool? DispatchMotionEvent(MotionEvent e, out bool callBase)
{
callBase = true;
if (_disposed)
{
return null;
}
var eventTime = (ulong)DateTime.Now.Millisecond;
var inputRoot = _view.InputRoot;
var actionMasked = e.ActionMasked;
var modifiers = GetModifiers(e.MetaState, e.ButtonState);
if (actionMasked == MotionEventActions.Move)
{
for (int index = 0; index < e.PointerCount; index++)
{
var toolType = e.GetToolType(index);
var device = GetDevice(toolType);
var eventType = toolType == MotionEventToolType.Finger ? RawPointerEventType.TouchUpdate : RawPointerEventType.Move;
var point = CreatePoint(e, index);
modifiers |= GetToolModifiers(toolType);
// ButtonState reports only mouse buttons, but not touch or stylus pointer.
if (toolType != MotionEventToolType.Mouse)
{
modifiers |= RawInputModifiers.LeftMouseButton;
}
var args = new RawTouchEventArgs(device, eventTime, inputRoot, eventType, point, modifiers, e.GetPointerId(index))
{
IntermediatePoints = new Lazy<IReadOnlyList<RawPointerPoint>?>(() =>
{
var site = e.HistorySize;
s_intermediatePointsPooledList.Clear();
s_intermediatePointsPooledList.Capacity = site;
for (int pos = 0; pos < site; pos++)
{
s_intermediatePointsPooledList.Add(CreateHistoricalPoint(e, index, pos));
}
return s_intermediatePointsPooledList;
})
};
_view.Input(args);
}
}
else
{
var index = e.ActionIndex;
var toolType = e.GetToolType(index);
var device = GetDevice(toolType);
modifiers |= GetToolModifiers(toolType);
var point = CreatePoint(e, index);
if (actionMasked == MotionEventActions.Scroll && toolType == MotionEventToolType.Mouse)
{
var delta = new Vector(e.GetAxisValue(Axis.Hscroll), e.GetAxisValue(Axis.Vscroll));
var args = new RawMouseWheelEventArgs(device, eventTime, inputRoot, point.Position, delta, RawInputModifiers.None);
_view.Input(args);
}
else
{
var eventType = GetActionType(e, actionMasked, toolType);
if (eventType >= 0)
{
var args = new RawTouchEventArgs(device, eventTime, inputRoot, eventType, point, modifiers, e.GetPointerId(index));
_view.Input(args);
}
}
}
return true;
}
private static RawInputModifiers GetModifiers(MetaKeyStates metaState, MotionEventButtonState buttonState)
{
var modifiers = RawInputModifiers.None;
if (metaState.HasAnyFlag(MetaKeyStates.ShiftOn))
{
modifiers |= RawInputModifiers.Shift;
}
if (metaState.HasAnyFlag(MetaKeyStates.CtrlOn))
{
modifiers |= RawInputModifiers.Control;
}
if (metaState.HasAnyFlag(MetaKeyStates.AltOn))
{
modifiers |= RawInputModifiers.Alt;
}
if (metaState.HasAnyFlag(MetaKeyStates.MetaOn))
{
modifiers |= RawInputModifiers.Meta;
}
if (buttonState.HasAnyFlag(MotionEventButtonState.Primary))
{
modifiers |= RawInputModifiers.LeftMouseButton;
}
if (buttonState.HasAnyFlag(MotionEventButtonState.Secondary))
{
modifiers |= RawInputModifiers.RightMouseButton;
}
if (buttonState.HasAnyFlag(MotionEventButtonState.Tertiary))
{
modifiers |= RawInputModifiers.MiddleMouseButton;
}
if (buttonState.HasAnyFlag(MotionEventButtonState.Back))
{
modifiers |= RawInputModifiers.XButton1MouseButton;
}
if (buttonState.HasAnyFlag(MotionEventButtonState.Forward))
{
modifiers |= RawInputModifiers.XButton2MouseButton;
}
if (buttonState.HasAnyFlag(MotionEventButtonState.StylusPrimary))
{
modifiers |= RawInputModifiers.PenBarrelButton;
}
return modifiers;
}
#pragma warning disable CA1416 // Validate platform compatibility
private static RawPointerEventType GetActionType(MotionEvent e, MotionEventActions actionMasked, MotionEventToolType toolType)
{
var isTouch = toolType == MotionEventToolType.Finger;
var isMouse = toolType == MotionEventToolType.Mouse;
switch (actionMasked)
{
// DOWN
case MotionEventActions.Down when !isMouse:
case MotionEventActions.PointerDown when !isMouse:
return isTouch ? RawPointerEventType.TouchBegin : RawPointerEventType.LeftButtonDown;
case MotionEventActions.ButtonPress:
return e.ActionButton switch
{
MotionEventButtonState.Back => RawPointerEventType.XButton1Down,
MotionEventButtonState.Forward => RawPointerEventType.XButton2Down,
MotionEventButtonState.Primary => RawPointerEventType.LeftButtonDown,
MotionEventButtonState.Secondary => RawPointerEventType.RightButtonDown,
MotionEventButtonState.StylusPrimary => RawPointerEventType.LeftButtonDown,
MotionEventButtonState.StylusSecondary => RawPointerEventType.RightButtonDown,
MotionEventButtonState.Tertiary => RawPointerEventType.MiddleButtonDown,
_ => RawPointerEventType.LeftButtonDown
};
// UP
case MotionEventActions.Up when !isMouse:
case MotionEventActions.PointerUp when !isMouse:
return isTouch ? RawPointerEventType.TouchEnd : RawPointerEventType.LeftButtonUp;
case MotionEventActions.ButtonRelease:
return e.ActionButton switch
{
MotionEventButtonState.Back => RawPointerEventType.XButton1Up,
MotionEventButtonState.Forward => RawPointerEventType.XButton2Up,
MotionEventButtonState.Primary => RawPointerEventType.LeftButtonUp,
MotionEventButtonState.Secondary => RawPointerEventType.RightButtonUp,
MotionEventButtonState.StylusPrimary => RawPointerEventType.LeftButtonUp,
MotionEventButtonState.StylusSecondary => RawPointerEventType.RightButtonUp,
MotionEventButtonState.Tertiary => RawPointerEventType.MiddleButtonUp,
_ => RawPointerEventType.LeftButtonUp
};
// MOVE
case MotionEventActions.Outside:
case MotionEventActions.HoverMove:
case MotionEventActions.Move:
return isTouch ? RawPointerEventType.TouchUpdate : RawPointerEventType.Move;
// CANCEL
case MotionEventActions.Cancel:
return isTouch ? RawPointerEventType.TouchCancel : RawPointerEventType.LeaveWindow;
default:
return (RawPointerEventType)(-1);
}
}
#pragma warning restore CA1416 // Validate platform compatibility
private IPointerDevice GetDevice(MotionEventToolType type)
{
return type switch
{
MotionEventToolType.Mouse => _mouseDevice,
MotionEventToolType.Stylus => _penDevice,
MotionEventToolType.Eraser => _penDevice,
MotionEventToolType.Finger => _touchDevice,
_ => _touchDevice
};
}
private RawPointerPoint CreatePoint(MotionEvent e, int index)
{
return new RawPointerPoint
{
Position = new Point(e.GetX(index), e.GetY(index)) / _view.RenderScaling,
Pressure = Math.Min(e.GetPressure(index), 1), // android pressure can depend on the device, can be mixed up with "GetSize", may be larger than 1.0f on some devices
Twist = e.GetOrientation(index) * s_radiansToDegree
};
}
private RawPointerPoint CreateHistoricalPoint(MotionEvent e, int index, int pos)
{
return new RawPointerPoint
{
Position = new Point(e.GetHistoricalX(index, pos), e.GetHistoricalY(index, pos)) / _view.RenderScaling,
Pressure = Math.Min(e.GetHistoricalPressure(index, pos), 1),
Twist = e.GetHistoricalOrientation(index, pos) * s_radiansToDegree
};
}
private static RawInputModifiers GetToolModifiers(MotionEventToolType toolType)
{
// Android "Eraser" indicates Inverted pen OR actual Eraser. So we have to go both here.
return toolType == MotionEventToolType.Eraser ? RawInputModifiers.PenInverted | RawInputModifiers.PenEraser : RawInputModifiers.None;
}
public void Dispose()
{
_disposed = true;
}
}
}

85
src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs

@ -1,85 +0,0 @@
using System;
using Android.Views;
using Avalonia.Input;
using Avalonia.Input.Raw;
using Avalonia.Platform;
namespace Avalonia.Android.Platform.Specific.Helpers
{
public class AndroidTouchEventsHelper<TView> : IDisposable where TView : ITopLevelImpl, IAndroidView
{
private TView _view;
public bool HandleEvents { get; set; }
public AndroidTouchEventsHelper(TView view, Func<IInputRoot> getInputRoot, Func<MotionEvent, int, Point> getPointfunc)
{
this._view = view;
HandleEvents = true;
_getPointFunc = getPointfunc;
_getInputRoot = getInputRoot;
}
private TouchDevice _touchDevice = new TouchDevice();
private Func<MotionEvent, int, Point> _getPointFunc;
private Func<IInputRoot> _getInputRoot;
public bool? DispatchTouchEvent(MotionEvent e, out bool callBase)
{
if (!HandleEvents)
{
callBase = true;
return null;
}
var eventTime = DateTime.Now;
//Basic touch support
var pointerEventType = e.Action switch
{
MotionEventActions.Down => RawPointerEventType.TouchBegin,
MotionEventActions.Up => RawPointerEventType.TouchEnd,
MotionEventActions.Cancel => RawPointerEventType.TouchCancel,
_ => RawPointerEventType.TouchUpdate
};
if (e.Action.HasFlag(MotionEventActions.PointerDown))
{
pointerEventType = RawPointerEventType.TouchBegin;
}
if (e.Action.HasFlag(MotionEventActions.PointerUp))
{
pointerEventType = RawPointerEventType.TouchEnd;
}
for (int i = 0; i < e.PointerCount; i++)
{
//if point is in view otherwise it's possible avalonia not to find the proper window to dispatch the event
var point = _getPointFunc(e, i);
double x = _view.View.GetX();
double y = _view.View.GetY();
double r = x + _view.View.Width;
double b = y + _view.View.Height;
if (x <= point.X && r >= point.X && y <= point.Y && b >= point.Y)
{
var inputRoot = _getInputRoot();
var mouseEvent = new RawTouchEventArgs(_touchDevice, (uint)eventTime.Ticks, inputRoot,
i == e.ActionIndex ? pointerEventType : RawPointerEventType.TouchUpdate, point, RawInputModifiers.None, e.GetPointerId(i));
_view.Input(mouseEvent);
}
}
callBase = true;
//if return false events for move and up are not received!!!
return e.Action != MotionEventActions.Up;
}
public void Dispose()
{
HandleEvents = false;
}
}
}

4
src/Avalonia.Base/Input/Raw/RawPointerEventArgs.cs

@ -137,9 +137,13 @@ namespace Avalonia.Input.Raw
/// </summary>
public Point Position { get; set; }
/// <inheritdoc cref="PointerPointProperties.Twist" />
public float Twist { get; set; }
/// <inheritdoc cref="PointerPointProperties.Pressure" />
public float Pressure { get; set; }
/// <inheritdoc cref="PointerPointProperties.XTilt" />
public float XTilt { get; set; }
/// <inheritdoc cref="PointerPointProperties.YTilt" />
public float YTilt { get; set; }

15
src/Avalonia.Base/Media/KnownColors.cs

@ -1,10 +1,11 @@
using System;
using System.Reflection;
using System.Collections.Generic;
using Avalonia.SourceGenerator;
namespace Avalonia.Media
{
internal static class KnownColors
internal static partial class KnownColors
{
private static readonly IReadOnlyDictionary<string, KnownColor> _knownColorNames;
private static readonly IReadOnlyDictionary<uint, string> _knownColors;
@ -12,23 +13,25 @@ namespace Avalonia.Media
private static readonly Dictionary<KnownColor, ISolidColorBrush> _knownBrushes;
#endif
[GenerateEnumValueDictionary()]
private static partial Dictionary<string, KnownColor> GetKnownColors();
static KnownColors()
{
var knownColorNames = new Dictionary<string, KnownColor>(StringComparer.OrdinalIgnoreCase);
var knownColors = new Dictionary<uint, string>();
foreach (var field in typeof(KnownColor).GetRuntimeFields())
foreach (var field in GetKnownColors())
{
if (field.FieldType != typeof(KnownColor)) continue;
var knownColor = (KnownColor)field.GetValue(null)!;
var knownColor = field.Value;
if (knownColor == KnownColor.None) continue;
knownColorNames.Add(field.Name, knownColor);
knownColorNames.Add(field.Key, knownColor);
// some known colors have the same value, so use the first
if (!knownColors.ContainsKey((uint)knownColor))
{
knownColors.Add((uint)knownColor, field.Name);
knownColors.Add((uint)knownColor, field.Key);
}
}

15
src/Avalonia.Base/VisualTree/VisualExtensions.cs

@ -413,7 +413,7 @@ namespace Avalonia.VisualTree
Index = index,
ZIndex = element.ZIndex,
})
.OrderBy(x => x, null)
.OrderBy(x => x, ZOrderElement.Comparer)
.Select(x => x.Element!);
}
@ -448,6 +448,19 @@ namespace Avalonia.VisualTree
public int Index { get; set; }
public int ZIndex { get; set; }
class ZOrderComparer : IComparer<ZOrderElement>
{
public int Compare(ZOrderElement? x, ZOrderElement? y)
{
if (ReferenceEquals(x, y)) return 0;
if (ReferenceEquals(null, y)) return 1;
if (ReferenceEquals(null, x)) return -1;
return x.CompareTo(y);
}
}
public static IComparer<ZOrderElement> Comparer { get; } = new ZOrderComparer();
public int CompareTo(ZOrderElement? other)
{
if (other is null)

1
src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj

@ -108,4 +108,5 @@
<PackageReference Include="Microsoft.Build.Framework" Version="15.1.548" PrivateAssets="All" />
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
</ItemGroup>
<Import Project="..\..\build\SourceGenerators.props" />
</Project>

10
src/Avalonia.Controls.DataGrid/Collections/DataGridSortDescription.cs

@ -12,9 +12,6 @@ namespace Avalonia.Collections
{
public virtual string PropertyPath => null;
[Obsolete("Use Direction property to read or override sorting direction.")]
public virtual bool Descending => Direction == ListSortDirection.Descending;
public virtual ListSortDirection Direction => ListSortDirection.Ascending;
public bool HasPropertyPath => !String.IsNullOrEmpty(PropertyPath);
public abstract IComparer<object> Comparer { get; }
@ -254,13 +251,6 @@ namespace Avalonia.Collections
return new DataGridPathSortDescription(propertyPath, direction, null, culture);
}
[Obsolete("Use overload taking a ListSortDirection.")]
public static DataGridSortDescription FromPath(string propertyPath, bool descending, CultureInfo culture = null)
{
return new DataGridPathSortDescription(propertyPath, descending ? ListSortDirection.Descending : ListSortDirection.Ascending, null, culture);
}
public static DataGridSortDescription FromPath(string propertyPath, ListSortDirection direction, IComparer comparer)
{
return new DataGridPathSortDescription(propertyPath, direction, comparer, null);

11
src/Avalonia.Controls/Notifications/WindowNotificationManager.cs

@ -102,15 +102,12 @@ namespace Avalonia.Controls.Notifications
Content = content
};
if (notification != null)
notificationControl.NotificationClosed += (sender, args) =>
{
notificationControl.NotificationClosed += (sender, args) =>
{
notification.OnClose?.Invoke();
notification?.OnClose?.Invoke();
_items?.Remove(sender);
};
}
_items?.Remove(sender);
};
notificationControl.PointerPressed += (sender, args) =>
{

3
src/Avalonia.Dialogs/ManagedFileChooser.cs

@ -36,9 +36,8 @@ namespace Avalonia.Dialogs
if (_quickLinksRoot != null)
{
var isQuickLink = _quickLinksRoot.IsLogicalAncestorOf(e.Source as Control);
#pragma warning disable CS0618 // Type or member is obsolete
if (e.ClickCount == 2 || isQuickLink)
#pragma warning restore CS0618 // Type or member is obsolete
{
if (model.ItemType == ManagedFileChooserItemType.File)
{

319
src/Avalonia.X11/X11Atoms.cs

@ -39,183 +39,176 @@ using static Avalonia.X11.XLib;
namespace Avalonia.X11
{
internal class X11Atoms
internal partial class X11Atoms
{
private readonly IntPtr _display;
// Our atoms
public readonly IntPtr AnyPropertyType = (IntPtr)0;
public readonly IntPtr XA_PRIMARY = (IntPtr)1;
public readonly IntPtr XA_SECONDARY = (IntPtr)2;
public readonly IntPtr XA_ARC = (IntPtr)3;
public readonly IntPtr XA_ATOM = (IntPtr)4;
public readonly IntPtr XA_BITMAP = (IntPtr)5;
public readonly IntPtr XA_CARDINAL = (IntPtr)6;
public readonly IntPtr XA_COLORMAP = (IntPtr)7;
public readonly IntPtr XA_CURSOR = (IntPtr)8;
public readonly IntPtr XA_CUT_BUFFER0 = (IntPtr)9;
public readonly IntPtr XA_CUT_BUFFER1 = (IntPtr)10;
public readonly IntPtr XA_CUT_BUFFER2 = (IntPtr)11;
public readonly IntPtr XA_CUT_BUFFER3 = (IntPtr)12;
public readonly IntPtr XA_CUT_BUFFER4 = (IntPtr)13;
public readonly IntPtr XA_CUT_BUFFER5 = (IntPtr)14;
public readonly IntPtr XA_CUT_BUFFER6 = (IntPtr)15;
public readonly IntPtr XA_CUT_BUFFER7 = (IntPtr)16;
public readonly IntPtr XA_DRAWABLE = (IntPtr)17;
public readonly IntPtr XA_FONT = (IntPtr)18;
public readonly IntPtr XA_INTEGER = (IntPtr)19;
public readonly IntPtr XA_PIXMAP = (IntPtr)20;
public readonly IntPtr XA_POINT = (IntPtr)21;
public readonly IntPtr XA_RECTANGLE = (IntPtr)22;
public readonly IntPtr XA_RESOURCE_MANAGER = (IntPtr)23;
public readonly IntPtr XA_RGB_COLOR_MAP = (IntPtr)24;
public readonly IntPtr XA_RGB_BEST_MAP = (IntPtr)25;
public readonly IntPtr XA_RGB_BLUE_MAP = (IntPtr)26;
public readonly IntPtr XA_RGB_DEFAULT_MAP = (IntPtr)27;
public readonly IntPtr XA_RGB_GRAY_MAP = (IntPtr)28;
public readonly IntPtr XA_RGB_GREEN_MAP = (IntPtr)29;
public readonly IntPtr XA_RGB_RED_MAP = (IntPtr)30;
public readonly IntPtr XA_STRING = (IntPtr)31;
public readonly IntPtr XA_VISUALID = (IntPtr)32;
public readonly IntPtr XA_WINDOW = (IntPtr)33;
public readonly IntPtr XA_WM_COMMAND = (IntPtr)34;
public readonly IntPtr XA_WM_HINTS = (IntPtr)35;
public readonly IntPtr XA_WM_CLIENT_MACHINE = (IntPtr)36;
public readonly IntPtr XA_WM_ICON_NAME = (IntPtr)37;
public readonly IntPtr XA_WM_ICON_SIZE = (IntPtr)38;
public readonly IntPtr XA_WM_NAME = (IntPtr)39;
public readonly IntPtr XA_WM_NORMAL_HINTS = (IntPtr)40;
public readonly IntPtr XA_WM_SIZE_HINTS = (IntPtr)41;
public readonly IntPtr XA_WM_ZOOM_HINTS = (IntPtr)42;
public readonly IntPtr XA_MIN_SPACE = (IntPtr)43;
public readonly IntPtr XA_NORM_SPACE = (IntPtr)44;
public readonly IntPtr XA_MAX_SPACE = (IntPtr)45;
public readonly IntPtr XA_END_SPACE = (IntPtr)46;
public readonly IntPtr XA_SUPERSCRIPT_X = (IntPtr)47;
public readonly IntPtr XA_SUPERSCRIPT_Y = (IntPtr)48;
public readonly IntPtr XA_SUBSCRIPT_X = (IntPtr)49;
public readonly IntPtr XA_SUBSCRIPT_Y = (IntPtr)50;
public readonly IntPtr XA_UNDERLINE_POSITION = (IntPtr)51;
public readonly IntPtr XA_UNDERLINE_THICKNESS = (IntPtr)52;
public readonly IntPtr XA_STRIKEOUT_ASCENT = (IntPtr)53;
public readonly IntPtr XA_STRIKEOUT_DESCENT = (IntPtr)54;
public readonly IntPtr XA_ITALIC_ANGLE = (IntPtr)55;
public readonly IntPtr XA_X_HEIGHT = (IntPtr)56;
public readonly IntPtr XA_QUAD_WIDTH = (IntPtr)57;
public readonly IntPtr XA_WEIGHT = (IntPtr)58;
public readonly IntPtr XA_POINT_SIZE = (IntPtr)59;
public readonly IntPtr XA_RESOLUTION = (IntPtr)60;
public readonly IntPtr XA_COPYRIGHT = (IntPtr)61;
public readonly IntPtr XA_NOTICE = (IntPtr)62;
public readonly IntPtr XA_FONT_NAME = (IntPtr)63;
public readonly IntPtr XA_FAMILY_NAME = (IntPtr)64;
public readonly IntPtr XA_FULL_NAME = (IntPtr)65;
public readonly IntPtr XA_CAP_HEIGHT = (IntPtr)66;
public readonly IntPtr XA_WM_CLASS = (IntPtr)67;
public readonly IntPtr XA_WM_TRANSIENT_FOR = (IntPtr)68;
public IntPtr AnyPropertyType = (IntPtr)0;
public IntPtr XA_PRIMARY = (IntPtr)1;
public IntPtr XA_SECONDARY = (IntPtr)2;
public IntPtr XA_ARC = (IntPtr)3;
public IntPtr XA_ATOM = (IntPtr)4;
public IntPtr XA_BITMAP = (IntPtr)5;
public IntPtr XA_CARDINAL = (IntPtr)6;
public IntPtr XA_COLORMAP = (IntPtr)7;
public IntPtr XA_CURSOR = (IntPtr)8;
public IntPtr XA_CUT_BUFFER0 = (IntPtr)9;
public IntPtr XA_CUT_BUFFER1 = (IntPtr)10;
public IntPtr XA_CUT_BUFFER2 = (IntPtr)11;
public IntPtr XA_CUT_BUFFER3 = (IntPtr)12;
public IntPtr XA_CUT_BUFFER4 = (IntPtr)13;
public IntPtr XA_CUT_BUFFER5 = (IntPtr)14;
public IntPtr XA_CUT_BUFFER6 = (IntPtr)15;
public IntPtr XA_CUT_BUFFER7 = (IntPtr)16;
public IntPtr XA_DRAWABLE = (IntPtr)17;
public IntPtr XA_FONT = (IntPtr)18;
public IntPtr XA_INTEGER = (IntPtr)19;
public IntPtr XA_PIXMAP = (IntPtr)20;
public IntPtr XA_POINT = (IntPtr)21;
public IntPtr XA_RECTANGLE = (IntPtr)22;
public IntPtr XA_RESOURCE_MANAGER = (IntPtr)23;
public IntPtr XA_RGB_COLOR_MAP = (IntPtr)24;
public IntPtr XA_RGB_BEST_MAP = (IntPtr)25;
public IntPtr XA_RGB_BLUE_MAP = (IntPtr)26;
public IntPtr XA_RGB_DEFAULT_MAP = (IntPtr)27;
public IntPtr XA_RGB_GRAY_MAP = (IntPtr)28;
public IntPtr XA_RGB_GREEN_MAP = (IntPtr)29;
public IntPtr XA_RGB_RED_MAP = (IntPtr)30;
public IntPtr XA_STRING = (IntPtr)31;
public IntPtr XA_VISUALID = (IntPtr)32;
public IntPtr XA_WINDOW = (IntPtr)33;
public IntPtr XA_WM_COMMAND = (IntPtr)34;
public IntPtr XA_WM_HINTS = (IntPtr)35;
public IntPtr XA_WM_CLIENT_MACHINE = (IntPtr)36;
public IntPtr XA_WM_ICON_NAME = (IntPtr)37;
public IntPtr XA_WM_ICON_SIZE = (IntPtr)38;
public IntPtr XA_WM_NAME = (IntPtr)39;
public IntPtr XA_WM_NORMAL_HINTS = (IntPtr)40;
public IntPtr XA_WM_SIZE_HINTS = (IntPtr)41;
public IntPtr XA_WM_ZOOM_HINTS = (IntPtr)42;
public IntPtr XA_MIN_SPACE = (IntPtr)43;
public IntPtr XA_NORM_SPACE = (IntPtr)44;
public IntPtr XA_MAX_SPACE = (IntPtr)45;
public IntPtr XA_END_SPACE = (IntPtr)46;
public IntPtr XA_SUPERSCRIPT_X = (IntPtr)47;
public IntPtr XA_SUPERSCRIPT_Y = (IntPtr)48;
public IntPtr XA_SUBSCRIPT_X = (IntPtr)49;
public IntPtr XA_SUBSCRIPT_Y = (IntPtr)50;
public IntPtr XA_UNDERLINE_POSITION = (IntPtr)51;
public IntPtr XA_UNDERLINE_THICKNESS = (IntPtr)52;
public IntPtr XA_STRIKEOUT_ASCENT = (IntPtr)53;
public IntPtr XA_STRIKEOUT_DESCENT = (IntPtr)54;
public IntPtr XA_ITALIC_ANGLE = (IntPtr)55;
public IntPtr XA_X_HEIGHT = (IntPtr)56;
public IntPtr XA_QUAD_WIDTH = (IntPtr)57;
public IntPtr XA_WEIGHT = (IntPtr)58;
public IntPtr XA_POINT_SIZE = (IntPtr)59;
public IntPtr XA_RESOLUTION = (IntPtr)60;
public IntPtr XA_COPYRIGHT = (IntPtr)61;
public IntPtr XA_NOTICE = (IntPtr)62;
public IntPtr XA_FONT_NAME = (IntPtr)63;
public IntPtr XA_FAMILY_NAME = (IntPtr)64;
public IntPtr XA_FULL_NAME = (IntPtr)65;
public IntPtr XA_CAP_HEIGHT = (IntPtr)66;
public IntPtr XA_WM_CLASS = (IntPtr)67;
public IntPtr XA_WM_TRANSIENT_FOR = (IntPtr)68;
public readonly IntPtr EDID;
public IntPtr EDID;
public readonly IntPtr WM_PROTOCOLS;
public readonly IntPtr WM_DELETE_WINDOW;
public readonly IntPtr WM_TAKE_FOCUS;
public readonly IntPtr _NET_SUPPORTED;
public readonly IntPtr _NET_CLIENT_LIST;
public readonly IntPtr _NET_NUMBER_OF_DESKTOPS;
public readonly IntPtr _NET_DESKTOP_GEOMETRY;
public readonly IntPtr _NET_DESKTOP_VIEWPORT;
public readonly IntPtr _NET_CURRENT_DESKTOP;
public readonly IntPtr _NET_DESKTOP_NAMES;
public readonly IntPtr _NET_ACTIVE_WINDOW;
public readonly IntPtr _NET_WORKAREA;
public readonly IntPtr _NET_SUPPORTING_WM_CHECK;
public readonly IntPtr _NET_VIRTUAL_ROOTS;
public readonly IntPtr _NET_DESKTOP_LAYOUT;
public readonly IntPtr _NET_SHOWING_DESKTOP;
public readonly IntPtr _NET_CLOSE_WINDOW;
public readonly IntPtr _NET_MOVERESIZE_WINDOW;
public readonly IntPtr _NET_WM_MOVERESIZE;
public readonly IntPtr _NET_RESTACK_WINDOW;
public readonly IntPtr _NET_REQUEST_FRAME_EXTENTS;
public readonly IntPtr _NET_WM_NAME;
public readonly IntPtr _NET_WM_VISIBLE_NAME;
public readonly IntPtr _NET_WM_ICON_NAME;
public readonly IntPtr _NET_WM_VISIBLE_ICON_NAME;
public readonly IntPtr _NET_WM_DESKTOP;
public readonly IntPtr _NET_WM_WINDOW_TYPE;
public readonly IntPtr _NET_WM_STATE;
public readonly IntPtr _NET_WM_ALLOWED_ACTIONS;
public readonly IntPtr _NET_WM_STRUT;
public readonly IntPtr _NET_WM_STRUT_PARTIAL;
public readonly IntPtr _NET_WM_ICON_GEOMETRY;
public readonly IntPtr _NET_WM_ICON;
public readonly IntPtr _NET_WM_PID;
public readonly IntPtr _NET_WM_HANDLED_ICONS;
public readonly IntPtr _NET_WM_USER_TIME;
public readonly IntPtr _NET_FRAME_EXTENTS;
public readonly IntPtr _NET_WM_PING;
public readonly IntPtr _NET_WM_SYNC_REQUEST;
public readonly IntPtr _NET_WM_SYNC_REQUEST_COUNTER;
public readonly IntPtr _NET_SYSTEM_TRAY_S;
public readonly IntPtr _NET_SYSTEM_TRAY_ORIENTATION;
public readonly IntPtr _NET_SYSTEM_TRAY_OPCODE;
public readonly IntPtr _NET_WM_STATE_MAXIMIZED_HORZ;
public readonly IntPtr _NET_WM_STATE_MAXIMIZED_VERT;
public readonly IntPtr _NET_WM_STATE_FULLSCREEN;
public readonly IntPtr _XEMBED;
public readonly IntPtr _XEMBED_INFO;
public readonly IntPtr _MOTIF_WM_HINTS;
public readonly IntPtr _NET_WM_STATE_SKIP_TASKBAR;
public readonly IntPtr _NET_WM_STATE_ABOVE;
public readonly IntPtr _NET_WM_STATE_MODAL;
public readonly IntPtr _NET_WM_STATE_HIDDEN;
public readonly IntPtr _NET_WM_CONTEXT_HELP;
public readonly IntPtr _NET_WM_WINDOW_OPACITY;
public readonly IntPtr _NET_WM_WINDOW_TYPE_DESKTOP;
public readonly IntPtr _NET_WM_WINDOW_TYPE_DOCK;
public readonly IntPtr _NET_WM_WINDOW_TYPE_TOOLBAR;
public readonly IntPtr _NET_WM_WINDOW_TYPE_MENU;
public readonly IntPtr _NET_WM_WINDOW_TYPE_UTILITY;
public readonly IntPtr _NET_WM_WINDOW_TYPE_SPLASH;
public readonly IntPtr _NET_WM_WINDOW_TYPE_DIALOG;
public readonly IntPtr _NET_WM_WINDOW_TYPE_NORMAL;
public readonly IntPtr CLIPBOARD;
public readonly IntPtr CLIPBOARD_MANAGER;
public readonly IntPtr SAVE_TARGETS;
public readonly IntPtr MULTIPLE;
public readonly IntPtr PRIMARY;
public readonly IntPtr OEMTEXT;
public readonly IntPtr UNICODETEXT;
public readonly IntPtr TARGETS;
public readonly IntPtr UTF8_STRING;
public readonly IntPtr UTF16_STRING;
public readonly IntPtr ATOM_PAIR;
public readonly IntPtr MANAGER;
public readonly IntPtr _KDE_NET_WM_BLUR_BEHIND_REGION;
public readonly IntPtr INCR;
public IntPtr WM_PROTOCOLS;
public IntPtr WM_DELETE_WINDOW;
public IntPtr WM_TAKE_FOCUS;
public IntPtr _NET_SUPPORTED;
public IntPtr _NET_CLIENT_LIST;
public IntPtr _NET_NUMBER_OF_DESKTOPS;
public IntPtr _NET_DESKTOP_GEOMETRY;
public IntPtr _NET_DESKTOP_VIEWPORT;
public IntPtr _NET_CURRENT_DESKTOP;
public IntPtr _NET_DESKTOP_NAMES;
public IntPtr _NET_ACTIVE_WINDOW;
public IntPtr _NET_WORKAREA;
public IntPtr _NET_SUPPORTING_WM_CHECK;
public IntPtr _NET_VIRTUAL_ROOTS;
public IntPtr _NET_DESKTOP_LAYOUT;
public IntPtr _NET_SHOWING_DESKTOP;
public IntPtr _NET_CLOSE_WINDOW;
public IntPtr _NET_MOVERESIZE_WINDOW;
public IntPtr _NET_WM_MOVERESIZE;
public IntPtr _NET_RESTACK_WINDOW;
public IntPtr _NET_REQUEST_FRAME_EXTENTS;
public IntPtr _NET_WM_NAME;
public IntPtr _NET_WM_VISIBLE_NAME;
public IntPtr _NET_WM_ICON_NAME;
public IntPtr _NET_WM_VISIBLE_ICON_NAME;
public IntPtr _NET_WM_DESKTOP;
public IntPtr _NET_WM_WINDOW_TYPE;
public IntPtr _NET_WM_STATE;
public IntPtr _NET_WM_ALLOWED_ACTIONS;
public IntPtr _NET_WM_STRUT;
public IntPtr _NET_WM_STRUT_PARTIAL;
public IntPtr _NET_WM_ICON_GEOMETRY;
public IntPtr _NET_WM_ICON;
public IntPtr _NET_WM_PID;
public IntPtr _NET_WM_HANDLED_ICONS;
public IntPtr _NET_WM_USER_TIME;
public IntPtr _NET_FRAME_EXTENTS;
public IntPtr _NET_WM_PING;
public IntPtr _NET_WM_SYNC_REQUEST;
public IntPtr _NET_WM_SYNC_REQUEST_COUNTER;
public IntPtr _NET_SYSTEM_TRAY_S;
public IntPtr _NET_SYSTEM_TRAY_ORIENTATION;
public IntPtr _NET_SYSTEM_TRAY_OPCODE;
public IntPtr _NET_WM_STATE_MAXIMIZED_HORZ;
public IntPtr _NET_WM_STATE_MAXIMIZED_VERT;
public IntPtr _NET_WM_STATE_FULLSCREEN;
public IntPtr _XEMBED;
public IntPtr _XEMBED_INFO;
public IntPtr _MOTIF_WM_HINTS;
public IntPtr _NET_WM_STATE_SKIP_TASKBAR;
public IntPtr _NET_WM_STATE_ABOVE;
public IntPtr _NET_WM_STATE_MODAL;
public IntPtr _NET_WM_STATE_HIDDEN;
public IntPtr _NET_WM_CONTEXT_HELP;
public IntPtr _NET_WM_WINDOW_OPACITY;
public IntPtr _NET_WM_WINDOW_TYPE_DESKTOP;
public IntPtr _NET_WM_WINDOW_TYPE_DOCK;
public IntPtr _NET_WM_WINDOW_TYPE_TOOLBAR;
public IntPtr _NET_WM_WINDOW_TYPE_MENU;
public IntPtr _NET_WM_WINDOW_TYPE_UTILITY;
public IntPtr _NET_WM_WINDOW_TYPE_SPLASH;
public IntPtr _NET_WM_WINDOW_TYPE_DIALOG;
public IntPtr _NET_WM_WINDOW_TYPE_NORMAL;
public IntPtr CLIPBOARD;
public IntPtr CLIPBOARD_MANAGER;
public IntPtr SAVE_TARGETS;
public IntPtr MULTIPLE;
public IntPtr PRIMARY;
public IntPtr OEMTEXT;
public IntPtr UNICODETEXT;
public IntPtr TARGETS;
public IntPtr UTF8_STRING;
public IntPtr UTF16_STRING;
public IntPtr ATOM_PAIR;
public IntPtr MANAGER;
public IntPtr _KDE_NET_WM_BLUR_BEHIND_REGION;
public IntPtr INCR;
private readonly Dictionary<string, IntPtr> _namesToAtoms = new Dictionary<string, IntPtr>();
private readonly Dictionary<IntPtr, string> _atomsToNames = new Dictionary<IntPtr, string>();
public X11Atoms(IntPtr display)
{
_display = display;
PopulateAtoms(display);
}
// make sure this array stays in sync with the statements below
var fields = typeof(X11Atoms).GetFields()
.Where(f => f.FieldType == typeof(IntPtr) && (IntPtr)f.GetValue(this) == IntPtr.Zero).ToArray();
var atomNames = fields.Select(f => f.Name).ToArray();
IntPtr[] atoms = new IntPtr [atomNames.Length];
;
XInternAtoms(display, atomNames, atomNames.Length, true, atoms);
for (var c = 0; c < fields.Length; c++)
private void InitAtom(ref IntPtr field, string name, IntPtr value)
{
if (value != IntPtr.Zero)
{
_namesToAtoms[fields[c].Name] = atoms[c];
_atomsToNames[atoms[c]] = fields[c].Name;
fields[c].SetValue(this, atoms[c]);
field = value;
_namesToAtoms[name] = value;
_atomsToNames[value] = name;
}
}

8
src/Avalonia.X11/X11CursorFactory.cs

@ -5,13 +5,14 @@ using System.Runtime.InteropServices;
using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Input;
using Avalonia.Platform;
using Avalonia.SourceGenerator;
using Avalonia.Utilities;
#nullable enable
namespace Avalonia.X11
{
class X11CursorFactory : ICursorFactory
partial class X11CursorFactory : ICursorFactory
{
private static readonly byte[] NullCursorData = new byte[] { 0 };
@ -48,11 +49,14 @@ namespace Avalonia.X11
{StandardCursorType.TopRightCorner, CursorFontShape.XC_top_right_corner},
};
[GenerateEnumValueList]
private static partial CursorFontShape[] GetAllCursorShapes();
public X11CursorFactory(IntPtr display)
{
_display = display;
_nullCursor = GetNullCursor(display);
_cursors = Enum.GetValues(typeof(CursorFontShape)).Cast<CursorFontShape>()
_cursors = GetAllCursorShapes()
.ToDictionary(id => id, id => XLib.XCreateFontCursor(_display, id));
}

15
src/Avalonia.X11/X11Platform.cs

@ -278,7 +278,8 @@ namespace Avalonia
"llvmpipe"
};
public string WmClass { get; set; } = Assembly.GetEntryAssembly()?.GetName()?.Name;
public string WmClass { get; set; }
/// <summary>
/// Enables multitouch support. The default value is true.
@ -287,6 +288,18 @@ namespace Avalonia
/// Multitouch allows a surface (a touchpad or touchscreen) to recognize the presence of more than one point of contact with the surface at the same time.
/// </remarks>
public bool? EnableMultiTouch { get; set; } = true;
public X11PlatformOptions()
{
try
{
WmClass = Assembly.GetEntryAssembly()?.GetName()?.Name;
}
catch
{
//
}
}
}
public static class AvaloniaX11PlatformExtensions
{

3
src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs

@ -158,9 +158,6 @@ namespace Avalonia.Markup.Xaml.XamlIl.Runtime
string.Join(",", lst.Select(e => $"`{e.ClrAssemblyName}:{e.ClrNamespace}.{name}`")));
}
}
[Obsolete("Don't use", true)]
public static readonly IServiceProvider RootServiceProviderV1 = new RootServiceProvider(null);
// Don't emit debug symbols for this code so debugger will be forced to step into XAML instead
#line hidden

8
src/Shared/SourceGeneratorAttributes.cs

@ -38,4 +38,12 @@ namespace Avalonia.SourceGenerator
}
}
internal class GenerateEnumValueDictionaryAttribute : Attribute
{
}
internal class GenerateEnumValueListAttribute : Attribute
{
}
}

70
src/Skia/Avalonia.Skia/Helpers/DrawingContextHelper.cs

@ -1,5 +1,4 @@
using System;
using Avalonia.Platform;
using Avalonia.Platform;
using Avalonia.Rendering;
using SkiaSharp;
@ -29,72 +28,5 @@ namespace Avalonia.Skia.Helpers
return new DrawingContextImpl(createInfo);
}
/// <summary>
/// Unsupported - Wraps a GPU Backed SkiaSurface in an Avalonia DrawingContext.
/// </summary>
[Obsolete]
public static IDrawingContextImpl WrapSkiaSurface(this SKSurface surface, GRContext grContext, Vector dpi, params IDisposable[] disposables)
{
var createInfo = new DrawingContextImpl.CreateInfo
{
GrContext = grContext,
Surface = surface,
Dpi = dpi,
DisableTextLcdRendering = false,
};
return new DrawingContextImpl(createInfo, disposables);
}
/// <summary>
/// Unsupported - Wraps a non-GPU Backed SkiaSurface in an Avalonia DrawingContext.
/// </summary>
[Obsolete]
public static IDrawingContextImpl WrapSkiaSurface(this SKSurface surface, Vector dpi, params IDisposable[] disposables)
{
var createInfo = new DrawingContextImpl.CreateInfo
{
Surface = surface,
Dpi = dpi,
DisableTextLcdRendering = false,
};
return new DrawingContextImpl(createInfo, disposables);
}
[Obsolete]
public static IDrawingContextImpl CreateDrawingContext(Size size, Vector dpi, GRContext grContext = null)
{
if (grContext is null)
{
var surface = SKSurface.Create(
new SKImageInfo(
(int)Math.Ceiling(size.Width),
(int)Math.Ceiling(size.Height),
SKImageInfo.PlatformColorType,
SKAlphaType.Premul));
return WrapSkiaSurface(surface, dpi, surface);
}
else
{
var surface = SKSurface.Create(grContext, false,
new SKImageInfo(
(int)Math.Ceiling(size.Width),
(int)Math.Ceiling(size.Height),
SKImageInfo.PlatformColorType,
SKAlphaType.Premul));
return WrapSkiaSurface(surface, grContext, dpi, surface);
}
}
[Obsolete]
public static void DrawTo(this IDrawingContextImpl source, IDrawingContextImpl destination, SKPaint paint = null)
{
var src = (DrawingContextImpl)source;
var dst = (DrawingContextImpl)destination;
dst.Canvas.DrawSurface(src.Surface, new SKPoint(0, 0), paint);
}
}
}

9
src/Windows/Avalonia.Win32/Win32Platform.cs

@ -65,15 +65,6 @@ namespace Avalonia
"Microsoft Basic Render"
};
/// <summary>
/// Enables multitouch support. The default value is true.
/// </summary>
/// <remarks>
/// Multitouch allows a surface (a touchpad or touchscreen) to recognize the presence of more than one point of contact with the surface at the same time.
/// </remarks>
[Obsolete("Multitouch is always enabled on supported Windows versions")]
public bool? EnableMultitouch { get; set; } = true;
/// <summary>
/// Embeds popups to the window when set to true. The default value is false.
/// </summary>

94
src/tools/DevGenerators/EnumMemberDictionaryGenerator.cs

@ -0,0 +1,94 @@
using System.IO;
using System.Linq;
using System.Text;
using Generator;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace DevGenerators;
[Generator(LanguageNames.CSharp)]
public class EnumMemberDictionaryGenerator : IIncrementalGenerator
{
const string DictionaryAttributeFullName = "global::Avalonia.SourceGenerator.GenerateEnumValueDictionaryAttribute";
const string ListAttributeFullName = "global::Avalonia.SourceGenerator.GenerateEnumValueListAttribute";
public void Initialize(IncrementalGeneratorInitializationContext context)
{
var allMethodsWithAttributes = context.SyntaxProvider
.CreateSyntaxProvider(
static (s, _) => s is MethodDeclarationSyntax
{
AttributeLists.Count: > 0,
} md && md.Modifiers.Any(m=>m.IsKind(SyntaxKind.PartialKeyword)),
static (context, _) =>
(IMethodSymbol)context.SemanticModel.GetDeclaredSymbol(context.Node)!);
var all = allMethodsWithAttributes
.Where(s =>
s.HasAttributeWithFullyQualifiedName(DictionaryAttributeFullName)
|| s.HasAttributeWithFullyQualifiedName(ListAttributeFullName)
).Collect();
context.RegisterSourceOutput(all, static (context, methods) =>
{
foreach (var typeGroup in methods.GroupBy(f => f.ContainingType))
{
var classBuilder = new StringBuilder();
if (typeGroup.Key.ContainingNamespace != null)
classBuilder
.AppendLine("using System;")
.Append("namespace ")
.Append(typeGroup.Key.ContainingNamespace)
.AppendLine(";");
classBuilder
.Append("partial class ")
.AppendLine(typeGroup.Key.Name)
.AppendLine("{");
foreach (var method in typeGroup)
{
var namedReturn = method.ReturnType as INamedTypeSymbol;
var arrayReturn = method.ReturnType as IArrayTypeSymbol;
if ((namedReturn != null && namedReturn.Arity > 0) || arrayReturn != null)
{
ITypeSymbol enumType = namedReturn != null
? namedReturn.TypeArguments.Last()
: arrayReturn!.ElementType;
var isDic = method.HasAttributeWithFullyQualifiedName(DictionaryAttributeFullName);
classBuilder
.Pad(1)
.Append("private static partial " + method.ReturnType + " " + method.Name + "()")
.AppendLine().Pad(4).Append(" => new ").Append(method.ReturnType).AppendLine("{");
foreach (var member in enumType.GetMembers())
{
if (member.Name == ".ctor")
continue;
if (isDic)
classBuilder.Pad(2)
.Append("{\"")
.Append(member.Name)
.Append("\", ")
.Append(member.ToString())
.AppendLine("},");
else
classBuilder.Pad(2).Append(member.ToString()).AppendLine(",");
}
classBuilder.Pad(1).AppendLine("};");
}
}
classBuilder.AppendLine("}");
context.AddSource(typeGroup.Key.GetFullyQualifiedName().Replace(":", ""), classBuilder.ToString());
}
});
}
}

73
src/tools/DevGenerators/X11AtomsGenerator.cs

@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using System.Text;
using Generator;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace DevGenerators;
[Generator(LanguageNames.CSharp)]
public class X11AtomsGenerator : IIncrementalGenerator
{
public void Initialize(IncrementalGeneratorInitializationContext context)
{
var x11AtomsClasses = context.SyntaxProvider
.CreateSyntaxProvider(
static (s, _) => s is ClassDeclarationSyntax
{
Identifier.Text: "X11Atoms"
},
static (context, _) =>
(INamedTypeSymbol)context.SemanticModel.GetDeclaredSymbol(context.Node)!);
var all = x11AtomsClasses.Collect();
context.RegisterSourceOutput(all, static (context, classes) =>
{
foreach (var cl in classes)
{
var classBuilder = new StringBuilder();
if (cl.ContainingNamespace != null)
classBuilder
.AppendLine("using System;")
.AppendLine("using static Avalonia.X11.XLib;")
.Append("namespace ")
.Append(cl.ContainingNamespace)
.AppendLine(";");
classBuilder
.Append("partial class ")
.AppendLine(cl.Name)
.AppendLine("{");
var fields = cl.GetMembers().OfType<IFieldSymbol>()
.Where(f => f.Type.Name == "IntPtr"
&& f.DeclaredAccessibility == Accessibility.Public).ToList();
classBuilder.Pad(1).AppendLine("private void PopulateAtoms(IntPtr display)").Pad(1).AppendLine("{");
classBuilder.Pad(2).Append("var atoms = new IntPtr[").Append(fields.Count).AppendLine("];");
classBuilder.Pad(2).Append("var atomNames = new string[").Append(fields.Count).AppendLine("] {");
for (int c = 0; c < fields.Count; c++)
classBuilder.Pad(3).Append("\"").Append(fields[c].Name).AppendLine("\",");
classBuilder.Pad(2).AppendLine("};");
classBuilder.Pad(2).AppendLine("XInternAtoms(display, atomNames, atomNames.Length, true, atoms);");
for (int c = 0; c < fields.Count; c++)
classBuilder.Pad(2).Append("InitAtom(ref ").Append(fields[c].Name).Append(", \"")
.Append(fields[c].Name).Append("\", atoms[").Append(c).AppendLine("]);");
classBuilder.Pad(1).AppendLine("}");
classBuilder.AppendLine("}");
context.AddSource(cl.GetFullyQualifiedName().Replace(":", ""), classBuilder.ToString());
}
});
}
}
Loading…
Cancel
Save