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
4
6
10#include "qwaylanddnd_p.h"
15
16#include <QtWaylandClient/private/qwayland-xdg-toplevel-drag-v1.h>
17
18#include <QtCore/QMimeData>
19#include <QtGui/QGuiApplication>
20#include <QtGui/private/qguiapplication_p.h>
21
22#if QT_CONFIG(clipboard)
23#include <qpa/qplatformclipboard.h>
24#endif
25#include <qpa/qplatformdrag.h>
26#include <qpa/qwindowsysteminterface.h>
27
29
30namespace QtWaylandClient {
31
32using namespace Qt::StringLiterals;
33
34QWaylandDataDevice::QWaylandDataDevice(QWaylandDataDeviceManager *manager, QWaylandInputDevice *inputDevice)
35 : QObject(inputDevice)
36 , QtWayland::wl_data_device(manager->get_data_device(inputDevice->wl_seat()))
37 , m_display(manager->display())
38 , m_inputDevice(inputDevice)
39{
40}
41
43{
44 if (version() >= WL_DATA_DEVICE_RELEASE_SINCE_VERSION)
45 release();
46 else
47 wl_data_device_destroy(object());
48}
49
50QWaylandDataOffer *QWaylandDataDevice::selectionOffer() const
51{
52 return m_selectionOffer.data();
53}
54
56{
57 if (m_selectionOffer.isNull())
58 return;
59
60 m_selectionOffer.reset();
61
62#if QT_CONFIG(clipboard)
63 QGuiApplicationPrivate::platformIntegration()->clipboard()->emitChanged(QClipboard::Clipboard);
64#endif
65}
66
67QWaylandDataSource *QWaylandDataDevice::selectionSource() const
68{
69 return m_selectionSource.data();
70}
71
72void QWaylandDataDevice::setSelectionSource(QWaylandDataSource *source)
73{
74 if (source)
75 connect(source, &QWaylandDataSource::cancelled, this, &QWaylandDataDevice::selectionSourceCancelled);
76 set_selection(source ? source->object() : nullptr, m_inputDevice->serial());
77 m_selectionSource.reset(source);
78}
79
80#if QT_CONFIG(draganddrop)
82{
83 return m_dragOffer.data();
84}
85
87{
89
90 if (!origin) {
91 qCDebug(lcQpaWayland) << "Couldn't start a drag because the origin window could not be found.";
92 return false;
93 }
94
95 // dragging data without mimetypes is a legal operation in Qt terms
96 // but Wayland uses a mimetype to determine if a drag is accepted or not
97 // In this rare case, insert a placeholder
98 if (mimeData->formats().isEmpty())
99 mimeData->setData("application/x-qt-avoid-empty-placeholder"_L1, QByteArray("1"));
100
101 static const QString plain = QStringLiteral("text/plain");
102 static const QString utf8 = QStringLiteral("text/plain;charset=utf-8");
103
106
108
109 if (version() >= 3)
111
115 if (!drag->currentDrag()) {
116 return;
117 }
118 // in old versions drop action is not set, so we guess
119 if (m_dragSource->version() < 3) {
121 } else {
124 }
125 });
127 [this](bool accepted, Qt::DropAction action) {
129 if (m_toplevelDrag) {
130 // If the widget was dropped but the drag not accepted it
131 // should be its own window in the future. To distinguish
132 // from canceling mid-drag the drag is accepted here as the
133 // we know if the widget is over a zone where it can be
134 // incorporated or not
136 }
139 });
142 if (m_toplevelDrag) {
144 m_toplevelDrag = nullptr;
145 }
146 });
147
148 if (mimeData->hasFormat("application/x-qt-mainwindowdrag-window"_L1)
152 QDataStream windowStream(mimeData->data("application/x-qt-mainwindowdrag-window"_L1));
154 QWindow *dockWindow = reinterpret_cast<QWindow *>(dockWindowPtr);
155 QDataStream offsetStream(mimeData->data("application/x-qt-mainwindowdrag-position"_L1));
157 if (auto waylandWindow = static_cast<QWaylandWindow *>(dockWindow->handle())) {
161 m_dragSource->object()));
163 }
164 }
165 }
166
168 return true;
169}
170
172{
174}
175#endif
176
177void QWaylandDataDevice::data_device_data_offer(struct ::wl_data_offer *id)
178{
179 new QWaylandDataOffer(m_display, id);
180}
181
182#if QT_CONFIG(draganddrop)
184{
186
187 QMimeData *dragData = nullptr;
189 if (drag) {
192 } else if (m_dragOffer) {
195 } else {
196 return;
197 }
198
202 if (drag) {
205 drag->finishDrag();
206 } else if (m_dragOffer) {
208 }
209}
210
212{
215 return; // Ignore foreign surfaces
216
220
221 QMimeData *dragData = nullptr;
223
226 if (drag) {
229 } else if (m_dragOffer) {
232 }
233
237 if (drag) {
239 }
240
242}
243
245{
246 if (m_dragWindow)
250
252 if (!drag) {
254 }
255}
256
258{
259 Q_UNUSED(time);
260
262
263 if (!drag && !m_dragOffer)
264 return;
265
266 if (!m_dragWindow)
267 return;
268
270
271 QMimeData *dragData = nullptr;
273 if (drag) {
276 } else {
279 }
280
284
285 if (drag) {
287 }
288
290}
291#endif // QT_CONFIG(draganddrop)
292
293void QWaylandDataDevice::data_device_selection(wl_data_offer *id)
294{
295 if (id)
296 m_selectionOffer.reset(static_cast<QWaylandDataOffer *>(wl_data_offer_get_user_data(id)));
297 else
298 m_selectionOffer.reset();
299
300#if QT_CONFIG(clipboard)
301 QGuiApplicationPrivate::platformIntegration()->clipboard()->emitChanged(QClipboard::Clipboard);
302#endif
303}
304
305void QWaylandDataDevice::selectionSourceCancelled()
306{
307 m_selectionSource.reset();
308#if QT_CONFIG(clipboard)
309 QGuiApplicationPrivate::platformIntegration()->clipboard()->emitChanged(QClipboard::Clipboard);
310#endif
311}
312
313#if QT_CONFIG(draganddrop)
315{
318 if (m_toplevelDrag) {
320 m_toplevelDrag = nullptr;
321 }
322}
323
325{
327 if (wnd) {
329 if (wwnd && wwnd->decoration()) {
331 wwnd->decoration()->margins().top());
332 }
333 }
334 return pnt;
335}
336
338{
339 if (response.isAccepted()) {
340 if (version() >= 3)
342
344 } else {
346 }
347}
348
350{
351
353 if (actions & Qt::CopyAction)
357
358 // wayland does not support LinkAction at the time of writing
359 return wlActions;
360}
361
362
363#endif // QT_CONFIG(draganddrop)
364
365}
366
367QT_END_NAMESPACE
368
369#include "moc_qwaylanddatadevice_p.cpp"
QWaylandDataSource * selectionSource() const
QWaylandDataOffer * selectionOffer() const
void setSelectionSource(QWaylandDataSource *source)
Combined button and popup list for selecting options.