Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qwaylanddatadevice.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 Klarälvdalens Datakonsult AB (KDAB).
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5
7
11#include "qwaylanddnd_p.h"
16
17#include <QtWaylandClient/private/qwayland-xdg-toplevel-drag-v1.h>
18
19#include <QtCore/QMimeData>
20#include <QtGui/QGuiApplication>
21#include <QtGui/private/qguiapplication_p.h>
22
23#if QT_CONFIG(clipboard)
24#include <qpa/qplatformclipboard.h>
25#endif
26#include <qpa/qplatformdrag.h>
27#include <qpa/qwindowsysteminterface.h>
28
30
31namespace QtWaylandClient {
32
33using namespace Qt::StringLiterals;
34
35QWaylandDataDevice::QWaylandDataDevice(QWaylandDataDeviceManager *manager, QWaylandInputDevice *inputDevice)
36 : QObject(inputDevice)
37 , QtWayland::wl_data_device(manager->get_data_device(inputDevice->wl_seat()))
38 , m_display(manager->display())
39 , m_inputDevice(inputDevice)
40{
41}
42
44{
45 if (version() >= WL_DATA_DEVICE_RELEASE_SINCE_VERSION)
46 release();
47 else
48 wl_data_device_destroy(object());
49}
50
51QWaylandDataOffer *QWaylandDataDevice::selectionOffer() const
52{
53 return m_selectionOffer.get();
54}
55
57{
58 if (!m_selectionOffer)
59 return;
60
61 m_selectionOffer.reset();
62
63#if QT_CONFIG(clipboard)
64 QGuiApplicationPrivate::platformIntegration()->clipboard()->emitChanged(QClipboard::Clipboard);
65#endif
66}
67
68QWaylandDataSource *QWaylandDataDevice::selectionSource() const
69{
70 return m_selectionSource.get();
71}
72
73void QWaylandDataDevice::setSelectionSource(QWaylandDataSource *source)
74{
75 if (source)
76 connect(source, &QWaylandDataSource::cancelled, this, &QWaylandDataDevice::selectionSourceCancelled);
77 set_selection(source ? source->object() : nullptr, m_inputDevice->serial());
78 m_selectionSource.reset(source);
79}
80
81#if QT_CONFIG(draganddrop)
83{
84 return m_dragOffer.get();
85}
86
88{
90
91 if (!origin) {
92 qCDebug(lcQpaWayland) << "Couldn't start a drag because the origin window could not be found.";
93 return false;
94 }
95
96 // dragging data without mimetypes is a legal operation in Qt terms
97 // but Wayland uses a mimetype to determine if a drag is accepted or not
98 // In this rare case, insert a placeholder
99 if (mimeData->formats().isEmpty())
100 mimeData->setData("application/x-qt-avoid-empty-placeholder"_L1, QByteArray("1"));
101
102 static const QString plain = QStringLiteral("text/plain");
103 static const QString utf8 = QStringLiteral("text/plain;charset=utf-8");
104
107
109
110 if (version() >= 3)
112
116 this, [this](bool accepted, Qt::DropAction action) {
118 if (!drag->currentDrag()) {
119 return;
120 }
121 // in old versions drop action is not set, so we guess
122 if (m_dragSource->version() < 3) {
124 } else {
127 }
128 });
130 this, [this](bool accepted, Qt::DropAction action) {
132 if (m_toplevelDrag) {
133 // If the widget was dropped but the drag not accepted it
134 // should be its own window in the future. To distinguish
135 // from canceling mid-drag the drag is accepted here as the
136 // we know if the widget is over a zone where it can be
137 // incorporated or not
138 response = { true, Qt::MoveAction };
139 }
142 });
143 connect(m_dragSource.get(), &QWaylandDataSource::finished, this, [this]() {
145 if (m_toplevelDrag) {
147 m_toplevelDrag = nullptr;
148 }
149 });
150
151 if (mimeData->hasFormat("application/x-qt-mainwindowdrag-window"_L1)
155 QDataStream windowStream(mimeData->data("application/x-qt-mainwindowdrag-window"_L1));
157 QWindow *dockWindow = reinterpret_cast<QWindow *>(dockWindowPtr);
158 QDataStream offsetStream(mimeData->data("application/x-qt-mainwindowdrag-position"_L1));
160 if (auto waylandWindow = static_cast<QWaylandWindow *>(dockWindow->handle())) {
164 m_dragSource->object()));
166 }
167 }
168 }
169
171 return true;
172}
173
175{
177}
178#endif
179
180void QWaylandDataDevice::data_device_data_offer(struct ::wl_data_offer *id)
181{
182 new QWaylandDataOffer(m_display, id);
183}
184
185#if QT_CONFIG(draganddrop)
187{
189
190 QMimeData *dragData = nullptr;
192 if (drag) {
195 } else if (m_dragOffer) {
198 } else {
199 return;
200 }
201
205
206 // re-evaluate as it could have changed during user code above
208 if (drag) {
212 } else if (m_dragOffer
216 }
217}
218
220{
225 return;
226
229 return; // Ignore foreign surfaces
230
232 m_dragPoint = QPoint(x, y);
234
235 QMimeData *dragData = nullptr;
237
240 if (drag) {
243 } else if (m_dragOffer) {
246 }
247
251 if (drag) {
253 }
254
256}
257
259{
260 if (m_dragWindow)
264
266 if (!drag) {
268 }
269}
270
272{
273 Q_UNUSED(time);
276
278
279 if (!drag && !m_dragOffer)
280 return;
281
282 if (!m_dragWindow)
283 return;
284
285 m_dragPoint = QPoint(x, y);
286
287 QMimeData *dragData = nullptr;
289 if (drag) {
292 } else {
295 }
296
300
301 if (drag) {
303 }
304
306}
307#endif // QT_CONFIG(draganddrop)
308
309void QWaylandDataDevice::data_device_selection(wl_data_offer *id)
310{
311 if (id)
312 m_selectionOffer.reset(static_cast<QWaylandDataOffer *>(wl_data_offer_get_user_data(id)));
313 else
314 m_selectionOffer.reset();
315
316#if QT_CONFIG(clipboard)
317 QGuiApplicationPrivate::platformIntegration()->clipboard()->emitChanged(QClipboard::Clipboard);
318#endif
319}
320
321void QWaylandDataDevice::selectionSourceCancelled()
322{
323 m_selectionSource.reset();
324#if QT_CONFIG(clipboard)
325 QGuiApplicationPrivate::platformIntegration()->clipboard()->emitChanged(QClipboard::Clipboard);
326#endif
327}
328
329#if QT_CONFIG(draganddrop)
331{
334 if (m_toplevelDrag) {
336 m_toplevelDrag = nullptr;
337 }
338}
339
341{
342 if (response.isAccepted()) {
343 if (version() >= 3)
345
347 } else {
349 }
350}
351
353{
354
356 if (actions & Qt::CopyAction)
360
361 // wayland does not support LinkAction at the time of writing
362 return wlActions;
363}
364
365
366#endif // QT_CONFIG(draganddrop)
367
368}
369
370QT_END_NAMESPACE
371
372#include "moc_qwaylanddatadevice_p.cpp"
QWaylandDataSource * selectionSource() const
QWaylandDataOffer * selectionOffer() const
void setSelectionSource(QWaylandDataSource *source)
Combined button and popup list for selecting options.