Fix X11 external drag and drop not releasing consistently

This commit is contained in:
2025-04-02 00:36:06 +03:00
parent 7e59c3b9a7
commit 287eaae850

View File

@@ -471,12 +471,20 @@ namespace X11Impl
return p; return p;
} }
static StringAnsi GetAtomName(X11::Display* display, X11::Atom atom)
{
char* atomNamePtr = X11::XGetAtomName(display, atom);
StringAnsi atomName = StringAnsi(atomNamePtr);
X11::XFree(atomNamePtr);
return atomName;
}
static X11::Atom SelectTargetFromList(X11::Display* display, const char* targetType, X11::Atom* list, int count) static X11::Atom SelectTargetFromList(X11::Display* display, const char* targetType, X11::Atom* list, int count)
{ {
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
X11::Atom atom = list[i]; X11::Atom atom = list[i];
if (atom != 0 && StringAnsi(XGetAtomName(display, atom)) == targetType) if (atom != 0 && GetAtomName(display, atom) == targetType)
return atom; return atom;
} }
return 0; return 0;
@@ -484,11 +492,11 @@ namespace X11Impl
static X11::Atom SelectTargetFromAtoms(X11::Display* display, const char* targetType, X11::Atom t1, X11::Atom t2, X11::Atom t3) static X11::Atom SelectTargetFromAtoms(X11::Display* display, const char* targetType, X11::Atom t1, X11::Atom t2, X11::Atom t3)
{ {
if (t1 != 0 && StringAnsi(XGetAtomName(display, t1)) == targetType) if (t1 != 0 && GetAtomName(display, t1) == targetType)
return t1; return t1;
if (t2 != 0 && StringAnsi(XGetAtomName(display, t2)) == targetType) if (t2 != 0 && GetAtomName(display, t2) == targetType)
return t2; return t2;
if (t3 != 0 && StringAnsi(XGetAtomName(display, t3)) == targetType) if (t3 != 0 && GetAtomName(display, t3) == targetType)
return t3; return t3;
return 0; return 0;
} }
@@ -1164,10 +1172,11 @@ bool SDLCALL SDLPlatform::X11EventHook(void* userdata, _XEvent* xevent)
m.data.l[4] = xAtomXdndActionCopy; m.data.l[4] = xAtomXdndActionCopy;
X11::XSendEvent(xDisplay, event.xclient.data.l[0], 0, NoEventMask, (X11::XEvent*)&m); X11::XSendEvent(xDisplay, event.xclient.data.l[0], 0, NoEventMask, (X11::XEvent*)&m);
X11::XFlush(xDisplay); X11::XFlush(xDisplay);
xDndPos = Float2((float)(event.xclient.data.l[2] >> 16), (float)(event.xclient.data.l[2] & 0xffff)); xDndPos = Float2((float)(event.xclient.data.l[2] >> 16), (float)(event.xclient.data.l[2] & 0xffff));
window = WindowsManager::GetByNativePtr((void*)event.xany.window); window = WindowsManager::GetByNativePtr((void*)event.xany.window);
if (window) if (window)
{ {
xDndPos = window->ScreenToClient(xDndPos);
LinuxDropFilesData dropData; LinuxDropFilesData dropData;
xDndResult = DragDropEffect::None; xDndResult = DragDropEffect::None;
if (window->_dragOver) if (window->_dragOver)
@@ -1194,14 +1203,12 @@ bool SDLCALL SDLPlatform::X11EventHook(void* userdata, _XEvent* xevent)
} }
else if ((uint32)event.xclient.message_type == (uint32)xAtomXdndDrop) else if ((uint32)event.xclient.message_type == (uint32)xAtomXdndDrop)
{ {
auto w = event.xany.window;
if (xDnDRequested != 0) if (xDnDRequested != 0)
{ {
xDndSourceWindow = event.xclient.data.l[0]; xDndSourceWindow = event.xclient.data.l[0];
if (xDnDVersion >= 1) XConvertSelection(xDisplay, xAtomXdndSelection, xDnDRequested, xAtomPrimary,
XConvertSelection(xDisplay, xAtomXdndSelection, xDnDRequested, xAtomPrimary, w, event.xclient.data.l[2]); event.xany.window, xDnDVersion >= 1 ? event.xclient.data.l[2] : CurrentTime);
else X11::XFlush(xDisplay);
XConvertSelection(xDisplay, xAtomXdndSelection, xDnDRequested, xAtomPrimary, w, CurrentTime);
} }
else else
{ {
@@ -1212,7 +1219,7 @@ bool SDLCALL SDLPlatform::X11EventHook(void* userdata, _XEvent* xevent)
m.window = event.xclient.data.l[0]; m.window = event.xclient.data.l[0];
m.message_type = xAtomXdndFinished; m.message_type = xAtomXdndFinished;
m.format = 32; m.format = 32;
m.data.l[0] = w; m.data.l[0] = event.xany.window;
m.data.l[1] = 0; m.data.l[1] = 0;
m.data.l[2] = 0; m.data.l[2] = 0;
X11::XSendEvent(xDisplay, event.xclient.data.l[0], 0, NoEventMask, (X11::XEvent*)&m); X11::XSendEvent(xDisplay, event.xclient.data.l[0], 0, NoEventMask, (X11::XEvent*)&m);