You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
2.9 KiB
77 lines
2.9 KiB
1 month ago
|
From e1a146806873879c380486f084a990936c5fa537 Mon Sep 17 00:00:00 2001
|
||
|
From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
|
||
|
Date: Fri, 10 May 2024 13:20:30 +0200
|
||
|
Subject: [PATCH 58/59] Fix race condition in drag and drop
|
||
|
|
||
|
The data source may be deleted by libwayland while we hold a
|
||
|
reference to it. This could cause crashes when dragging
|
||
|
and dropping repeatedly and very rapidly between two
|
||
|
components.
|
||
|
|
||
|
Tapping into sourceDestroyed() for this as well allows us to
|
||
|
recover more gracefully.
|
||
|
|
||
|
This also required adding some null pointer checks to the code,
|
||
|
since it wasn't really prepared for the data source
|
||
|
disappearing.
|
||
|
|
||
|
Pick-to: 5.15 6.2 6.5 6.7 6.8
|
||
|
Fixes: QTBUG-124502
|
||
|
Change-Id: Ic3df8bf70176c5424ac5c693f8456f61e7b2762b
|
||
|
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
|
||
|
(cherry picked from commit 792bd8510e3bc6b47bcaedfb1386390ce3a10a3a)
|
||
|
---
|
||
|
src/compositor/wayland_wrapper/qwldatadevice.cpp | 15 +++++++++++----
|
||
|
1 file changed, 11 insertions(+), 4 deletions(-)
|
||
|
|
||
|
diff --git a/src/compositor/wayland_wrapper/qwldatadevice.cpp b/src/compositor/wayland_wrapper/qwldatadevice.cpp
|
||
|
index a3a795f9..f301678e 100644
|
||
|
--- a/src/compositor/wayland_wrapper/qwldatadevice.cpp
|
||
|
+++ b/src/compositor/wayland_wrapper/qwldatadevice.cpp
|
||
|
@@ -76,6 +76,9 @@ void DataDevice::sourceDestroyed(DataSource *source)
|
||
|
{
|
||
|
if (m_selectionSource == source)
|
||
|
m_selectionSource = nullptr;
|
||
|
+
|
||
|
+ if (m_dragDataSource == source)
|
||
|
+ m_dragDataSource = nullptr;
|
||
|
}
|
||
|
|
||
|
#if QT_CONFIG(draganddrop)
|
||
|
@@ -105,9 +108,11 @@ void DataDevice::setDragFocus(QWaylandSurface *focus, const QPointF &localPositi
|
||
|
if (m_dragDataSource && !offer)
|
||
|
return;
|
||
|
|
||
|
- send_enter(resource->handle, serial, focus->resource(),
|
||
|
- wl_fixed_from_double(localPosition.x()), wl_fixed_from_double(localPosition.y()),
|
||
|
- offer->resource()->handle);
|
||
|
+ if (offer) {
|
||
|
+ send_enter(resource->handle, serial, focus->resource(),
|
||
|
+ wl_fixed_from_double(localPosition.x()), wl_fixed_from_double(localPosition.y()),
|
||
|
+ offer->resource()->handle);
|
||
|
+ }
|
||
|
|
||
|
m_dragFocus = focus;
|
||
|
m_dragFocusResource = resource;
|
||
|
@@ -139,7 +144,7 @@ void DataDevice::drop()
|
||
|
if (m_dragFocusResource) {
|
||
|
send_drop(m_dragFocusResource->handle);
|
||
|
setDragFocus(nullptr, QPoint());
|
||
|
- } else {
|
||
|
+ } else if (m_dragDataSource) {
|
||
|
m_dragDataSource->cancel();
|
||
|
}
|
||
|
m_dragOrigin = nullptr;
|
||
|
@@ -155,6 +160,8 @@ void DataDevice::data_device_start_drag(Resource *resource, struct ::wl_resource
|
||
|
{
|
||
|
m_dragClient = resource->client();
|
||
|
m_dragDataSource = source ? DataSource::fromResource(source) : nullptr;
|
||
|
+ if (m_dragDataSource)
|
||
|
+ m_dragDataSource->setDevice(this);
|
||
|
m_dragOrigin = QWaylandSurface::fromResource(origin);
|
||
|
QWaylandDrag *drag = m_seat->drag();
|
||
|
setDragIcon(icon ? QWaylandSurface::fromResource(icon) : nullptr);
|
||
|
--
|
||
|
2.46.0
|
||
|
|