summaryrefslogtreecommitdiffstats
path: root/src/compositor/compositor_api/qwaylandquickitem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/compositor/compositor_api/qwaylandquickitem.cpp')
-rw-r--r--src/compositor/compositor_api/qwaylandquickitem.cpp171
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