diff options
author | Paul Olav Tvete <paul.tvete@qt.io> | 2016-06-16 11:47:38 +0200 |
---|---|---|
committer | Paul Olav Tvete <paul.tvete@qt.io> | 2016-06-20 13:38:11 +0000 |
commit | 8b3626b9a48fcf303cd7a20aede9a1577311a684 (patch) | |
tree | ad80f2af7aa6e3ea15e348964942888b3dbd0cf8 /src | |
parent | 75294be3c8574d7bb7c8fd53b717e7df9821e183 (diff) |
Compositor: Fix popup support properly
- Make popups work with overlays such as QQuickDrawer.
- No longer require that there is a background item that
accepts mouse events.
- UI items on top of the compositor area that should block mouse
clicks on popups, must set the property "qtwayland_blocking_overlay".
Change-Id: If81793750e016f53e3873e216e90ed86d324c067
Reviewed-by: Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
Reviewed-by: Johan Helsing <johan.helsing@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp | 34 | ||||
-rw-r--r-- | src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h | 5 |
2 files changed, 38 insertions, 1 deletions
diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp index d4b16e85f..5fe43e547 100644 --- a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp +++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp @@ -192,13 +192,19 @@ QWaylandQuickShellEventFilter::QWaylandQuickShellEventFilter(QObject *parent) bool QWaylandQuickShellEventFilter::eventFilter(QObject *receiver, QEvent *e) { if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease) { + bool press = e->type() == QEvent::MouseButtonPress; + if (press && !waitForRelease) { + // The user clicked something: we need to close popups unless this press is caught later + if (!mousePressTimeout.isActive()) + mousePressTimeout.start(0, this); + } + QQuickItem *item = qobject_cast<QQuickItem*>(receiver); if (!item) return false; QMouseEvent *event = static_cast<QMouseEvent*>(e); QWaylandQuickShellSurfaceItem *shellSurfaceItem = qobject_cast<QWaylandQuickShellSurfaceItem*>(item); - bool press = event->type() == QEvent::MouseButtonPress; bool finalRelease = (event->type() == QEvent::MouseButtonRelease) && (event->buttons() == Qt::NoButton); bool popupClient = shellSurfaceItem && shellSurfaceItem->surface()->client() == client; @@ -211,6 +217,21 @@ bool QWaylandQuickShellEventFilter::eventFilter(QObject *receiver, QEvent *e) return true; } + if (finalRelease && mousePressTimeout.isActive()) { + // the user somehow managed to press and release the mouse button in 0 milliseconds + qWarning("Badly written autotest detected"); + mousePressTimeout.stop(); + stopFilter(); + } + + if (press && !shellSurfaceItem && !QQmlProperty(item, QStringLiteral("qtwayland_blocking_overlay")).isValid()) { + // the user clicked on something that's not blocking mouse events + e->ignore(); //propagate the event to items below + return true; // don't give the event to the item + } + + mousePressTimeout.stop(); // we've got this + if (press && !popupClient) { // The user clicked outside the active popup's client. The popups should // be closed, but the event filter will stay to catch the release- @@ -224,4 +245,15 @@ bool QWaylandQuickShellEventFilter::eventFilter(QObject *receiver, QEvent *e) return false; } +void QWaylandQuickShellEventFilter::timerEvent(QTimerEvent *event) +{ + if (event->timerId() == mousePressTimeout.timerId()) { + mousePressTimeout.stop(); + closePopups(); + stopFilter(); + // Don't wait for release: Since the press wasn't accepted, + // the release won't be delivered. + } +} + QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h b/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h index c2f46917e..c39a1cd08 100644 --- a/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h +++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h @@ -38,6 +38,7 @@ #define QWAYLANDQUICKSHELLSURFACEITEM_P_H #include <QtWaylandCompositor/private/qwaylandquickitem_p.h> +#include <QtCore/QBasicTimer> QT_BEGIN_NAMESPACE @@ -86,6 +87,9 @@ public: static void startFilter(QWaylandClient *client, CallbackFunction closePopupCallback); static void cancelFilter(); +protected: + void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE; + private: void stopFilter(); @@ -95,6 +99,7 @@ private: bool waitForRelease; QPointer<QWaylandClient> client; CallbackFunction closePopups; + QBasicTimer mousePressTimeout; static QWaylandQuickShellEventFilter *self; }; |