diff --git a/src/wayland/CMakeLists.txt b/src/wayland/CMakeLists.txt index 3ddd4fa056..ddd8cef3dc 100644 --- a/src/wayland/CMakeLists.txt +++ b/src/wayland/CMakeLists.txt @@ -1,5 +1,6 @@ set(SERVER_LIB_SRCS abstract_data_source.cpp + abstract_drop_handler.cpp appmenu_interface.cpp blur_interface.cpp clientbuffer.cpp @@ -319,6 +320,7 @@ install(TARGETS KWaylandServer EXPORT KWaylandServerTargets ${KF5_INSTALL_TARGET set(SERVER_LIB_HEADERS ${CMAKE_CURRENT_BINARY_DIR}/KWaylandServer/kwaylandserver_export.h abstract_data_source.h + abstract_drop_handler.h appmenu_interface.h blur_interface.h clientbuffer.h diff --git a/src/wayland/abstract_drop_handler.cpp b/src/wayland/abstract_drop_handler.cpp new file mode 100644 index 0000000000..a5611d2139 --- /dev/null +++ b/src/wayland/abstract_drop_handler.cpp @@ -0,0 +1,17 @@ +/* + SPDX-FileCopyrightText: 2020 David Edmundson + SPDX-FileCopyrightText: 2021 David Redondo + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "abstract_drop_handler.h" + +namespace KWaylandServer +{ +AbstractDropHandler::AbstractDropHandler(QObject *parent) + : QObject(parent) +{ +} + +} diff --git a/src/wayland/abstract_drop_handler.h b/src/wayland/abstract_drop_handler.h new file mode 100644 index 0000000000..466fa2ee09 --- /dev/null +++ b/src/wayland/abstract_drop_handler.h @@ -0,0 +1,26 @@ +/* + SPDX-FileCopyrightText: 2020 David Edmundson + SPDX-FileCopyrightText: 2021 David Redondo + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#pragma once + +#include + +#include + +namespace KWaylandServer +{ +class SurfaceInterface; + +class KWAYLANDSERVER_EXPORT AbstractDropHandler : public QObject +{ + Q_OBJECT +public: + AbstractDropHandler(QObject *parent = nullptr); + virtual void updateDragTarget(SurfaceInterface *surface, quint32 serial) = 0; + virtual void drop() = 0; +}; +} diff --git a/src/wayland/datadevice_interface.cpp b/src/wayland/datadevice_interface.cpp index 6211f8d013..b182d602ac 100644 --- a/src/wayland/datadevice_interface.cpp +++ b/src/wayland/datadevice_interface.cpp @@ -91,10 +91,6 @@ void DataDeviceInterfacePrivate::data_device_start_drag(Resource *resource, dataSource = DataSourceInterface::get(sourceResource); } - if (proxyRemoteSurface) { - // origin is a proxy surface - focusSurface = proxyRemoteSurface.data(); - } const bool pointerGrab = seat->hasImplicitPointerGrab(serial) && seat->focusedPointerSurface() == focusSurface; if (!pointerGrab) { // Client doesn't have pointer grab. @@ -171,7 +167,7 @@ void DataDeviceInterfacePrivate::data_device_destroy_resource(QtWaylandServer::w } DataDeviceInterface::DataDeviceInterface(SeatInterface *seat, wl_resource *resource) - : QObject(nullptr) + : AbstractDropHandler(nullptr) , d(new DataDeviceInterfacePrivate(seat, this, resource)) { SeatInterfacePrivate *seatPrivate = SeatInterfacePrivate::get(seat); diff --git a/src/wayland/datadevice_interface.h b/src/wayland/datadevice_interface.h index d57e92e58e..9f8b46fa79 100644 --- a/src/wayland/datadevice_interface.h +++ b/src/wayland/datadevice_interface.h @@ -11,6 +11,8 @@ #include +#include "abstract_drop_handler.h" + struct wl_client; struct wl_resource; @@ -65,7 +67,7 @@ private: * @see SeatInterface * @see DataSourceInterface */ -class KWAYLANDSERVER_EXPORT DataDeviceInterface : public QObject +class KWAYLANDSERVER_EXPORT DataDeviceInterface : public AbstractDropHandler { Q_OBJECT public: @@ -80,7 +82,7 @@ public: /** * The event is sent when a drag-and-drop operation is ended because the implicit grab is removed. */ - void drop(); + void drop() override; /** * Updates the SurfaceInterface to which drag motion events are sent. * @@ -92,7 +94,7 @@ public: * @param surface The SurfaceInterface which gets motion events * @param serial The serial to be used for enter/leave */ - void updateDragTarget(SurfaceInterface *surface, quint32 serial); + void updateDragTarget(SurfaceInterface *surface, quint32 serial) override; void updateProxy(SurfaceInterface *remote); wl_client *client(); diff --git a/src/wayland/seat_interface.cpp b/src/wayland/seat_interface.cpp index 831e4256fa..4c73f43b0d 100644 --- a/src/wayland/seat_interface.cpp +++ b/src/wayland/seat_interface.cpp @@ -189,6 +189,15 @@ void SeatInterfacePrivate::registerDataDevice(DataDeviceInterface *dataDevice) } } +KWaylandServer::AbstractDropHandler *SeatInterface::dropHandlerForSurface(SurfaceInterface *surface) const +{ + auto list = d->dataDevicesForSurface(surface); + if (list.isEmpty()) { + return nullptr; + }; + return list.first(); +} + void SeatInterfacePrivate::registerDataControlDevice(DataControlDeviceV1Interface *dataDevice) { Q_ASSERT(dataDevice->seat() == q); @@ -275,7 +284,7 @@ void SeatInterfacePrivate::endDrag(quint32 serial) { QObject::disconnect(drag.dragSourceDestroyConnection); - DataDeviceInterface *dragTargetDevice = drag.target; + AbstractDropHandler *dragTargetDevice = drag.target.data(); AbstractDataSource *dragSource = drag.source; if (dragSource) { // TODO: Also check the current drag-and-drop action. @@ -487,7 +496,10 @@ void SeatInterface::setTimestamp(quint32 time) Q_EMIT timestampChanged(time); } -void SeatInterface::setDragTarget(SurfaceInterface *surface, const QPointF &globalPosition, const QMatrix4x4 &inputTransformation) +void SeatInterface::setDragTarget(AbstractDropHandler *dropTarget, + SurfaceInterface *surface, + const QPointF &globalPosition, + const QMatrix4x4 &inputTransformation) { if (surface == d->drag.surface) { // no change @@ -501,10 +513,7 @@ void SeatInterface::setDragTarget(SurfaceInterface *surface, const QPointF &glob // TODO: technically we can have mulitple data devices // and we should send the drag to all of them, but that seems overly complicated // in practice so far the only case for mulitple data devices is for clipboard overriding - d->drag.target = nullptr; - if (d->dataDevicesForSurface(surface).size() > 0) { - d->drag.target = d->dataDevicesForSurface(surface).first(); - } + d->drag.target = dropTarget; if (d->drag.mode == SeatInterfacePrivate::Drag::Mode::Pointer) { notifyPointerMotion(globalPosition); @@ -523,13 +532,13 @@ void SeatInterface::setDragTarget(SurfaceInterface *surface, const QPointF &glob return; } -void SeatInterface::setDragTarget(SurfaceInterface *surface, const QMatrix4x4 &inputTransformation) +void SeatInterface::setDragTarget(AbstractDropHandler *target, SurfaceInterface *surface, const QMatrix4x4 &inputTransformation) { if (d->drag.mode == SeatInterfacePrivate::Drag::Mode::Pointer) { - setDragTarget(surface, pointerPos(), inputTransformation); + setDragTarget(target, surface, pointerPos(), inputTransformation); } else { Q_ASSERT(d->drag.mode == SeatInterfacePrivate::Drag::Mode::Touch); - setDragTarget(surface, d->globalTouch.focus.firstTouchPos, inputTransformation); + setDragTarget(target, surface, d->globalTouch.focus.firstTouchPos, inputTransformation); } } diff --git a/src/wayland/seat_interface.h b/src/wayland/seat_interface.h index 62da215f41..13eaeeaf20 100644 --- a/src/wayland/seat_interface.h +++ b/src/wayland/seat_interface.h @@ -18,6 +18,7 @@ struct wl_resource; namespace KWaylandServer { class AbstractDataSource; +class AbstractDropHandler; class DragAndDropIcon; class DataDeviceInterface; class Display; @@ -216,16 +217,18 @@ public: * Sends a drag leave event to the current target and an enter event to @p surface. * The enter position is derived from @p globalPosition and transformed by @p inputTransformation. */ - void setDragTarget(SurfaceInterface *surface, const QPointF &globalPosition, const QMatrix4x4 &inputTransformation); + void setDragTarget(AbstractDropHandler *dropTarget, SurfaceInterface *surface, const QPointF &globalPosition, const QMatrix4x4 &inputTransformation); /** * Sets the current drag target to @p surface. * * Sends a drag leave event to the current target and an enter event to @p surface. * The enter position is derived from current global position and transformed by @p inputTransformation. */ - void setDragTarget(SurfaceInterface *surface, const QMatrix4x4 &inputTransformation = QMatrix4x4()); + void setDragTarget(AbstractDropHandler *dropTarget, SurfaceInterface *surface, const QMatrix4x4 &inputTransformation = QMatrix4x4()); ///@} + AbstractDropHandler *dropHandlerForSurface(SurfaceInterface *surface) const; + /** * @name Pointer related methods */ diff --git a/src/wayland/seat_interface_p.h b/src/wayland/seat_interface_p.h index 78992968f4..00190a5565 100644 --- a/src/wayland/seat_interface_p.h +++ b/src/wayland/seat_interface_p.h @@ -123,7 +123,7 @@ public: Mode mode = Mode::None; AbstractDataSource *source = nullptr; QPointer surface; - QPointer target; + QPointer target; QPointer dragIcon; QMatrix4x4 transformation; quint32 dragImplicitGrabSerial = -1;