Skip to content

Commit 640d249

Browse files
authored
[X11] Use XcursorLibraryLoadCursor for dnd cursors (#18286)
1 parent 5e7963b commit 640d249

File tree

2 files changed

+32
-14
lines changed

2 files changed

+32
-14
lines changed

src/Avalonia.X11/X11CursorFactory.cs

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ internal partial class X11CursorFactory : ICursorFactory
1515
private static IntPtr _nullCursor;
1616

1717
private readonly IntPtr _display;
18-
private Dictionary<CursorFontShape, IntPtr> _cursors;
18+
private Dictionary<StandardCursorType, IntPtr> _cursors;
1919

2020
private static readonly Dictionary<StandardCursorType, CursorFontShape> s_mapping =
2121
new Dictionary<StandardCursorType, CursorFontShape>
@@ -45,29 +45,29 @@ internal partial class X11CursorFactory : ICursorFactory
4545
{StandardCursorType.TopRightCorner, CursorFontShape.XC_top_right_corner},
4646
};
4747

48+
private static readonly Dictionary<StandardCursorType, string> s_libraryCursors = new()
49+
{
50+
{StandardCursorType.DragCopy, "dnd-copy"},
51+
{StandardCursorType.DragLink, "dnd-link"},
52+
{StandardCursorType.DragMove, "dnd-move"},
53+
// TODO: Check if other platforms have dnd-none, dnd-no-drop and dnd-ask
54+
};
55+
4856
public X11CursorFactory(IntPtr display)
4957
{
5058
_display = display;
5159
_nullCursor = GetNullCursor(display);
5260

53-
// 78 = number of items in CursorFontShape enum
54-
// Unlikely to change, but, do we have a Src Gen for this?
55-
_cursors = new Dictionary<CursorFontShape, IntPtr>(78);
61+
_cursors = new Dictionary<StandardCursorType, IntPtr>();
5662
}
5763

5864
public ICursorImpl GetCursor(StandardCursorType cursorType)
5965
{
6066
IntPtr handle;
6167
if (cursorType == StandardCursorType.None)
62-
{
6368
handle = _nullCursor;
64-
}
6569
else
66-
{
67-
handle = s_mapping.TryGetValue(cursorType, out var shape)
68-
? GetCursorHandleLazy(shape)
69-
: GetCursorHandleLazy(CursorFontShape.XC_left_ptr);
70-
}
70+
handle = GetCursorHandleCached(cursorType);
7171
return new CursorImpl(handle);
7272
}
7373

@@ -139,10 +139,25 @@ public ILockedFramebuffer Lock()
139139
public IFramebufferRenderTarget CreateFramebufferRenderTarget() => new FuncFramebufferRenderTarget(Lock);
140140
}
141141

142-
private nint GetCursorHandleLazy(CursorFontShape shape)
142+
private nint GetCursorHandleCached(StandardCursorType type)
143143
{
144-
if (!_cursors.TryGetValue(shape, out var handle))
145-
_cursors[shape] = handle = XLib.XCreateFontCursor(_display, shape);
144+
if (!_cursors.TryGetValue(type, out var handle))
145+
{
146+
if(s_libraryCursors.TryGetValue(type, out var cursorName))
147+
handle = XLib.XcursorLibraryLoadCursor(_display, cursorName);
148+
else if(s_mapping.TryGetValue(type, out var cursorShape))
149+
handle = XLib.XCreateFontCursor(_display, cursorShape);
150+
151+
if (handle == IntPtr.Zero)
152+
{
153+
if (type != StandardCursorType.Arrow)
154+
handle = GetCursorHandleCached(StandardCursorType.Arrow);
155+
else
156+
handle = _nullCursor;
157+
}
158+
159+
_cursors[type] = handle;
160+
}
146161

147162
return handle;
148163
}

src/Avalonia.X11/XLib.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,9 @@ public static extern int XGetWindowProperty(IntPtr display, IntPtr window, IntPt
329329
[DllImport(libX11)]
330330
public static extern IntPtr XCreateFontCursor(IntPtr display, CursorFontShape shape);
331331

332+
[DllImport(libXCursor)]
333+
public static extern IntPtr XcursorLibraryLoadCursor(IntPtr display, string name);
334+
332335
[DllImport(libX11)]
333336
public static extern IntPtr XCreatePixmapCursor(IntPtr display, IntPtr source, IntPtr mask,
334337
ref XColor foreground_color, ref XColor background_color, int x_hot, int y_hot);

0 commit comments

Comments
 (0)