KWayland

dataoffer.cpp
1 /*
2  SPDX-FileCopyrightText: 2014 Martin Gräßlin <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 #include "dataoffer.h"
7 #include "datadevice.h"
8 #include "wayland_pointer_p.h"
9 // Qt
10 #include <QMimeDatabase>
11 #include <QMimeType>
12 // Wayland
13 #include <wayland-client-protocol.h>
14 
15 namespace KWayland
16 {
17 namespace Client
18 {
19 class Q_DECL_HIDDEN DataOffer::Private
20 {
21 public:
22  Private(wl_data_offer *offer, DataOffer *q);
23  WaylandPointer<wl_data_offer, wl_data_offer_destroy> dataOffer;
25  DataDeviceManager::DnDActions sourceActions = DataDeviceManager::DnDAction::None;
26  DataDeviceManager::DnDAction selectedAction = DataDeviceManager::DnDAction::None;
27 
28 private:
29  void offer(const QString &mimeType);
30  void setAction(DataDeviceManager::DnDAction action);
31  static void offerCallback(void *data, wl_data_offer *dataOffer, const char *mimeType);
32  static void sourceActionsCallback(void *data, wl_data_offer *wl_data_offer, uint32_t source_actions);
33  static void actionCallback(void *data, wl_data_offer *wl_data_offer, uint32_t dnd_action);
34  DataOffer *q;
35 
36  static const struct wl_data_offer_listener s_listener;
37 };
38 
39 #ifndef K_DOXYGEN
40 const struct wl_data_offer_listener DataOffer::Private::s_listener = {offerCallback, sourceActionsCallback, actionCallback};
41 #endif
42 
43 DataOffer::Private::Private(wl_data_offer *offer, DataOffer *q)
44  : q(q)
45 {
46  dataOffer.setup(offer);
47  wl_data_offer_add_listener(offer, &s_listener, this);
48 }
49 
50 void DataOffer::Private::offerCallback(void *data, wl_data_offer *dataOffer, const char *mimeType)
51 {
52  auto d = reinterpret_cast<Private *>(data);
53  Q_ASSERT(d->dataOffer == dataOffer);
54  d->offer(QString::fromUtf8(mimeType));
55 }
56 
57 void DataOffer::Private::offer(const QString &mimeType)
58 {
59  QMimeDatabase db;
60  const auto &m = db.mimeTypeForName(mimeType);
61  if (m.isValid()) {
62  mimeTypes << m;
63  Q_EMIT q->mimeTypeOffered(m.name());
64  }
65 }
66 
67 void DataOffer::Private::sourceActionsCallback(void *data, wl_data_offer *wl_data_offer, uint32_t source_actions)
68 {
69  Q_UNUSED(wl_data_offer)
70  DataDeviceManager::DnDActions actions;
71  if (source_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY) {
72  actions |= DataDeviceManager::DnDAction::Copy;
73  }
74  if (source_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE) {
75  actions |= DataDeviceManager::DnDAction::Move;
76  }
77  if (source_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK) {
78  actions |= DataDeviceManager::DnDAction::Ask;
79  }
80  auto d = reinterpret_cast<Private *>(data);
81  if (d->sourceActions != actions) {
82  d->sourceActions = actions;
83  Q_EMIT d->q->sourceDragAndDropActionsChanged();
84  }
85 }
86 
87 void DataOffer::Private::actionCallback(void *data, wl_data_offer *wl_data_offer, uint32_t dnd_action)
88 {
89  Q_UNUSED(wl_data_offer)
90  auto d = reinterpret_cast<Private *>(data);
91  switch (dnd_action) {
92  case WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY:
93  d->setAction(DataDeviceManager::DnDAction::Copy);
94  break;
95  case WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE:
96  d->setAction(DataDeviceManager::DnDAction::Move);
97  break;
98  case WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK:
99  d->setAction(DataDeviceManager::DnDAction::Ask);
100  break;
101  case WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE:
102  d->setAction(DataDeviceManager::DnDAction::None);
103  break;
104  default:
105  Q_UNREACHABLE();
106  }
107 }
108 
109 void DataOffer::Private::setAction(DataDeviceManager::DnDAction action)
110 {
111  if (action == selectedAction) {
112  return;
113  }
114  selectedAction = action;
115  Q_EMIT q->selectedDragAndDropActionChanged();
116 }
117 
118 DataOffer::DataOffer(DataDevice *parent, wl_data_offer *dataOffer)
119  : QObject(parent)
120  , d(new Private(dataOffer, this))
121 {
122 }
123 
124 DataOffer::~DataOffer()
125 {
126  release();
127 }
128 
130 {
131  d->dataOffer.release();
132 }
133 
134 void DataOffer::destroy()
135 {
136  d->dataOffer.destroy();
137 }
138 
139 bool DataOffer::isValid() const
140 {
141  return d->dataOffer.isValid();
142 }
143 
144 QList<QMimeType> DataOffer::offeredMimeTypes() const
145 {
146  return d->mimeTypes;
147 }
148 
149 void DataOffer::accept(const QMimeType &mimeType, quint32 serial)
150 {
151  accept(mimeType.name(), serial);
152 }
153 
154 void DataOffer::accept(const QString &mimeType, quint32 serial)
155 {
156  wl_data_offer_accept(d->dataOffer, serial, mimeType.toUtf8().constData());
157 }
158 
159 void DataOffer::receive(const QMimeType &mimeType, qint32 fd)
160 {
161  receive(mimeType.name(), fd);
162 }
163 
164 void DataOffer::receive(const QString &mimeType, qint32 fd)
165 {
166  Q_ASSERT(isValid());
167  wl_data_offer_receive(d->dataOffer, mimeType.toUtf8().constData(), fd);
168 }
169 
170 DataOffer::operator wl_data_offer *()
171 {
172  return d->dataOffer;
173 }
174 
175 DataOffer::operator wl_data_offer *() const
176 {
177  return d->dataOffer;
178 }
179 
180 void DataOffer::dragAndDropFinished()
181 {
182  Q_ASSERT(isValid());
183  if (wl_proxy_get_version(d->dataOffer) < WL_DATA_OFFER_FINISH_SINCE_VERSION) {
184  return;
185  }
186  wl_data_offer_finish(d->dataOffer);
187 }
188 
189 DataDeviceManager::DnDActions DataOffer::sourceDragAndDropActions() const
190 {
191  return d->sourceActions;
192 }
193 
194 void DataOffer::setDragAndDropActions(DataDeviceManager::DnDActions supported, DataDeviceManager::DnDAction preferred)
195 {
196  if (wl_proxy_get_version(d->dataOffer) < WL_DATA_OFFER_SET_ACTIONS_SINCE_VERSION) {
197  return;
198  }
199  auto toWayland = [](DataDeviceManager::DnDAction action) {
200  switch (action) {
201  case DataDeviceManager::DnDAction::Copy:
202  return WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
203  case DataDeviceManager::DnDAction::Move:
204  return WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
205  case DataDeviceManager::DnDAction::Ask:
206  return WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
207  case DataDeviceManager::DnDAction::None:
208  return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
209  default:
210  Q_UNREACHABLE();
211  }
212  };
213  uint32_t wlSupported = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
214  if (supported.testFlag(DataDeviceManager::DnDAction::Copy)) {
215  wlSupported |= toWayland(DataDeviceManager::DnDAction::Copy);
216  }
217  if (supported.testFlag(DataDeviceManager::DnDAction::Move)) {
218  wlSupported |= toWayland(DataDeviceManager::DnDAction::Move);
219  }
220  if (supported.testFlag(DataDeviceManager::DnDAction::Ask)) {
221  wlSupported |= toWayland(DataDeviceManager::DnDAction::Ask);
222  }
223  wl_data_offer_set_actions(d->dataOffer, wlSupported, toWayland(preferred));
224 }
225 
226 DataDeviceManager::DnDAction DataOffer::selectedDragAndDropAction() const
227 {
228  return d->selectedAction;
229 }
230 
231 }
232 }
QString fromUtf8(const char *str, int size)
virtual void release(quint64 objid)
bool testFlag(Enum flag) const const
DnDAction
Drag and Drop actions supported by DataSource and DataOffer.
QMimeType mimeTypeForName(const QString &nameOrAlias) const const
QByteArray toUtf8() const const
const char * constData() const const
QStringList mimeTypes(Mode mode=Writing)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Feb 7 2023 03:56:21 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.