summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJan Arne Petersen <jan.petersen@kdab.com>2014-08-10 06:54:55 +0200
committerJan Arne Petersen <jan.petersen@kdab.com>2014-08-13 21:24:40 +0200
commitc288de20291eb5d9a3dc3e3eae16d007fd08afa3 (patch)
treed1fcf22a9e1d84978f76c1b10de255feb8fbbe95 /src
parentbbae1f2afe5aaa8522dfeb6de6c759c54c4292ef (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.cpp10
-rw-r--r--src/client/qwaylanddisplay_p.h1
-rw-r--r--src/client/qwaylandwindow.cpp20
-rw-r--r--src/client/qwaylandwindow_p.h3
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.cpp6
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.h2
-rw-r--r--src/compositor/compositor_api/qwaylandsurfaceitem.cpp25
-rw-r--r--src/compositor/wayland_wrapper/qwlsurface.cpp16
-rw-r--r--src/compositor/wayland_wrapper/qwlsurface_p.h1
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 &region) 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;