16#include <QtWaylandClient/private/qwayland-qt-toplevel-drag-v1.h>
18#include <QtCore/QMimeData>
19#include <QtGui/QGuiApplication>
20#include <QtGui/private/qguiapplication_p.h>
22#if QT_CONFIG(clipboard)
23#include <qpa/qplatformclipboard.h>
25#include <qpa/qplatformdrag.h>
26#include <qpa/qwindowsysteminterface.h>
36 ,
QtWayland::wl_data_device(
manager->get_data_device(inputDevice->wl_seat()))
38 , m_inputDevice(inputDevice)
44 if (version() >= WL_DATA_DEVICE_RELEASE_SINCE_VERSION)
50 return m_selectionOffer.data();
55 if (m_selectionOffer.isNull())
58 m_selectionOffer.reset();
60#if QT_CONFIG(clipboard)
67 return m_selectionSource.data();
75 m_selectionSource.reset(
source);
78#if QT_CONFIG(draganddrop)
81 return m_dragOffer.data();
84bool QWaylandDataDevice::startDrag(
QMimeData *
mimeData, Qt::DropActions supportedActions, QWaylandWindow *
icon)
89 origin = seat->touchFocus();
92 qCDebug(lcQpaWayland) <<
"Couldn't start a drag because the origin window could not be found.";
96 m_dragSource.reset(
new QWaylandDataSource(m_display->dndSelectionHandler(),
mimeData));
99 m_dragSource->set_actions(dropActionsToWl(supportedActions));
103 auto drag = static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag());
104 if (!drag->currentDrag()) {
108 if (m_dragSource->version() < 3) {
109 drag->setResponse(accepted);
111 QPlatformDropQtResponse response(accepted, action);
112 drag->setResponse(response);
117 QPlatformDropQtResponse response(accepted, action);
118 if (m_toplevelDrag) {
124 response = { accepted, Qt::MoveAction };
127 ->setDropResponse(response);
129 connect(m_dragSource.data(), &QWaylandDataSource::finished,
this, [
this]() {
130 static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->finishDrag();
131 if (m_toplevelDrag) {
132 m_toplevelDrag->destroy();
133 m_toplevelDrag = nullptr;
138 && m_display->xdgToplevelDragManager()) {
142 windowStream >> dockWindowPtr;
146 if (
auto waylandWindow =
static_cast<QWaylandWindow *
>(dockWindow->handle())) {
147 if (
auto toplevel = waylandWindow->surfaceRole<xdg_toplevel>()) {
148 m_toplevelDrag =
new QtWayland::qt_toplevel_drag_v1(
149 m_display->xdgToplevelDragManager()->get_qt_toplevel_drag(
150 m_dragSource->object()));
151 m_toplevelDrag->attach(toplevel,
offset.x(),
offset.y());
156 start_drag(m_dragSource->object(), origin->wlSurface(),
icon->wlSurface(), m_display->currentInputDevice()->serial());
160void QWaylandDataDevice::cancelDrag()
162 m_dragSource.reset();
166void QWaylandDataDevice::data_device_data_offer(struct ::wl_data_offer *
id)
171#if QT_CONFIG(draganddrop)
172void QWaylandDataDevice::data_device_drop()
177 Qt::DropActions supportedActions;
181 }
else if (m_dragOffer) {
182 dragData = m_dragOffer->mimeData();
183 supportedActions = m_dragOffer->supportedActions();
188 QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(m_dragWindow, dragData, m_dragPoint, supportedActions,
193 drag->setDropResponse(response);
195 }
else if (m_dragOffer) {
196 m_dragOffer->finish();
200void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface, wl_fixed_t
x, wl_fixed_t
y, wl_data_offer *
id)
202 auto *dragWaylandWindow = surface ? QWaylandWindow::fromWlSurface(surface) :
nullptr;
203 if (!dragWaylandWindow)
206 m_dragWindow = dragWaylandWindow->window();
207 m_dragPoint = calculateDragPosition(
x,
y, m_dragWindow);
208 m_enterSerial = serial;
211 Qt::DropActions supportedActions;
213 m_dragOffer.reset(
static_cast<QWaylandDataOffer *
>(wl_data_offer_get_user_data(
id)));
217 }
else if (m_dragOffer) {
218 dragData = m_dragOffer->mimeData();
219 supportedActions = m_dragOffer->supportedActions();
229 sendResponse(supportedActions, response);
232void QWaylandDataDevice::data_device_leave()
245void QWaylandDataDevice::data_device_motion(uint32_t
time, wl_fixed_t
x, wl_fixed_t
y)
251 if (!drag && !m_dragOffer)
254 m_dragPoint = calculateDragPosition(
x,
y, m_dragWindow);
257 Qt::DropActions supportedActions;
262 dragData = m_dragOffer->mimeData();
263 supportedActions = m_dragOffer->supportedActions();
266 const QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(m_dragWindow, dragData, m_dragPoint, supportedActions,
274 sendResponse(supportedActions, response);
278void QWaylandDataDevice::data_device_selection(wl_data_offer *
id)
281 m_selectionOffer.reset(
static_cast<QWaylandDataOffer *
>(wl_data_offer_get_user_data(
id)));
283 m_selectionOffer.reset();
285#if QT_CONFIG(clipboard)
290void QWaylandDataDevice::selectionSourceCancelled()
292 m_selectionSource.reset();
293#if QT_CONFIG(clipboard)
298#if QT_CONFIG(draganddrop)
299void QWaylandDataDevice::dragSourceCancelled()
302 m_dragSource.reset();
303 if (m_toplevelDrag) {
304 m_toplevelDrag->destroy();
305 m_toplevelDrag =
nullptr;
309QPoint QWaylandDataDevice::calculateDragPosition(
int x,
int y,
QWindow *wnd)
const
311 QPoint pnt(wl_fixed_to_int(
x), wl_fixed_to_int(
y));
313 QWaylandWindow *wwnd =
static_cast<QWaylandWindow*
>(m_dragWindow->handle());
314 if (wwnd && wwnd->decoration()) {
315 pnt -=
QPoint(wwnd->decoration()->margins().left(),
316 wwnd->decoration()->margins().top());
322void QWaylandDataDevice::sendResponse(Qt::DropActions supportedActions,
const QPlatformDragQtResponse &response)
326 m_dragOffer->set_actions(dropActionsToWl(supportedActions), dropActionsToWl(response.
acceptedAction()));
328 m_dragOffer->accept(m_enterSerial, m_dragOffer->firstFormat());
330 m_dragOffer->accept(m_enterSerial,
QString());
334int QWaylandDataDevice::dropActionsToWl(Qt::DropActions actions)
337 int wlActions = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
339 wlActions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
341 wlActions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
354#include "moc_qwaylanddatadevice_p.cpp"
\inmodule QtCore\reentrant
QMimeData * mimeData() const
Returns the MIME data that is encapsulated by the drag object.
Qt::DropActions supportedActions() const
Returns the set of possible drop actions for this drag operation.
static QPlatformIntegration * platformIntegration()
static Qt::KeyboardModifiers keyboardModifiers()
Returns the current state of the modifier keys on the keyboard.
static Qt::MouseButtons mouseButtons()
Returns the current state of the buttons on the mouse.
virtual bool hasFormat(const QString &mimetype) const
Returns true if the object can return data for the MIME type specified by mimeType; otherwise returns...
QByteArray data(const QString &mimetype) const
Returns the data stored in the object in the format described by the MIME type specified by mimeType.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
\inmodule QtCore\reentrant
\macro QT_RESTRICTED_CAST_FROM_ASCII
~QWaylandDataDevice() override
QWaylandDataSource * selectionSource() const
QWaylandDataOffer * selectionOffer() const
QWaylandDataDevice(QWaylandDataDeviceManager *manager, QWaylandInputDevice *inputDevice)
void setSelectionSource(QWaylandDataSource *source)
void invalidateSelectionOffer()
void dndDropped(bool accepted, Qt::DropAction action)
void dndResponseUpdated(bool accepted, Qt::DropAction action)
QWaylandInputDevice * currentInputDevice() const
struct wl_display * display
Combined button and popup list for selecting options.
#define qCDebug(category,...)
GLint GLint GLint GLint GLint x
[0]
GLenum GLuint GLintptr offset
GLsizei GLsizei GLchar * source
if(qFloatDistance(a, b)<(1<< 7))
[0]
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)
QNetworkAccessManager manager