diff options
author | Jan Arne Petersen <jan.petersen@kdab.com> | 2014-08-10 06:54:55 +0200 |
---|---|---|
committer | Jan Arne Petersen <jan.petersen@kdab.com> | 2014-08-13 21:24:40 +0200 |
commit | c288de20291eb5d9a3dc3e3eae16d007fd08afa3 (patch) | |
tree | d1fcf22a9e1d84978f76c1b10de255feb8fbbe95 /src | |
parent | bbae1f2afe5aaa8522dfeb6de6c759c54c4292ef (diff) |
Add support for setMask to set input region
Also fix input region handling in compositor.
Change-Id: If88ad6a03443526eddee045d7af54daf5057373a
Done-with: Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
Reviewed-by: Giulio Camuffo <giulio.camuffo@jollamobile.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/client/qwaylanddisplay.cpp | 10 | ||||
-rw-r--r-- | src/client/qwaylanddisplay_p.h | 1 | ||||
-rw-r--r-- | src/client/qwaylandwindow.cpp | 20 | ||||
-rw-r--r-- | src/client/qwaylandwindow_p.h | 3 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandsurface.cpp | 6 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandsurface.h | 2 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandsurfaceitem.cpp | 25 | ||||
-rw-r--r-- | src/compositor/wayland_wrapper/qwlsurface.cpp | 16 | ||||
-rw-r--r-- | src/compositor/wayland_wrapper/qwlsurface_p.h | 1 |
9 files changed, 78 insertions, 6 deletions
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp index 5764d3110..4475356b0 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp @@ -96,6 +96,16 @@ QWaylandShellSurface *QWaylandDisplay::createShellSurface(QWaylandWindow *window return Q_NULLPTR; } +struct ::wl_region *QWaylandDisplay::createRegion(const QRegion &qregion) +{ + struct ::wl_region *region = mCompositor.create_region(); + + Q_FOREACH (const QRect &rect, qregion.rects()) + wl_region_add(region, rect.x(), rect.y(), rect.width(), rect.height()); + + return region; +} + QWaylandClientBufferIntegration * QWaylandDisplay::clientBufferIntegration() const { return mWaylandIntegration->clientBufferIntegration(); diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h index 6ed30d195..ade8475e7 100644 --- a/src/client/qwaylanddisplay_p.h +++ b/src/client/qwaylanddisplay_p.h @@ -103,6 +103,7 @@ public: struct wl_surface *createSurface(void *handle); QWaylandShellSurface *createShellSurface(QWaylandWindow *window); + struct ::wl_region *createRegion(const QRegion &qregion); QWaylandClientBufferIntegration *clientBufferIntegration() const; diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index a6190c0d1..a3e9b53cf 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -88,6 +88,7 @@ QWaylandWindow::QWaylandWindow(QWindow *window) , mMouseDevice(0) , mMouseSerial(0) , mState(Qt::WindowNoState) + , mMask() { init(mDisplay->createSurface(static_cast<QtWayland::wl_surface *>(this))); @@ -124,6 +125,7 @@ QWaylandWindow::QWaylandWindow(QWindow *window) setOrientationMask(window->screen()->orientationUpdateMask()); setWindowFlags(window->flags()); setGeometry_helper(window->geometry()); + setMask(window->mask()); setWindowStateInternal(window->windowState()); handleContentOrientationChange(window->contentOrientation()); } @@ -262,6 +264,24 @@ void QWaylandWindow::lower() mShellSurface->lower(); } +void QWaylandWindow::setMask(const QRegion &mask) +{ + if (mMask == mask) + return; + + mMask = mask; + + if (mMask.isEmpty()) { + set_input_region(0); + } else { + struct ::wl_region *region = mDisplay->createRegion(mMask); + set_input_region(region); + wl_region_destroy(region); + } + + commit(); +} + void QWaylandWindow::configure(uint32_t edges, int32_t width, int32_t height) { QMutexLocker resizeLocker(&mResizeLock); diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index 9c0be84c6..85e9f429e 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -139,6 +139,8 @@ public: void raise() Q_DECL_OVERRIDE; void lower() Q_DECL_OVERRIDE; + void setMask(const QRegion ®ion) Q_DECL_OVERRIDE; + void requestActivateWindow() Q_DECL_OVERRIDE; bool isExposed() const Q_DECL_OVERRIDE; @@ -215,6 +217,7 @@ protected: int mMouseSerial; Qt::WindowState mState; + QRegion mMask; private: bool setWindowStateInternal(Qt::WindowState flags); diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index c0a04c297..b3673c52e 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -319,6 +319,12 @@ bool QWaylandSurface::transientInactive() const return d->transientInactive(); } +bool QWaylandSurface::inputRegionContains(const QPoint &p) const +{ + Q_D(const QWaylandSurface); + return d->inputRegion().contains(p); +} + void QWaylandSurface::destroy() { Q_D(QWaylandSurface); diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h index 4575614dd..6d348e6b3 100644 --- a/src/compositor/compositor_api/qwaylandsurface.h +++ b/src/compositor/compositor_api/qwaylandsurface.h @@ -169,6 +169,8 @@ public: bool transientInactive() const; + bool inputRegionContains(const QPoint &p) const; + Q_INVOKABLE void destroy(); Q_INVOKABLE void destroySurface(); Q_INVOKABLE void destroySurfaceByForce(); diff --git a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp index cf9880b58..254d45bbd 100644 --- a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp +++ b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp @@ -144,6 +144,11 @@ void QWaylandSurfaceItem::mousePressEvent(QMouseEvent *event) if (!surface()) return; + if (!surface()->inputRegionContains(event->pos())) { + event->ignore(); + return; + } + QWaylandInputDevice *inputDevice = compositor()->defaultInputDevice(); if (inputDevice->mouseFocus() != this) inputDevice->setMouseFocus(this, event->localPos(), event->windowPos()); @@ -193,6 +198,11 @@ void QWaylandSurfaceItem::hoverLeaveEvent(QHoverEvent *event) void QWaylandSurfaceItem::wheelEvent(QWheelEvent *event) { if (surface()) { + if (!surface()->inputRegionContains(event->pos())) { + event->ignore(); + return; + } + QWaylandInputDevice *inputDevice = compositor()->defaultInputDevice(); inputDevice->sendMouseWheelEvent(event->orientation(), event->delta()); } @@ -218,12 +228,19 @@ void QWaylandSurfaceItem::touchEvent(QTouchEvent *event) { if (m_touchEventsEnabled) { QWaylandInputDevice *inputDevice = compositor()->defaultInputDevice(); + + QPoint pointPos; + const QList<QTouchEvent::TouchPoint> &points = event->touchPoints(); + if (!points.isEmpty()) + pointPos = points.at(0).pos().toPoint(); + + if (event->type() == QEvent::TouchBegin && !surface()->inputRegionContains(pointPos)) { + event->ignore(); + return; + } + event->accept(); if (inputDevice->mouseFocus() != this) { - QPoint pointPos; - QList<QTouchEvent::TouchPoint> points = event->touchPoints(); - if (!points.isEmpty()) - pointPos = points.at(0).pos().toPoint(); inputDevice->setMouseFocus(this, pointPos, pointPos); } inputDevice->sendFullTouchEvent(event); diff --git a/src/compositor/wayland_wrapper/qwlsurface.cpp b/src/compositor/wayland_wrapper/qwlsurface.cpp index 904895f85..171ad1e52 100644 --- a/src/compositor/wayland_wrapper/qwlsurface.cpp +++ b/src/compositor/wayland_wrapper/qwlsurface.cpp @@ -106,6 +106,11 @@ public: bool canSend; }; +static QRegion infiniteRegion() { + return QRegion(QRect(QPoint(std::numeric_limits<int>::min(), std::numeric_limits<int>::min()), + QPoint(std::numeric_limits<int>::max(), std::numeric_limits<int>::max()))); +} + Surface::Surface(struct wl_client *client, uint32_t id, QWaylandCompositor *compositor, QWaylandSurface *surface) : QtWaylandServer::wl_surface(client, id) , m_compositor(compositor->handle()) @@ -116,6 +121,7 @@ Surface::Surface(struct wl_client *client, uint32_t id, QWaylandCompositor *comp , m_extendedSurface(0) , m_subSurface(0) , m_inputPanelSurface(0) + , m_inputRegion(infiniteRegion()) , m_transientParent(0) , m_transientInactive(false) , m_transientOffset(QPointF(0, 0)) @@ -126,6 +132,7 @@ Surface::Surface(struct wl_client *client, uint32_t id, QWaylandCompositor *comp { m_pending.buffer = 0; m_pending.newlyAttached = false; + m_pending.inputRegion = infiniteRegion(); } Surface::~Surface() @@ -192,7 +199,6 @@ void Surface::setSize(const QSize &size) { if (size != m_size) { m_opaqueRegion = QRegion(); - m_inputRegion = QRegion(QRect(QPoint(), size)); m_size = size; m_waylandSurface->sizeChanged(); } @@ -382,7 +388,11 @@ void Surface::surface_set_opaque_region(Resource *, struct wl_resource *region) void Surface::surface_set_input_region(Resource *, struct wl_resource *region) { - m_inputRegion = region ? Region::fromResource(region)->region() : QRegion(QRect(QPoint(), size())); + if (region) { + m_pending.inputRegion = Region::fromResource(region)->region(); + } else { + m_pending.inputRegion = infiniteRegion(); + } } void Surface::surface_commit(Resource *) @@ -409,6 +419,8 @@ void Surface::surface_commit(Resource *) m_frameCallbacks << m_pendingFrameCallbacks; m_pendingFrameCallbacks.clear(); + m_inputRegion = m_pending.inputRegion.intersected(QRect(QPoint(), m_size)); + emit m_waylandSurface->redraw(); } diff --git a/src/compositor/wayland_wrapper/qwlsurface_p.h b/src/compositor/wayland_wrapper/qwlsurface_p.h index ff7b09250..70b86aec6 100644 --- a/src/compositor/wayland_wrapper/qwlsurface_p.h +++ b/src/compositor/wayland_wrapper/qwlsurface_p.h @@ -171,6 +171,7 @@ protected: QRegion damage; QPoint offset; bool newlyAttached; + QRegion inputRegion; } m_pending; QPoint m_lastLocalMousePos; |