Add timeout check for drag&drop on Linux to prevent deadlock

This commit is contained in:
Wojtek Figat
2021-04-23 22:36:56 +02:00
parent 27fbd896f7
commit 23e722a9fb

View File

@@ -1382,6 +1382,7 @@ DragDropEffect LinuxWindow::DoDragDrop(const StringView& data)
X11::Window previousWindow = 0; X11::Window previousWindow = 0;
DragDropEffect result = DragDropEffect::None; DragDropEffect result = DragDropEffect::None;
float lastDraw = Platform::GetTimeSeconds(); float lastDraw = Platform::GetTimeSeconds();
float startTime = lastDraw;
while (true) while (true)
{ {
X11::XNextEvent(xDisplay, &event); X11::XNextEvent(xDisplay, &event);
@@ -1559,7 +1560,7 @@ DragDropEffect LinuxWindow::DoDragDrop(const StringView& data)
if (!(event.xclient.data.l[1]&1) && status != Unaware) if (!(event.xclient.data.l[1]&1) && status != Unaware)
status = Unreceptive; status = Unreceptive;
} }
else if (event.type == ButtonRelease && event.xbutton.button == 1) else if (event.type == ButtonRelease && event.xbutton.button == Button1)
{ {
if (status == CanDrop) if (status == CanDrop)
{ {
@@ -1597,11 +1598,46 @@ DragDropEffect LinuxWindow::DoDragDrop(const StringView& data)
// Redraw // Redraw
const float time = Platform::GetTimeSeconds(); const float time = Platform::GetTimeSeconds();
if (time - lastDraw >= 1.0f / 60.0f) if (time - lastDraw >= 1.0f / 20.0f)
{ {
lastDraw = time; lastDraw = time;
Engine::OnDraw(); Engine::OnDraw();
} }
// Prevent dead-loop
if (time - startTime >= 10.0f)
{
break;
}
}
// Drag end
if (previousWindow != 0 && previousVersion != -1)
{
// Send drag left event
auto ww = WindowsManager::GetByNativePtr((void*)previousWindow);
if (ww)
{
ww->_dragOver = false;
ww->OnDragLeave();
}
else
{
X11::XClientMessageEvent m;
memset(&m, 0, sizeof(m));
m.type = ClientMessage;
m.display = event.xclient.display;
m.window = previousWindow;
m.message_type = xAtomXdndLeave;
m.format = 32;
m.data.l[0] = _window;
m.data.l[1] = 0;
m.data.l[2] = 0;
m.data.l[3] = 0;
m.data.l[4] = 0;
X11::XSendEvent(xDisplay, previousWindow, 0, NoEventMask, (X11::XEvent*)&m);
X11::XFlush(xDisplay);
}
} }
// End grabbing // End grabbing