Safely end drag if the source data device gets destroyed
We cannot end a drag after the destroyed() signal for the source data device is emitted because DataDeviceInterface and its d pointer are gone by that time.
This commit is contained in:
parent
34982850e2
commit
0613e8f4c9
4 changed files with 17 additions and 16 deletions
|
@ -175,6 +175,7 @@ DataOfferInterface *DataDeviceInterfacePrivate::createDataOffer(AbstractDataSour
|
|||
void DataDeviceInterfacePrivate::data_device_destroy_resource(QtWaylandServer::wl_data_device::Resource *resource)
|
||||
{
|
||||
Q_UNUSED(resource)
|
||||
emit q->aboutToBeDestroyed();
|
||||
delete q;
|
||||
}
|
||||
|
||||
|
|
|
@ -118,6 +118,7 @@ public:
|
|||
wl_client *client();
|
||||
|
||||
Q_SIGNALS:
|
||||
void aboutToBeDestroyed();
|
||||
void dragStarted();
|
||||
void selectionChanged(KWaylandServer::DataSourceInterface*);
|
||||
void selectionCleared();
|
||||
|
|
|
@ -293,20 +293,15 @@ void SeatInterface::Private::registerDataDevice(DataDeviceInterface *dataDevice)
|
|||
}
|
||||
drag.source = dataDevice;
|
||||
drag.sourcePointer = interfaceForSurface(originSurface, pointers);
|
||||
drag.destroyConnection = QObject::connect(dataDevice, &QObject::destroyed, q,
|
||||
drag.destroyConnection = QObject::connect(dataDevice, &DataDeviceInterface::aboutToBeDestroyed, q,
|
||||
[this] {
|
||||
endDrag(display->nextSerial());
|
||||
cancelDrag(display->nextSerial());
|
||||
}
|
||||
);
|
||||
if (dataDevice->dragSource()) {
|
||||
drag.dragSourceDestroyConnection = QObject::connect(dataDevice->dragSource(), &AbstractDataSource::aboutToBeDestroyed, q,
|
||||
[this] {
|
||||
const auto serial = display->nextSerial();
|
||||
if (drag.target) {
|
||||
drag.target->updateDragTarget(nullptr, serial);
|
||||
drag.target = nullptr;
|
||||
}
|
||||
endDrag(serial);
|
||||
cancelDrag(display->nextSerial());
|
||||
}
|
||||
);
|
||||
} else {
|
||||
|
@ -395,6 +390,15 @@ void SeatInterface::Private::registerPrimarySelectionDevice(PrimarySelectionDevi
|
|||
}
|
||||
}
|
||||
|
||||
void SeatInterface::Private::cancelDrag(quint32 serial)
|
||||
{
|
||||
if (drag.target) {
|
||||
drag.target->updateDragTarget(nullptr, serial);
|
||||
drag.target = nullptr;
|
||||
}
|
||||
endDrag(serial);
|
||||
}
|
||||
|
||||
void SeatInterface::Private::endDrag(quint32 serial)
|
||||
{
|
||||
QObject::disconnect(drag.destroyConnection);
|
||||
|
@ -1215,14 +1219,8 @@ void SeatInterface::cancelTouchSequence()
|
|||
(*it)->cancel();
|
||||
}
|
||||
if (d->drag.mode == Private::Drag::Mode::Touch) {
|
||||
// cancel the drag, don't drop.
|
||||
if (d->drag.target) {
|
||||
// remove the current target
|
||||
d->drag.target->updateDragTarget(nullptr, 0);
|
||||
d->drag.target = nullptr;
|
||||
}
|
||||
// and end the drag for the source, serial does not matter
|
||||
d->endDrag(0);
|
||||
// cancel the drag, don't drop. serial does not matter
|
||||
d->cancelDrag(0);
|
||||
}
|
||||
d->globalTouch.ids.clear();
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ public:
|
|||
void registerDataDevice(DataDeviceInterface *dataDevice);
|
||||
void registerDataControlDevice(DataControlDeviceV1Interface *dataDevice);
|
||||
void endDrag(quint32 serial);
|
||||
void cancelDrag(quint32 serial);
|
||||
quint32 nextSerial() const;
|
||||
|
||||
QString name;
|
||||
|
|
Loading…
Reference in a new issue