diff --git a/src/wayland/datadevice_interface.cpp b/src/wayland/datadevice_interface.cpp index e1b627ff0b..36b74225e9 100644 --- a/src/wayland/datadevice_interface.cpp +++ b/src/wayland/datadevice_interface.cpp @@ -212,6 +212,25 @@ void DataDeviceInterface::drop() d->drag.surface = nullptr; } +static DataDeviceManagerInterface::DnDAction chooseDndAction(AbstractDataSource *source, DataOfferInterface *offer) +{ + if (offer->preferredDragAndDropAction().has_value()) { + if (source->supportedDragAndDropActions().testFlag(*offer->preferredDragAndDropAction())) { + return *offer->preferredDragAndDropAction(); + } + } + + if (offer->supportedDragAndDropActions().has_value()) { + for (const auto &action : {DataDeviceManagerInterface::DnDAction::Copy, DataDeviceManagerInterface::DnDAction::Move, DataDeviceManagerInterface::DnDAction::Ask}) { + if (source->supportedDragAndDropActions().testFlag(action) && offer->supportedDragAndDropActions()->testFlag(action)) { + return action; + } + } + } + + return DataDeviceManagerInterface::DnDAction::None; +} + void DataDeviceInterface::updateDragTarget(SurfaceInterface *surface, quint32 serial) { if (d->drag.surface) { @@ -291,21 +310,7 @@ void DataDeviceInterface::updateDragTarget(SurfaceInterface *surface, quint32 se if (offer) { offer->sendSourceActions(); auto matchOffers = [dragSource, offer] { - DataDeviceManagerInterface::DnDAction action{DataDeviceManagerInterface::DnDAction::None}; - if (dragSource->supportedDragAndDropActions().testFlag(offer->preferredDragAndDropAction())) { - action = offer->preferredDragAndDropAction(); - } else { - if (dragSource->supportedDragAndDropActions().testFlag(DataDeviceManagerInterface::DnDAction::Copy) - && offer->supportedDragAndDropActions().testFlag(DataDeviceManagerInterface::DnDAction::Copy)) { - action = DataDeviceManagerInterface::DnDAction::Copy; - } else if (dragSource->supportedDragAndDropActions().testFlag(DataDeviceManagerInterface::DnDAction::Move) - && offer->supportedDragAndDropActions().testFlag(DataDeviceManagerInterface::DnDAction::Move)) { - action = DataDeviceManagerInterface::DnDAction::Move; - } else if (dragSource->supportedDragAndDropActions().testFlag(DataDeviceManagerInterface::DnDAction::Ask) - && offer->supportedDragAndDropActions().testFlag(DataDeviceManagerInterface::DnDAction::Ask)) { - action = DataDeviceManagerInterface::DnDAction::Ask; - } - } + const DataDeviceManagerInterface::DnDAction action = chooseDndAction(dragSource, offer); offer->dndAction(action); dragSource->dndAction(action); }; diff --git a/src/wayland/dataoffer_interface.cpp b/src/wayland/dataoffer_interface.cpp index d78abecae2..d8119e816e 100644 --- a/src/wayland/dataoffer_interface.cpp +++ b/src/wayland/dataoffer_interface.cpp @@ -25,8 +25,8 @@ public: DataOfferInterface *q; QPointer source; - DataDeviceManagerInterface::DnDActions supportedDnDActions = DataDeviceManagerInterface::DnDAction::None; - DataDeviceManagerInterface::DnDAction preferredDnDAction = DataDeviceManagerInterface::DnDAction::None; + std::optional supportedDnDActions = std::nullopt; + std::optional preferredDnDAction = std::nullopt; protected: void data_offer_destroy_resource(Resource *resource) override; @@ -182,12 +182,12 @@ wl_resource *DataOfferInterface::resource() const return d->resource()->handle; } -DataDeviceManagerInterface::DnDActions DataOfferInterface::supportedDragAndDropActions() const +std::optional DataOfferInterface::supportedDragAndDropActions() const { return d->supportedDnDActions; } -DataDeviceManagerInterface::DnDAction DataOfferInterface::preferredDragAndDropAction() const +std::optional DataOfferInterface::preferredDragAndDropAction() const { return d->preferredDnDAction; } diff --git a/src/wayland/dataoffer_interface.h b/src/wayland/dataoffer_interface.h index a147173c28..9b8647a4a9 100644 --- a/src/wayland/dataoffer_interface.h +++ b/src/wayland/dataoffer_interface.h @@ -12,6 +12,8 @@ #include "datadevicemanager_interface.h" +#include + namespace KWaylandServer { class DataDeviceInterface; @@ -35,12 +37,12 @@ public: /** * @returns The Drag and Drop actions supported by this DataOfferInterface. */ - DataDeviceManagerInterface::DnDActions supportedDragAndDropActions() const; + std::optional supportedDragAndDropActions() const; /** * @returns The preferred Drag and Drop action of this DataOfferInterface. */ - DataDeviceManagerInterface::DnDAction preferredDragAndDropAction() const; + std::optional preferredDragAndDropAction() const; /** * This event indicates the @p action selected by the compositor after matching the