diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2022-11-25 09:14:03 +0100 |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2022-12-07 10:35:04 +0100 |
commit | 5bae5debdf94f6bbec61f4ff50ecbf3c1231e0e3 (patch) | |
tree | 7e455bde883033ff6341a6254a0278add6f9839a /src | |
parent | 510fc8325774d3bef2ed474b8a28f90d31c5aebc (diff) | |
download | qtwayland-5bae5debdf94f6bbec61f4ff50ecbf3c1231e0e3.tar.gz |
compositor: Support touch interaction with client decorations
The client tells us when the title bar has been pressed and it
has started a move, but we only actually updated the position
of the window for mouse events. This adds touch event support
for this, but only for a single touch point. Since there is
no way of knowing which touch point actually triggered the
move, we just assume it is the first. This could cause some
odd behavior if you try interacting with the window frame
with two fingers at the same time, but not beyond what you
would expect.
[ChangeLog][QtWaylandCompositor] It is now possible to move
windows using client-side decorations with touch input as
well as mouse input.
Fixes: QTBUG-108690
Change-Id: I23ce1e39a26be5b1b5a5ac93d8f38cc59685aa96
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/compositor/extensions/qwaylandxdgshellintegration.cpp | 42 | ||||
-rw-r--r-- | src/compositor/extensions/qwaylandxdgshellintegration_p.h | 4 |
2 files changed, 33 insertions, 13 deletions
diff --git a/src/compositor/extensions/qwaylandxdgshellintegration.cpp b/src/compositor/extensions/qwaylandxdgshellintegration.cpp index ac13fffe..643ad65b 100644 --- a/src/compositor/extensions/qwaylandxdgshellintegration.cpp +++ b/src/compositor/extensions/qwaylandxdgshellintegration.cpp @@ -49,45 +49,63 @@ bool XdgToplevelIntegration::eventFilter(QObject *object, QEvent *event) if (event->type() == QEvent::MouseMove) { QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); return filterMouseMoveEvent(mouseEvent); - } else if (event->type() == QEvent::MouseButtonRelease) { - QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); - return filterMouseReleaseEvent(mouseEvent); + } else if (event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::TouchEnd || event->type() == QEvent::TouchCancel) { + return filterPointerReleaseEvent(); + } else if (event->type() == QEvent::TouchUpdate) { + QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event); + return filterTouchUpdateEvent(touchEvent); } return QWaylandQuickShellIntegration::eventFilter(object, event); } -bool XdgToplevelIntegration::filterMouseMoveEvent(QMouseEvent *event) +bool XdgToplevelIntegration::filterPointerMoveEvent(const QPointF &scenePosition) { if (grabberState == GrabberState::Resize) { - Q_ASSERT(resizeState.seat == m_item->compositor()->seatFor(event)); if (!resizeState.initialized) { - resizeState.initialMousePos = event->scenePosition(); + resizeState.initialMousePos = scenePosition; resizeState.initialized = true; return true; } - QPointF delta = m_item->mapToSurface(event->scenePosition() - resizeState.initialMousePos); + QPointF delta = m_item->mapToSurface(scenePosition - resizeState.initialMousePos); QSize newSize = m_toplevel->sizeForResize(resizeState.initialWindowSize, delta, resizeState.resizeEdges); m_toplevel->sendResizing(newSize); } else if (grabberState == GrabberState::Move) { - Q_ASSERT(moveState.seat == m_item->compositor()->seatFor(event)); QQuickItem *moveItem = m_item->moveItem(); if (!moveState.initialized) { - moveState.initialOffset = moveItem->mapFromItem(nullptr, event->scenePosition()); + moveState.initialOffset = moveItem->mapFromItem(nullptr, scenePosition); moveState.initialized = true; return true; } if (!moveItem->parentItem()) return true; - QPointF parentPos = moveItem->parentItem()->mapFromItem(nullptr, event->scenePosition()); + QPointF parentPos = moveItem->parentItem()->mapFromItem(nullptr, scenePosition); moveItem->setPosition(parentPos - moveState.initialOffset); } return false; } -bool XdgToplevelIntegration::filterMouseReleaseEvent(QMouseEvent *event) +bool XdgToplevelIntegration::filterTouchUpdateEvent(QTouchEvent *event) +{ + if (event->pointCount() == 0) + return false; + + Q_ASSERT(grabberState != GrabberState::Move || moveState.seat == m_item->compositor()->seatFor(event)); + Q_ASSERT(grabberState != GrabberState::Resize || resizeState.seat == m_item->compositor()->seatFor(event)); + + QEventPoint point = event->points().first(); + return filterPointerMoveEvent(point.scenePosition()); + } + +bool XdgToplevelIntegration::filterMouseMoveEvent(QMouseEvent *event) { - Q_UNUSED(event); + Q_ASSERT(grabberState != GrabberState::Move || moveState.seat == m_item->compositor()->seatFor(event)); + Q_ASSERT(grabberState != GrabberState::Resize || resizeState.seat == m_item->compositor()->seatFor(event)); + return filterPointerMoveEvent(event->scenePosition()); +} + +bool XdgToplevelIntegration::filterPointerReleaseEvent() +{ if (grabberState != GrabberState::Default) { grabberState = GrabberState::Default; return true; diff --git a/src/compositor/extensions/qwaylandxdgshellintegration_p.h b/src/compositor/extensions/qwaylandxdgshellintegration_p.h index 3fe09587..eba39767 100644 --- a/src/compositor/extensions/qwaylandxdgshellintegration_p.h +++ b/src/compositor/extensions/qwaylandxdgshellintegration_p.h @@ -89,8 +89,10 @@ private: // geometry-changed. } nonwindowedState; + bool filterPointerMoveEvent(const QPointF &scenePosition); bool filterMouseMoveEvent(QMouseEvent *event); - bool filterMouseReleaseEvent(QMouseEvent *event); + bool filterPointerReleaseEvent(); + bool filterTouchUpdateEvent(QTouchEvent *event); }; class XdgPopupIntegration : public QWaylandQuickShellIntegration |