Browse Source

Merge pull request #8765 from AvaloniaUI/fixes-remove-some-reflection-2022-08-17-1

Various changes to remove reflection usage
pull/8778/head
Dan Walmsley 4 years ago
committed by GitHub
parent
commit
90670a4460
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 15
      src/Avalonia.Base/Media/KnownColors.cs
  2. 15
      src/Avalonia.Base/VisualTree/VisualExtensions.cs
  3. 1
      src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj
  4. 319
      src/Avalonia.X11/X11Atoms.cs
  5. 8
      src/Avalonia.X11/X11CursorFactory.cs
  6. 15
      src/Avalonia.X11/X11Platform.cs
  7. 8
      src/Shared/SourceGeneratorAttributes.cs
  8. 94
      src/tools/DevGenerators/EnumMemberDictionaryGenerator.cs
  9. 73
      src/tools/DevGenerators/X11AtomsGenerator.cs

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>

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
{

8
src/Shared/SourceGeneratorAttributes.cs

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

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