From efbe1c96646a53b2bcdcd18ea48b59c97555e7d3 Mon Sep 17 00:00:00 2001 From: David Redondo Date: Fri, 3 Sep 2021 14:43:06 +0200 Subject: [PATCH] Introduce AbstractDropHandler This abstract class represents an object that receives drag and drop events. This roughly maps to some of DataDevice's receiving methods, but by being abstract also allows us to use the same code from xwayland in a manner transparent to all code paths. Preivous xwayland support with "proxy surfaces" have been removed. -- In future it will be extended to have the mouse move events, so that we can avoid spying on the seat both in dataDevice and kwin's internal filter --- src/wayland/CMakeLists.txt | 2 ++ src/wayland/abstract_drop_handler.cpp | 17 +++++++++++++++++ src/wayland/abstract_drop_handler.h | 26 ++++++++++++++++++++++++++ src/wayland/datadevice_interface.cpp | 6 +----- src/wayland/datadevice_interface.h | 8 +++++--- src/wayland/seat_interface.cpp | 27 ++++++++++++++++++--------- src/wayland/seat_interface.h | 7 +++++-- src/wayland/seat_interface_p.h | 2 +- 8 files changed, 75 insertions(+), 20 deletions(-) create mode 100644 src/wayland/abstract_drop_handler.cpp create mode 100644 src/wayland/abstract_drop_handler.h 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;