16#include <QtWaylandClient/private/qwayland-xdg-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)
47 wl_data_device_destroy(
object());
52 return m_selectionOffer.data();
57 if (m_selectionOffer.isNull())
60 m_selectionOffer.reset();
62#if QT_CONFIG(clipboard)
69 return m_selectionSource.data();
77 m_selectionSource.reset(
source);
80#if QT_CONFIG(draganddrop)
83 return m_dragOffer.data();
86bool QWaylandDataDevice::startDrag(
QMimeData *
mimeData, Qt::DropActions supportedActions, QWaylandWindow *
icon)
91 origin = seat->touchFocus();
94 qCDebug(lcQpaWayland) <<
"Couldn't start a drag because the origin window could not be found.";
104 m_dragSource.reset(
new QWaylandDataSource(m_display->dndSelectionHandler(),
mimeData));
107 m_dragSource->set_actions(dropActionsToWl(supportedActions));
111 auto drag = static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag());
112 if (!drag->currentDrag()) {
116 if (m_dragSource->version() < 3) {
117 drag->setResponse(accepted);
119 QPlatformDropQtResponse response(accepted, action);
120 drag->setResponse(response);
125 QPlatformDropQtResponse response(accepted, action);
126 if (m_toplevelDrag) {
132 response = { accepted, Qt::MoveAction };
135 ->setDropResponse(response);
137 connect(m_dragSource.data(), &QWaylandDataSource::finished,
this, [
this]() {
138 static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->finishDrag();
139 if (m_toplevelDrag) {
140 m_toplevelDrag->destroy();
141 m_toplevelDrag = nullptr;
146 && m_display->xdgToplevelDragManager()) {
150 windowStream >> dockWindowPtr;
154 if (
auto waylandWindow =
static_cast<QWaylandWindow *
>(dockWindow->handle())) {
155 if (
auto toplevel = waylandWindow->surfaceRole<xdg_toplevel>()) {
156 m_toplevelDrag =
new QtWayland::xdg_toplevel_drag_v1(
157 m_display->xdgToplevelDragManager()->get_xdg_toplevel_drag(
158 m_dragSource->object()));
159 m_toplevelDrag->attach(toplevel,
offset.x(),
offset.y());
164 start_drag(m_dragSource->object(), origin->wlSurface(),
icon->wlSurface(), m_display->currentInputDevice()->serial());
168void QWaylandDataDevice::cancelDrag()
170 m_dragSource.reset();
174void QWaylandDataDevice::data_device_data_offer(struct ::wl_data_offer *
id)
179#if QT_CONFIG(draganddrop)
180void QWaylandDataDevice::data_device_drop()
185 Qt::DropActions supportedActions;
189 }
else if (m_dragOffer) {
190 dragData = m_dragOffer->mimeData();
191 supportedActions = m_dragOffer->supportedActions();
196 QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(m_dragWindow, dragData, m_dragPoint, supportedActions,
201 drag->setDropResponse(response);
203 }
else if (m_dragOffer) {
204 m_dragOffer->finish();
208void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface, wl_fixed_t
x, wl_fixed_t
y, wl_data_offer *
id)
210 auto *dragWaylandWindow = surface ? QWaylandWindow::fromWlSurface(surface) :
nullptr;
211 if (!dragWaylandWindow)
214 m_dragWindow = dragWaylandWindow->window();
215 m_dragPoint = calculateDragPosition(
x,
y, m_dragWindow);
216 m_enterSerial = serial;
219 Qt::DropActions supportedActions;
221 m_dragOffer.reset(
static_cast<QWaylandDataOffer *
>(wl_data_offer_get_user_data(
id)));
226 }
else if (m_dragOffer) {
227 dragData = m_dragOffer->mimeData();
228 supportedActions = m_dragOffer->supportedActions();
238 sendResponse(supportedActions, response);
241void QWaylandDataDevice::data_device_leave()
254void QWaylandDataDevice::data_device_motion(uint32_t
time, wl_fixed_t
x, wl_fixed_t
y)
260 if (!drag && !m_dragOffer)
263 m_dragPoint = calculateDragPosition(
x,
y, m_dragWindow);
266 Qt::DropActions supportedActions;
271 dragData = m_dragOffer->mimeData();
272 supportedActions = m_dragOffer->supportedActions();
275 const QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(m_dragWindow, dragData, m_dragPoint, supportedActions,
283 sendResponse(supportedActions, response);
287void QWaylandDataDevice::data_device_selection(wl_data_offer *
id)
290 m_selectionOffer.reset(
static_cast<QWaylandDataOffer *
>(wl_data_offer_get_user_data(
id)));
292 m_selectionOffer.reset();
294#if QT_CONFIG(clipboard)
299void QWaylandDataDevice::selectionSourceCancelled()
301 m_selectionSource.reset();
302#if QT_CONFIG(clipboard)
307#if QT_CONFIG(draganddrop)
308void QWaylandDataDevice::dragSourceCancelled()
311 m_dragSource.reset();
312 if (m_toplevelDrag) {
313 m_toplevelDrag->destroy();
314 m_toplevelDrag =
nullptr;
318QPoint QWaylandDataDevice::calculateDragPosition(
int x,
int y,
QWindow *wnd)
const
320 QPoint pnt(wl_fixed_to_int(
x), wl_fixed_to_int(
y));
322 QWaylandWindow *wwnd =
static_cast<QWaylandWindow*
>(m_dragWindow->handle());
323 if (wwnd && wwnd->decoration()) {
324 pnt -=
QPoint(wwnd->decoration()->margins().left(),
325 wwnd->decoration()->margins().top());
331void QWaylandDataDevice::sendResponse(Qt::DropActions supportedActions,
const QPlatformDragQtResponse &response)
335 m_dragOffer->set_actions(dropActionsToWl(supportedActions), dropActionsToWl(response.
acceptedAction()));
337 m_dragOffer->accept(m_enterSerial, m_dragOffer->firstFormat());
339 m_dragOffer->accept(m_enterSerial,
QString());
343int QWaylandDataDevice::dropActionsToWl(Qt::DropActions actions)
346 int wlActions = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
348 wlActions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
350 wlActions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
363#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.
void setData(const QString &mimetype, const QByteArray &data)
Sets the data associated with the MIME type given by mimeType to the specified data.
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.
virtual QStringList formats() const
Returns a list of formats supported by the object.
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.
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
#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