diff options
Diffstat (limited to 'src/compositor/compositor_api/qwaylandquickitem.cpp')
-rw-r--r-- | src/compositor/compositor_api/qwaylandquickitem.cpp | 171 |
1 files changed, 135 insertions, 36 deletions
diff --git a/src/compositor/compositor_api/qwaylandquickitem.cpp b/src/compositor/compositor_api/qwaylandquickitem.cpp index a1855529c..08eefffa0 100644 --- a/src/compositor/compositor_api/qwaylandquickitem.cpp +++ b/src/compositor/compositor_api/qwaylandquickitem.cpp @@ -39,14 +39,17 @@ #include "qwaylandquicksurface.h" #include "qwaylandinputmethodcontrol.h" #include "qwaylandtextinput.h" +#include "qwaylandquickoutput.h" #include <QtWaylandCompositor/qwaylandcompositor.h> -#include <QtWaylandCompositor/qwaylandinput.h> +#include <QtWaylandCompositor/qwaylandseat.h> #include <QtWaylandCompositor/qwaylandbufferref.h> +#include <QtWaylandCompositor/QWaylandDrag> #include <QtWaylandCompositor/private/qwlclientbufferintegration_p.h> #include <QtGui/QKeyEvent> #include <QtGui/QGuiApplication> #include <QtGui/QScreen> +#include <QtGui/QOpenGLFunctions> #include <QtQuick/QSGSimpleTextureNode> #include <QtQuick/QQuickWindow> @@ -293,7 +296,7 @@ public: delete m_sgTex; m_sgTex = 0; if (m_ref.hasBuffer()) { - if (buffer.isShm()) { + if (buffer.isSharedMemory()) { m_sgTex = surfaceItem->window()->createTextureFromImage(buffer.image()); if (m_sgTex) { m_sgTex->bind(); @@ -492,13 +495,13 @@ void QWaylandQuickItem::mousePressEvent(QMouseEvent *event) return; } - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); + QWaylandSeat *seat = compositor()->seatFor(event); if (d->focusOnClick) - takeFocus(inputDevice); + takeFocus(seat); - inputDevice->sendMouseMoveEvent(d->view.data(), event->localPos() / d->scaleFactor(), event->windowPos()); - inputDevice->sendMousePressEvent(event->button()); + seat->sendMouseMoveEvent(d->view.data(), mapToSurface(event->localPos()), event->windowPos()); + seat->sendMousePressEvent(event->button()); } /*! @@ -508,8 +511,20 @@ void QWaylandQuickItem::mouseMoveEvent(QMouseEvent *event) { Q_D(QWaylandQuickItem); if (d->shouldSendInputEvents()) { - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendMouseMoveEvent(d->view.data(), event->localPos() / d->scaleFactor(), event->windowPos()); + QWaylandSeat *seat = compositor()->seatFor(event); + if (d->isDragging) { + QWaylandQuickOutput *currentOutput = qobject_cast<QWaylandQuickOutput *>(view()->output()); + //TODO: also check if dragging onto other outputs + QWaylandQuickItem *targetItem = qobject_cast<QWaylandQuickItem *>(currentOutput->pickClickableItem(mapToScene(event->localPos()))); + QWaylandSurface *targetSurface = targetItem ? targetItem->surface() : nullptr; + if (targetSurface) { + QPointF position = mapToItem(targetItem, event->localPos()); + QPointF surfacePosition = targetItem->mapToSurface(position); + seat->drag()->dragMove(targetSurface, surfacePosition); + } + } else { + seat->sendMouseMoveEvent(d->view.data(), mapToSurface(event->localPos()), event->windowPos()); + } } else { emit mouseMove(event->windowPos()); event->ignore(); @@ -523,8 +538,13 @@ void QWaylandQuickItem::mouseReleaseEvent(QMouseEvent *event) { Q_D(QWaylandQuickItem); if (d->shouldSendInputEvents()) { - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendMouseReleaseEvent(event->button()); + QWaylandSeat *seat = compositor()->seatFor(event); + if (d->isDragging) { + d->isDragging = false; + seat->drag()->drop(); + } else { + seat->sendMouseReleaseEvent(event->button()); + } } else { emit mouseRelease(); event->ignore(); @@ -542,8 +562,8 @@ void QWaylandQuickItem::hoverEnterEvent(QHoverEvent *event) return; } if (d->shouldSendInputEvents()) { - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendMouseMoveEvent(d->view.data(), event->pos(), mapToScene(event->pos())); + QWaylandSeat *seat = compositor()->seatFor(event); + seat->sendMouseMoveEvent(d->view.data(), event->pos(), mapToScene(event->pos())); } else { event->ignore(); } @@ -562,8 +582,8 @@ void QWaylandQuickItem::hoverMoveEvent(QHoverEvent *event) } } if (d->shouldSendInputEvents()) { - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendMouseMoveEvent(d->view.data(), event->pos() / d->scaleFactor(), mapToScene(event->pos())); + QWaylandSeat *seat = compositor()->seatFor(event); + seat->sendMouseMoveEvent(d->view.data(), mapToSurface(event->pos()), mapToScene(event->pos())); } else { event->ignore(); } @@ -576,8 +596,8 @@ void QWaylandQuickItem::hoverLeaveEvent(QHoverEvent *event) { Q_D(QWaylandQuickItem); if (d->shouldSendInputEvents()) { - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->setMouseFocus(Q_NULLPTR); + QWaylandSeat *seat = compositor()->seatFor(event); + seat->setMouseFocus(Q_NULLPTR); } else { event->ignore(); } @@ -595,8 +615,8 @@ void QWaylandQuickItem::wheelEvent(QWheelEvent *event) return; } - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendMouseWheelEvent(event->orientation(), event->delta()); + QWaylandSeat *seat = compositor()->seatFor(event); + seat->sendMouseWheelEvent(event->orientation(), event->delta()); } else { event->ignore(); } @@ -609,8 +629,8 @@ void QWaylandQuickItem::keyPressEvent(QKeyEvent *event) { Q_D(QWaylandQuickItem); if (d->shouldSendInputEvents()) { - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendFullKeyEvent(event); + QWaylandSeat *seat = compositor()->seatFor(event); + seat->sendFullKeyEvent(event); } else { event->ignore(); } @@ -623,8 +643,8 @@ void QWaylandQuickItem::keyReleaseEvent(QKeyEvent *event) { Q_D(QWaylandQuickItem); if (d->shouldSendInputEvents() && hasFocus()) { - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendFullKeyEvent(event); + QWaylandSeat *seat = compositor()->seatFor(event); + seat->sendFullKeyEvent(event); } else { event->ignore(); } @@ -637,7 +657,7 @@ void QWaylandQuickItem::touchEvent(QTouchEvent *event) { Q_D(QWaylandQuickItem); if (d->shouldSendInputEvents() && d->touchEventsEnabled) { - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); + QWaylandSeat *seat = compositor()->seatFor(event); if (event->type() == QEvent::TouchBegin) { QQuickItem *grabber = window()->mouseGrabberItem(); @@ -656,10 +676,10 @@ void QWaylandQuickItem::touchEvent(QTouchEvent *event) } event->accept(); - if (inputDevice->mouseFocus() != d->view.data()) { - inputDevice->sendMouseMoveEvent(d->view.data(), pointPos, mapToScene(pointPos)); + if (seat->mouseFocus() != d->view.data()) { + seat->sendMouseMoveEvent(d->view.data(), pointPos, mapToScene(pointPos)); } - inputDevice->sendFullTouchEvent(event); + seat->sendFullTouchEvent(event); } else { event->ignore(); } @@ -757,31 +777,90 @@ void QWaylandQuickItem::setSubsurfaceHandler(QObject *handler) } /*! + * \property QWaylandQuickItem::output + * + * This property holds the output on which this item is displayed. + */ +QWaylandOutput *QWaylandQuickItem::output() const +{ + Q_D(const QWaylandQuickItem); + return d->view->output(); +} + +void QWaylandQuickItem::setOutput(QWaylandOutput *output) +{ + Q_D(QWaylandQuickItem); + d->view->setOutput(output); +} + +/*! + * \property QWaylandQuickItem::bufferLocked + * + * This property holds whether the item's buffer is currently locked. As long as + * the buffer is locked, it will not be released and returned to the client. + * + * The default is false. + */ +bool QWaylandQuickItem::isBufferLocked() const +{ + Q_D(const QWaylandQuickItem); + return d->view->isBufferLocked(); +} + +void QWaylandQuickItem::setBufferLocked(bool locked) +{ + Q_D(QWaylandQuickItem); + d->view->setBufferLocked(locked); +} + +/*! + * \property bool QWaylandQuickItem::allowDiscardFrontBuffer + * + * By default, the item locks the current buffer until a new buffer is available + * and updatePaintNode() is called. Set this property to true to allow Qt to release the buffer + * immediately when the throttling view is no longer using it. This is useful for items that have + * slow update intervals. + */ +bool QWaylandQuickItem::allowDiscardFrontBuffer() const +{ + Q_D(const QWaylandQuickItem); + return d->view->allowDiscardFrontBuffer(); +} + +void QWaylandQuickItem::setAllowDiscardFrontBuffer(bool discard) +{ + Q_D(QWaylandQuickItem); + d->view->setAllowDiscardFrontBuffer(discard); +} + +/*! * \internal */ void QWaylandQuickItem::handleSurfaceChanged() { Q_D(QWaylandQuickItem); if (d->oldSurface) { - disconnect(d->oldSurface, &QWaylandSurface::mappedChanged, this, &QWaylandQuickItem::surfaceMappedChanged); + disconnect(d->oldSurface, &QWaylandSurface::hasContentChanged, this, &QWaylandQuickItem::surfaceMappedChanged); disconnect(d->oldSurface, &QWaylandSurface::parentChanged, this, &QWaylandQuickItem::parentChanged); disconnect(d->oldSurface, &QWaylandSurface::sizeChanged, this, &QWaylandQuickItem::updateSize); disconnect(d->oldSurface, &QWaylandSurface::bufferScaleChanged, this, &QWaylandQuickItem::updateSize); disconnect(d->oldSurface, &QWaylandSurface::configure, this, &QWaylandQuickItem::updateBuffer); disconnect(d->oldSurface, &QWaylandSurface::redraw, this, &QQuickItem::update); disconnect(d->oldSurface, &QWaylandSurface::childAdded, this, &QWaylandQuickItem::handleSubsurfaceAdded); + disconnect(d->oldSurface, &QWaylandSurface::dragStarted, this, &QWaylandQuickItem::handleDragStarted); #ifndef QT_NO_IM disconnect(d->oldSurface->inputMethodControl(), &QWaylandInputMethodControl::updateInputMethod, this, &QWaylandQuickItem::updateInputMethod); #endif } if (QWaylandSurface *newSurface = d->view->surface()) { - connect(newSurface, &QWaylandSurface::mappedChanged, this, &QWaylandQuickItem::surfaceMappedChanged); + connect(newSurface, &QWaylandSurface::hasContentChanged, this, &QWaylandQuickItem::surfaceMappedChanged); connect(newSurface, &QWaylandSurface::parentChanged, this, &QWaylandQuickItem::parentChanged); connect(newSurface, &QWaylandSurface::sizeChanged, this, &QWaylandQuickItem::updateSize); connect(newSurface, &QWaylandSurface::bufferScaleChanged, this, &QWaylandQuickItem::updateSize); connect(newSurface, &QWaylandSurface::configure, this, &QWaylandQuickItem::updateBuffer); connect(newSurface, &QWaylandSurface::redraw, this, &QQuickItem::update); connect(newSurface, &QWaylandSurface::childAdded, this, &QWaylandQuickItem::handleSubsurfaceAdded); + connect(newSurface, &QWaylandSurface::dragStarted, this, &QWaylandQuickItem::handleDragStarted); #ifndef QT_NO_IM connect(newSurface->inputMethodControl(), &QWaylandInputMethodControl::updateInputMethod, this, &QWaylandQuickItem::updateInputMethod); #endif @@ -808,16 +887,16 @@ void QWaylandQuickItem::handleSurfaceChanged() * Calling this function causes the item to take the focus of the * input \a device. */ -void QWaylandQuickItem::takeFocus(QWaylandInputDevice *device) +void QWaylandQuickItem::takeFocus(QWaylandSeat *device) { forceActiveFocus(); if (!surface()) return; - QWaylandInputDevice *target = device; + QWaylandSeat *target = device; if (!target) { - target = compositor()->defaultInputDevice(); + target = compositor()->defaultSeat(); } target->setKeyboardFocus(surface()); QWaylandTextInput *textInput = QWaylandTextInput::findIn(target); @@ -898,13 +977,23 @@ void QWaylandQuickItem::setFocusOnClick(bool focus) */ bool QWaylandQuickItem::inputRegionContains(const QPointF &localPosition) { - Q_D(QWaylandQuickItem); if (QWaylandSurface *s = surface()) - return s->inputRegionContains(localPosition.toPoint() / d->scaleFactor()); + return s->inputRegionContains(mapToSurface(localPosition).toPoint()); return false; } /*! + * Maps the given \a point in this item's coordinate system to the equivalent + * point within the Wayland surface's coordinate system, and returns the mapped + * coordinate. + */ +QPointF QWaylandQuickItem::mapToSurface(const QPointF &point) const +{ + Q_D(const QWaylandQuickItem); + return point / d->scaleFactor(); +} + +/*! * \qmlproperty bool QtWaylandCompositor::WaylandQuickItem::sizeFollowsSurface * * This property specifies whether the size of the item should always match @@ -1043,9 +1132,9 @@ void QWaylandQuickItem::updateInputMethod(Qt::InputMethodQueries queries) QSGNode *QWaylandQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) { Q_D(QWaylandQuickItem); - const bool mapped = surface() && surface()->isMapped() && d->view->currentBuffer().hasBuffer(); + const bool hasContent = surface() && surface()->hasContent() && d->view->currentBuffer().hasBuffer(); - if (!mapped || !d->paintEnabled) { + if (!hasContent || !d->paintEnabled) { delete oldNode; return 0; } @@ -1055,7 +1144,7 @@ QSGNode *QWaylandQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat const QRectF rect = invertY ? QRectF(0, height(), width(), -height()) : QRectF(0, 0, width(), height()); - if (ref.isShm() || bufferTypes[ref.bufferFormatEgl()].canProvideTexture) { + if (ref.isSharedMemory() || bufferTypes[ref.bufferFormatEgl()].canProvideTexture) { QSGSimpleTextureNode *node = static_cast<QSGSimpleTextureNode *>(oldNode); if (!node) { @@ -1138,6 +1227,8 @@ void QWaylandQuickItem::setInputEventsEnabled(bool enabled) { Q_D(QWaylandQuickItem); if (d->inputEventsEnabled != enabled) { + if (enabled) + setEnabled(true); d->setInputEventsEnabled(enabled); emit inputEventsEnabledChanged(); } @@ -1172,5 +1263,13 @@ void QWaylandQuickItem::handleSubsurfacePosition(const QPoint &pos) QQuickItem::setPosition(pos * d->scaleFactor()); } +void QWaylandQuickItem::handleDragStarted(QWaylandDrag *drag) +{ + Q_D(QWaylandQuickItem); + Q_ASSERT(drag->origin() == surface()); + drag->seat()->setMouseFocus(nullptr); + d->isDragging = true; +} + QT_END_NAMESPACE |