Browse Source

[X11] Use XcursorLibraryLoadCursor for dnd cursors (#18286)

pull/18310/head
Nikita Tsukanov 12 months ago
committed by GitHub
parent
commit
640d249ab7
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 43
      src/Avalonia.X11/X11CursorFactory.cs
  2. 3
      src/Avalonia.X11/XLib.cs

43
src/Avalonia.X11/X11CursorFactory.cs

@ -15,7 +15,7 @@ namespace Avalonia.X11
private static IntPtr _nullCursor;
private readonly IntPtr _display;
private Dictionary<CursorFontShape, IntPtr> _cursors;
private Dictionary<StandardCursorType, IntPtr> _cursors;
private static readonly Dictionary<StandardCursorType, CursorFontShape> s_mapping =
new Dictionary<StandardCursorType, CursorFontShape>
@ -45,29 +45,29 @@ namespace Avalonia.X11
{StandardCursorType.TopRightCorner, CursorFontShape.XC_top_right_corner},
};
private static readonly Dictionary<StandardCursorType, string> s_libraryCursors = new()
{
{StandardCursorType.DragCopy, "dnd-copy"},
{StandardCursorType.DragLink, "dnd-link"},
{StandardCursorType.DragMove, "dnd-move"},
// TODO: Check if other platforms have dnd-none, dnd-no-drop and dnd-ask
};
public X11CursorFactory(IntPtr display)
{
_display = display;
_nullCursor = GetNullCursor(display);
// 78 = number of items in CursorFontShape enum
// Unlikely to change, but, do we have a Src Gen for this?
_cursors = new Dictionary<CursorFontShape, IntPtr>(78);
_cursors = new Dictionary<StandardCursorType, IntPtr>();
}
public ICursorImpl GetCursor(StandardCursorType cursorType)
{
IntPtr handle;
if (cursorType == StandardCursorType.None)
{
handle = _nullCursor;
}
else
{
handle = s_mapping.TryGetValue(cursorType, out var shape)
? GetCursorHandleLazy(shape)
: GetCursorHandleLazy(CursorFontShape.XC_left_ptr);
}
handle = GetCursorHandleCached(cursorType);
return new CursorImpl(handle);
}
@ -139,10 +139,25 @@ namespace Avalonia.X11
public IFramebufferRenderTarget CreateFramebufferRenderTarget() => new FuncFramebufferRenderTarget(Lock);
}
private nint GetCursorHandleLazy(CursorFontShape shape)
private nint GetCursorHandleCached(StandardCursorType type)
{
if (!_cursors.TryGetValue(shape, out var handle))
_cursors[shape] = handle = XLib.XCreateFontCursor(_display, shape);
if (!_cursors.TryGetValue(type, out var handle))
{
if(s_libraryCursors.TryGetValue(type, out var cursorName))
handle = XLib.XcursorLibraryLoadCursor(_display, cursorName);
else if(s_mapping.TryGetValue(type, out var cursorShape))
handle = XLib.XCreateFontCursor(_display, cursorShape);
if (handle == IntPtr.Zero)
{
if (type != StandardCursorType.Arrow)
handle = GetCursorHandleCached(StandardCursorType.Arrow);
else
handle = _nullCursor;
}
_cursors[type] = handle;
}
return handle;
}

3
src/Avalonia.X11/XLib.cs

@ -329,6 +329,9 @@ namespace Avalonia.X11
[DllImport(libX11)]
public static extern IntPtr XCreateFontCursor(IntPtr display, CursorFontShape shape);
[DllImport(libXCursor)]
public static extern IntPtr XcursorLibraryLoadCursor(IntPtr display, string name);
[DllImport(libX11)]
public static extern IntPtr XCreatePixmapCursor(IntPtr display, IntPtr source, IntPtr mask,
ref XColor foreground_color, ref XColor background_color, int x_hot, int y_hot);

Loading…
Cancel
Save