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{
223
226 return; // Ignore foreign surfaces
227
231
232 QMimeData *dragData = nullptr;
234
237 if (drag) {
240 } else if (m_dragOffer) {
243 }
244
248 if (drag) {
250 }
251
253}
254
256{
257 if (m_dragWindow)
261
263 if (!drag) {
265 }
266}
267
269{
270 Q_UNUSED(time);
273
275
276 if (!drag && !m_dragOffer)
277 return;
278
279 if (!m_dragWindow)
280 return;
281
283
284 QMimeData *dragData = nullptr;
286 if (drag) {
289 } else {
292 }
293
297
298 if (drag) {
300 }
301
303}
304#endif // QT_CONFIG(draganddrop)
305
306void QWaylandDataDevice::data_device_selection(wl_data_offer *id)
307{
308 if (id)
309 m_selectionOffer.reset(static_cast<QWaylandDataOffer *>(wl_data_offer_get_user_data(id)));
310 else
311 m_selectionOffer.reset();
312
313#if QT_CONFIG(clipboard)
314 QGuiApplicationPrivate::platformIntegration()->clipboard()->emitChanged(QClipboard::Clipboard);
315#endif
316}
317
318void QWaylandDataDevice::selectionSourceCancelled()
319{
320 m_selectionSource.reset();
321#if QT_CONFIG(clipboard)
322 QGuiApplicationPrivate::platformIntegration()->clipboard()->emitChanged(QClipboard::Clipboard);
323#endif
324}
325
326#if QT_CONFIG(draganddrop)
328{
331 if (m_toplevelDrag) {
333 m_toplevelDrag = nullptr;
334 }
335}
336
338{
339 QPoint pnt(x, y);
340 if (wnd) {
342 if (wwnd && wwnd->decoration()) {
344 wwnd->decoration()->margins().top());
345 }
346 }
347 return pnt;
348}
349
351{
352 if (response.isAccepted()) {
353 if (version() >= 3)
355
357 } else {
359 }
360}
361
363{
364
366 if (actions & Qt::CopyAction)
370
371 // wayland does not support LinkAction at the time of writing
372 return wlActions;
373}
374
375
376#endif // QT_CONFIG(draganddrop)
377
378}
379
380QT_END_NAMESPACE
381
382#include "moc_qwaylanddatadevice_p.cpp"
QWaylandDataSource * selectionSource() const
QWaylandDataOffer * selectionOffer() const
void setSelectionSource(QWaylandDataSource *source)
Combined button and popup list for selecting options.