Implement touch event handling for SplitView

Amend 80166d58a1, which broke touch event
handling in SplitView. Implement handling of TouchBegin/Update/End
events equivalently to the mouse event handling.

As a drive-by, rename the logging category from 'mouse' to 'pointer',
and refactor the if/else sequence to a switch statement, reducing
duplication of code that's common for all event types.

Remove expectFail from the test that now passes.

Fixes: QTBUG-105312
Pick-to: 6.5 6.4 6.2
Change-Id: I156f55fa40b2afaaa115e59940d26187121fc16a
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
Volker Hilsheimer 2022-12-12 12:42:02 +01:00
parent f15f1d643e
commit 6de2397da2
2 changed files with 49 additions and 26 deletions

View File

@ -222,7 +222,7 @@ QT_BEGIN_NAMESPACE
*/
Q_LOGGING_CATEGORY(qlcQQuickSplitView, "qt.quick.controls.splitview")
Q_LOGGING_CATEGORY(qlcQQuickSplitViewMouse, "qt.quick.controls.splitview.mouse")
Q_LOGGING_CATEGORY(qlcQQuickSplitViewPointer, "qt.quick.controls.splitview.pointer")
Q_LOGGING_CATEGORY(qlcQQuickSplitViewState, "qt.quick.controls.splitview.state")
void QQuickSplitViewPrivate::updateFillIndex()
@ -896,7 +896,7 @@ void QQuickSplitViewPrivate::updateHandleVisibilities()
void QQuickSplitViewPrivate::updateHoveredHandle(QQuickItem *hoveredItem)
{
qCDebug(qlcQQuickSplitViewMouse) << "updating hovered handle after" << hoveredItem << "was hovered";
qCDebug(qlcQQuickSplitViewPointer) << "updating hovered handle after" << hoveredItem << "was hovered";
const int oldHoveredHandleIndex = m_hoveredHandleIndex;
m_hoveredHandleIndex = m_handleItems.indexOf(hoveredItem);
@ -909,16 +909,16 @@ void QQuickSplitViewPrivate::updateHoveredHandle(QQuickItem *hoveredItem)
QQuickSplitHandleAttached *oldHoveredHandleAttached = qobject_cast<QQuickSplitHandleAttached*>(
qmlAttachedPropertiesObject<QQuickSplitHandleAttached>(oldHoveredHandle, true));
QQuickSplitHandleAttachedPrivate::get(oldHoveredHandleAttached)->setHovered(false);
qCDebug(qlcQQuickSplitViewMouse) << "handle item at index" << oldHoveredHandleIndex << "is no longer hovered";
qCDebug(qlcQQuickSplitViewPointer) << "handle item at index" << oldHoveredHandleIndex << "is no longer hovered";
}
if (m_hoveredHandleIndex != -1) {
QQuickSplitHandleAttached *handleAttached = qobject_cast<QQuickSplitHandleAttached*>(
qmlAttachedPropertiesObject<QQuickSplitHandleAttached>(hoveredItem, true));
QQuickSplitHandleAttachedPrivate::get(handleAttached)->setHovered(true);
qCDebug(qlcQQuickSplitViewMouse) << "handle item at index" << m_hoveredHandleIndex << "is now hovered";
qCDebug(qlcQQuickSplitViewPointer) << "handle item at index" << m_hoveredHandleIndex << "is now hovered";
} else {
qCDebug(qlcQQuickSplitViewMouse) << "either there is no hovered item or" << hoveredItem << "is not a handle";
qCDebug(qlcQQuickSplitViewPointer) << "either there is no hovered item or" << hoveredItem << "is not a handle";
}
}
@ -987,7 +987,7 @@ bool QQuickSplitViewPrivate::handlePress(const QPointF &point, ulong timestamp)
setResizing(true);
qCDebug(qlcQQuickSplitViewMouse).nospace() << "handled press -"
qCDebug(qlcQQuickSplitViewPointer).nospace() << "handled press -"
<< " left/top index=" << m_pressedHandleIndex << ","
<< " size before press=" << m_leftOrTopItemSizeBeforePress << ","
<< " item=" << leftOrTopItem
@ -1380,27 +1380,51 @@ void QQuickSplitView::hoverLeaveEvent(QHoverEvent *event)
bool QQuickSplitView::childMouseEventFilter(QQuickItem *item, QEvent *event)
{
Q_D(QQuickSplitView);
qCDebug(qlcQQuickSplitViewMouse) << "childMouseEventFilter called with" << item << event;
qCDebug(qlcQQuickSplitViewPointer) << "childMouseEventFilter called with" << item << event;
if (event->type() == QEvent::MouseButtonPress) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
const QPointF point = mapFromItem(item, mouseEvent->position());
d->handlePress(point, mouseEvent->timestamp());
if (Q_LIKELY(event->isPointerEvent())) {
auto *pointerEvent = static_cast<QPointerEvent *>(event);
const auto &eventPoint = pointerEvent->points().first();
const QPointF point = mapFromItem(item, eventPoint.position());
const auto timestamp = pointerEvent->timestamp();
// Keep the mouse grab if this item belongs to the handle,
// otherwise this event can be stolen e.g. Flickable if we're inside it.
if (d->m_pressedHandleIndex != -1)
item->setKeepMouseGrab(true);
}
else if (event->type() == QEvent::MouseButtonRelease) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
const QPointF point = mapFromItem(item, mouseEvent->position());
d->handleRelease(point, mouseEvent->timestamp());
}
else if (event->type() == QEvent::MouseMove) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
const QPointF point = mapFromItem(item, mouseEvent->position());
d->handleMove(point, mouseEvent->timestamp());
switch (event->type()) {
case QEvent::MouseButtonPress:
d->handlePress(point, timestamp);
// Keep the mouse grab if this item belongs to the handle,
// otherwise this event can be stolen e.g. Flickable if we're inside it.
if (d->m_pressedHandleIndex != -1)
item->setKeepMouseGrab(true);
break;
case QEvent::MouseButtonRelease:
d->handleRelease(point, timestamp);
break;
case QEvent::MouseMove:
d->handleMove(point, timestamp);
break;
case QEvent::TouchBegin:
if (pointerEvent->pointCount() == 1) {
d->handlePress(point, timestamp);
// We filter the event on behalf of item, but we want the item
// to be the exclusive grabber so that we can continue to filter
// touch events for it.
if (d->m_pressedHandleIndex != -1) {
item->setKeepTouchGrab(true);
pointerEvent->setExclusiveGrabber(eventPoint, item);
}
}
break;
case QEvent::TouchEnd:
if (pointerEvent->pointCount() == 1)
d->handleRelease(point, timestamp);
break;
case QEvent::TouchUpdate:
if (pointerEvent->pointCount() == 1)
d->handleMove(point, timestamp);
break;
default:
break;
}
}
// If this event belongs to the handle, filter it. (d->m_pressedHandleIndex != -1) means that

View File

@ -2597,7 +2597,6 @@ TestCase {
touch.move(0, control, handleCenter.x + 100, handleCenter.y).commit()
verify(firstHandle.SplitHandle.pressed)
let firstItem = control.itemAt(0)
expectFail("", "broken, QTBUG-105312")
compare(firstItem.width, 125)
touch.release(0, control, handleCenter.x + 100, handleCenter.y).commit()