11#include <qpa/qwindowsysteminterface.h>
13#include <QtCore/private/qstdweb_p.h>
14#include <QtCore/qeventloop.h>
15#include <QtCore/qmimedata.h>
16#include <QtCore/qtimer.h>
32 if (drag->
source()->metaObject()->indexOfMethod(
"_q_closestWindowHandle()") == -1)
55 emscripten::val generateDefaultDragImage();
56 emscripten::val generateDragImageFromPixmap(
const QPixmap &
pixmap);
58 emscripten::val m_imageDomElement;
59 emscripten::val m_temporaryImageElementParent;
96 m_dragState = std::make_unique<DragState>(
drag,
window, [&loop]() { loop.
quit(); });
98 dragResult = m_dragState->dropAction;
111 "The event is not a DragStart event");
113 if (!m_dragState || m_dragState->window !=
event->targetWindow) {
114 event->cancelDragStart();
118 m_dragState->dragImage = std::make_unique<DragState::DragImage>(
119 m_dragState->drag->pixmap(), m_dragState->drag->mimeData(),
event->targetWindow);
120 event->dataTransfer.setDragImage(m_dragState->dragImage->htmlElement(),
121 m_dragState->drag->hotSpot());
122 event->dataTransfer.setDataFromMimeData(*m_dragState->drag->mimeData());
127 auto mimeDataPreview =
event->dataTransfer.toMimeDataPreview();
129 const Qt::DropActions actions = m_dragState
130 ? m_dragState->drag->supportedActions()
134 const auto dragResponse = QWindowSystemInterface::handleDrag(
135 event->targetWindow, &*mimeDataPreview,
event->pointInPage.toPoint(), actions,
137 event->acceptDragOver();
138 if (dragResponse.isAccepted()) {
139 event->dataTransfer.setDropAction(dragResponse.acceptedAction());
150 event->target(), wasmWindow->platformScreen()->element(),
event->localPoint);
151 const auto screenPos =
152 wasmWindow->platformScreen()->mapFromLocal(screenElementPos);
153 const QPoint targetWindowPos =
event->targetWindow->mapFromGlobal(screenPos).toPoint();
155 const Qt::DropActions actions = m_dragState
156 ? m_dragState->drag->supportedActions()
160 QFlags<Qt::KeyboardModifier>
modifiers =
event->modifiers;
167 const auto dropCallback = [&m_dragState = m_dragState, wasmWindow, targetWindowPos,
171 *dropResponse = QWindowSystemInterface::handleDrop(wasmWindow->window(),
mimeData,
172 targetWindowPos, actions,
175 if (dropResponse->isAccepted())
176 m_dragState->dropAction = dropResponse->acceptedAction();
181 event->dataTransfer.toMimeDataWithFile(dropCallback);
186 m_dragState->dropAction =
event->dropAction;
187 m_dragState->quitEventLoopClosure();
192 : m_temporaryImageElementParent(
QWasmWindow::fromWindow(
window)->containerElement())
196 m_imageDomElement.set(
"className",
"hidden-drag-image");
197 m_temporaryImageElementParent.call<
void>(
"appendChild", m_imageDomElement);
202 m_temporaryImageElementParent.call<
void>(
"removeChild", m_imageDomElement);
205emscripten::val QWasmDrag::DragState::DragImage::generateDragImage(
const QPixmap &
pixmap,
209 return generateDragImageFromPixmap(
pixmap);
211 return generateDragImageFromText(
mimeData);
212 return generateDefaultDragImage();
216QWasmDrag::DragState::DragImage::generateDragImageFromText(
const QMimeData *
mimeData)
218 emscripten::val dragImageElement =
219 emscripten::val::global(
"document")
220 .call<emscripten::val>(
"createElement", emscripten::val(
"span"));
222 constexpr qsizetype MaxCharactersInDragImage = 100;
225 dragImageElement.set(
228 return dragImageElement;
231emscripten::val QWasmDrag::DragState::DragImage::generateDefaultDragImage()
233 emscripten::val dragImageElement =
234 emscripten::val::global(
"document")
235 .call<emscripten::val>(
"createElement", emscripten::val(
"div"));
237 auto innerImgElement = emscripten::val::global(
"document")
238 .call<emscripten::val>(
"createElement", emscripten::val(
"img"));
239 innerImgElement.set(
"src",
240 "data:image/" + std::string(
"svg+xml") +
";base64,"
244 constexpr char DragImageSize[] =
"50px";
246 dragImageElement[
"style"].set(
"width", DragImageSize);
247 innerImgElement[
"style"].set(
"width", DragImageSize);
248 dragImageElement[
"style"].set(
"display",
"flex");
250 dragImageElement.call<
void>(
"appendChild", innerImgElement);
251 return dragImageElement;
254emscripten::val QWasmDrag::DragState::DragImage::generateDragImageFromPixmap(
const QPixmap &
pixmap)
256 emscripten::val dragImageElement =
257 emscripten::val::global(
"document")
258 .call<emscripten::val>(
"createElement", emscripten::val(
"canvas"));
259 dragImageElement.set(
"width",
pixmap.width());
260 dragImageElement.set(
"height",
pixmap.height());
262 dragImageElement[
"style"].set(
263 "width", std::to_string(
pixmap.width() /
pixmap.devicePixelRatio()) +
"px");
264 dragImageElement[
"style"].set(
265 "height", std::to_string(
pixmap.height() /
pixmap.devicePixelRatio()) +
"px");
267 auto context2d = dragImageElement.call<emscripten::val>(
"getContext", emscripten::val(
"2d"));
268 auto imageData = context2d.call<emscripten::val>(
269 "createImageData", emscripten::val(
pixmap.width()), emscripten::val(
pixmap.height()));
273 context2d.call<
void>(
"putImageData",
imageData, emscripten::val(0), emscripten::val(0));
275 return dragImageElement;
280 return m_imageDomElement;
static Base64IconStore * get()
QObject * source() const
Returns the source of the drag object.
int exec(ProcessEventsFlags flags=AllEvents)
Enters the main event loop and waits until exit() is called.
void quit()
Tells the event loop to exit normally.
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.
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
virtual void move(const QPoint &globalPos, Qt::MouseButtons b, Qt::KeyboardModifiers mods) override
std::string toStdString() const
Returns a std::string object with the data contained in this QString.
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString first(qsizetype n) const &
qsizetype length() const noexcept
Returns the number of characters in this string.
DragImage(const QPixmap &pixmap, const QMimeData *mimeData, QWindow *window)
emscripten::val htmlElement()
void onNativeDragFinished(DragEvent *event)
void onNativeDrop(DragEvent *event)
void onNativeDragOver(DragEvent *event)
static QWasmDrag * instance()
void onNativeDragStarted(DragEvent *event)
static QWasmIntegration * get()
static QWasmWindow * fromWindow(QWindow *window)
EGLImageKHR int int EGLuint64KHR * modifiers
Combined button and popup list for selecting options.
QWindow * windowForDrag(QDrag *drag)
QPointF mapPoint(emscripten::val source, emscripten::val target, const QPointF &point)
void drawImageToWebImageDataArray(const QImage &sourceImage, emscripten::val destinationImageData, const QRect &sourceRect)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
constexpr const T & qMin(const T &a, const T &b)
#define Q_RETURN_ARG(Type, data)
#define Q_ASSERT_X(cond, x, msg)
QWindow * qobject_cast< QWindow * >(QObject *o)
DragState(QWasmDrag &&other)=delete
std::unique_ptr< DragImage > dragImage
DragState(QDrag *drag, QWindow *window, std::function< void()> quitEventLoopClosure)
std::function< void()> quitEventLoopClosure
Qt::DropAction dropAction
DragState(const QWasmDrag &other)=delete
DragState & operator=(QWasmDrag &&other)=delete
DragState & operator=(const QWasmDrag &other)=delete