Skip to content

Commit dadcfd0

Browse files
kekekeksMrJul
authored andcommitted
[X11] Use XcursorLibraryLoadCursor for dnd cursors (#18286)
1 parent 5a57b1e commit dadcfd0

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
@@ -17,7 +17,7 @@ internal partial class X11CursorFactory : ICursorFactory
1717
private static IntPtr _nullCursor;
1818

1919
private readonly IntPtr _display;
20-
private Dictionary<CursorFontShape, IntPtr> _cursors;
20+
private Dictionary<StandardCursorType, IntPtr> _cursors;
2121

2222
private static readonly Dictionary<StandardCursorType, CursorFontShape> s_mapping =
2323
new Dictionary<StandardCursorType, CursorFontShape>
@@ -47,29 +47,29 @@ internal partial class X11CursorFactory : ICursorFactory
4747
{StandardCursorType.TopRightCorner, CursorFontShape.XC_top_right_corner},
4848
};
4949

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

55-
// 78 = number of items in CursorFontShape enum
56-
// Unlikely to change, but, do we have a Src Gen for this?
57-
_cursors = new Dictionary<CursorFontShape, IntPtr>(78);
63+
_cursors = new Dictionary<StandardCursorType, IntPtr>();
5864
}
5965

6066
public ICursorImpl GetCursor(StandardCursorType cursorType)
6167
{
6268
IntPtr handle;
6369
if (cursorType == StandardCursorType.None)
64-
{
6570
handle = _nullCursor;
66-
}
6771
else
68-
{
69-
handle = s_mapping.TryGetValue(cursorType, out var shape)
70-
? GetCursorHandleLazy(shape)
71-
: GetCursorHandleLazy(CursorFontShape.XC_left_ptr);
72-
}
72+
handle = GetCursorHandleCached(cursorType);
7373
return new CursorImpl(handle);
7474
}
7575

@@ -141,10 +141,25 @@ public ILockedFramebuffer Lock()
141141
public IFramebufferRenderTarget CreateFramebufferRenderTarget() => new FuncFramebufferRenderTarget(Lock);
142142
}
143143

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

149164
return handle;
150165
}

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)