From b3370f3c5b3ec7993c5f5ff835714c9c7a42dd17 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 28 Apr 2017 15:03:15 +0200 Subject: QQuickOverlay: reduce one event filter Instead of using the window content item for detecting when mouse and touch events propagate through the item hierarchy without being accepted/handled, utilize QQuickWindowPrivate::handleMouse/TouchEvent() to deliver the respective events from the window-level even filter. That way we can unconditionally accept mouse and touch events after the delivery to the item tree, to ensure receiving the consequent mouse and touch events. Change-Id: I5f70c2e0e0d931c544461261721cc9b17ce8d3ef Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickoverlay.cpp | 101 +++++++++++++++++----------------- 1 file changed, 49 insertions(+), 52 deletions(-) (limited to 'src/quicktemplates2/qquickoverlay.cpp') diff --git a/src/quicktemplates2/qquickoverlay.cpp b/src/quicktemplates2/qquickoverlay.cpp index 60f2a36f..0f7edc77 100644 --- a/src/quicktemplates2/qquickoverlay.cpp +++ b/src/quicktemplates2/qquickoverlay.cpp @@ -344,8 +344,6 @@ QQuickOverlay::QQuickOverlay(QQuickItem *parent) if (parent) { setSize(QSizeF(parent->width(), parent->height())); QQuickItemPrivate::get(parent)->addItemChangeListener(d, QQuickItemPrivate::Geometry); - parent->setAcceptedMouseButtons(Qt::AllButtons); - parent->installEventFilter(this); if (QQuickWindow *window = parent->window()) window->installEventFilter(this); } @@ -536,64 +534,63 @@ bool QQuickOverlay::childMouseEventFilter(QQuickItem *item, QEvent *event) bool QQuickOverlay::eventFilter(QObject *object, QEvent *event) { Q_D(QQuickOverlay); - if (!isVisible() || !d->window) + if (!isVisible() || object != d->window) return false; - if (object == d->window) { - switch (event->type()) { - case QEvent::TouchBegin: - case QEvent::TouchUpdate: - case QEvent::TouchEnd: - if (static_cast(event)->touchPointStates() & Qt::TouchPointPressed) - emit pressed(); - if (static_cast(event)->touchPointStates() & Qt::TouchPointReleased) - emit released(); - - // allow non-modal popups to close on touch release outside - if (!d->mouseGrabberPopup) { - for (const QTouchEvent::TouchPoint &point : static_cast(event)->touchPoints()) { - if (point.state() == Qt::TouchPointReleased) { - if (d->handleRelease(d->window->contentItem(), event, nullptr)) - break; - } + switch (event->type()) { + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + if (static_cast(event)->touchPointStates() & Qt::TouchPointPressed) + emit pressed(); + if (static_cast(event)->touchPointStates() & Qt::TouchPointReleased) + emit released(); + + // allow non-modal popups to close on touch release outside + if (!d->mouseGrabberPopup) { + for (const QTouchEvent::TouchPoint &point : static_cast(event)->touchPoints()) { + if (point.state() == Qt::TouchPointReleased) { + if (d->handleRelease(d->window->contentItem(), event, nullptr)) + break; } } - break; + } - case QEvent::MouseButtonPress: - // do not emit pressed() twice when mouse events have been synthesized from touch events - if (static_cast(event)->source() == Qt::MouseEventNotSynthesized) - emit pressed(); - break; + QQuickWindowPrivate::get(d->window)->handleTouchEvent(static_cast(event)); - case QEvent::MouseButtonRelease: - // do not emit released() twice when mouse events have been synthesized from touch events - if (static_cast(event)->source() == Qt::MouseEventNotSynthesized) - emit released(); + // If a touch event hasn't been accepted after being delivered, there + // were no items interested in touch events at any of the touch points. + // Make sure to accept the touch event in order to receive the consequent + // touch events, to be able to close non-modal popups on release outside. + event->accept(); + return true; - // allow non-modal popups to close on mouse release outside - if (!d->mouseGrabberPopup) - d->handleRelease(d->window->contentItem(), event, nullptr); - break; + case QEvent::MouseButtonPress: + // do not emit pressed() twice when mouse events have been synthesized from touch events + if (static_cast(event)->source() == Qt::MouseEventNotSynthesized) + emit pressed(); - default: - break; - } - } else if (object == d->window->contentItem()) { - // A touch or mouse press has reached the content item of the window, - // meaning that nothing at the press point was interested in touch or - // mouse events. Make sure to accept the press in order to receive the - // consequent move and release events to be able to close non-modal - // popups on release outside. - switch (event->type()) { - case QEvent::TouchBegin: - case QEvent::TouchUpdate: - case QEvent::MouseButtonPress: - event->accept(); - break; - default: - break; - } + QQuickWindowPrivate::get(d->window)->handleMouseEvent(static_cast(event)); + + // If a mouse event hasn't been accepted after being delivered, there + // was no item interested in mouse events at the mouse point. Make sure + // to accept the mouse event in order to receive the consequent mouse + // events, to be able to close non-modal popups on release outside. + event->accept(); + return true; + + case QEvent::MouseButtonRelease: + // do not emit released() twice when mouse events have been synthesized from touch events + if (static_cast(event)->source() == Qt::MouseEventNotSynthesized) + emit released(); + + // allow non-modal popups to close on mouse release outside + if (!d->mouseGrabberPopup) + d->handleRelease(d->window->contentItem(), event, nullptr); + break; + + default: + break; } return false; -- cgit v1.2.3