summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorPaul Olav Tvete <paul.tvete@theqtcompany.com>2015-12-09 14:38:30 +0100
committerPaul Olav Tvete <paul.tvete@theqtcompany.com>2016-02-04 12:08:58 +0000
commit933d69af3061e9fdfe9e9ca1ea61055aac2c0482 (patch)
tree0fccef825cf65421816d7a4104c01bd735b87495 /examples
parent93ca929fb9caf34715012dec608afd42e6ccf1e5 (diff)
Subsurface implementation, with C++ API
This adds support for subsurfaces to QWaylandCompositor and QWaylandSurface. Task-number: QTBUG-49809 Change-Id: I2fa9ee4dcd1f48a2a28dab536f9cd6edc716e42b Reviewed-by: Giulio Camuffo <giuliocamuffo@gmail.com>
Diffstat (limited to 'examples')
-rw-r--r--examples/wayland/qwindow-compositor/compositorwindow.cpp3
-rw-r--r--examples/wayland/qwindow-compositor/windowcompositor.cpp65
-rw-r--r--examples/wayland/qwindow-compositor/windowcompositor.h10
-rw-r--r--examples/wayland/subsurface/main.qml18
4 files changed, 90 insertions, 6 deletions
diff --git a/examples/wayland/qwindow-compositor/compositorwindow.cpp b/examples/wayland/qwindow-compositor/compositorwindow.cpp
index a902a7d0d..4b69022f2 100644
--- a/examples/wayland/qwindow-compositor/compositorwindow.cpp
+++ b/examples/wayland/qwindow-compositor/compositorwindow.cpp
@@ -107,7 +107,8 @@ void CompositorWindow::paintGL()
if (surface && surface->isMapped()) {
QSize s = surface->size();
if (!s.isEmpty()) {
- QRectF surfaceGeometry(view->position(), s);
+ QPointF pos = view->position() + view->parentPosition();
+ QRectF surfaceGeometry(pos, s);
QOpenGLTextureBlitter::Origin surfaceOrigin =
view->currentBuffer().origin() == QWaylandSurface::OriginTopLeft
? QOpenGLTextureBlitter::OriginTopLeft
diff --git a/examples/wayland/qwindow-compositor/windowcompositor.cpp b/examples/wayland/qwindow-compositor/windowcompositor.cpp
index f271570de..57d6b382f 100644
--- a/examples/wayland/qwindow-compositor/windowcompositor.cpp
+++ b/examples/wayland/qwindow-compositor/windowcompositor.cpp
@@ -88,6 +88,8 @@ void WindowCompositor::create()
connect(this, &QWaylandCompositor::surfaceCreated, this, &WindowCompositor::onSurfaceCreated);
connect(defaultInputDevice(), &QWaylandInputDevice::cursorSurfaceRequest, this, &WindowCompositor::adjustCursorSurface);
connect(defaultInputDevice()->drag(), &QWaylandDrag::dragStarted, this, &WindowCompositor::startDrag);
+
+ connect(this, &QWaylandCompositor::subsurfaceChanged, this, &WindowCompositor::onSubsurfaceChanged);
}
void WindowCompositor::onSurfaceCreated(QWaylandSurface *surface)
@@ -96,6 +98,9 @@ void WindowCompositor::onSurfaceCreated(QWaylandSurface *surface)
connect(surface, &QWaylandSurface::mappedChanged, this, &WindowCompositor::surfaceMappedChanged);
connect(surface, &QWaylandSurface::redraw, this, &WindowCompositor::triggerRender);
connect(surface, &QWaylandSurface::offsetForNextFrame, this, &WindowCompositor::frameOffset);
+
+ connect(surface, &QWaylandSurface::subsurfacePositionChanged, this, &WindowCompositor::onSubsurfacePositionChanged);
+
WindowCompositorView *view = new WindowCompositorView;
view->setSurface(surface);
view->setOutput(outputFor(m_window));
@@ -167,9 +172,17 @@ void WindowCompositor::onStartResize(QWaylandInputDevice *, QWaylandShellSurface
emit startResize(int(edges));
}
-void WindowCompositor::onSetTransient(QWaylandSurface *parentSurface, const QPoint &relativeToParent, QWaylandShellSurface::FocusPolicy focusPolicy)
+void WindowCompositor::onSetTransient(QWaylandSurface *parent, const QPoint &relativeToParent, QWaylandShellSurface::FocusPolicy focusPolicy)
{
- qDebug() << "Transient window support not implemented" << parentSurface << relativeToParent << focusPolicy;
+ QWaylandShellSurface *surface = qobject_cast<QWaylandShellSurface*>(sender());
+ WindowCompositorView *view = findView(surface->surface());
+
+ if (view) {
+ raise(view);
+ WindowCompositorView *parentView = findView(parent);
+ if (parentView)
+ view->setPosition(parentView->position() + relativeToParent);
+ }
}
void WindowCompositor::onSetPopup(QWaylandInputDevice *inputDevice, QWaylandSurface *parent, const QPoint &relativeToParent)
@@ -186,6 +199,23 @@ void WindowCompositor::onSetPopup(QWaylandInputDevice *inputDevice, QWaylandSurf
}
}
+void WindowCompositor::onSubsurfaceChanged(QWaylandSurface *child, QWaylandSurface *parent)
+{
+ WindowCompositorView *view = findView(child);
+ WindowCompositorView *parentView = findView(parent);
+ view->setParentView(parentView);
+}
+
+void WindowCompositor::onSubsurfacePositionChanged(const QPoint &position)
+{
+ QWaylandSurface *surface = qobject_cast<QWaylandSurface*>(sender());
+ if (!surface)
+ return;
+ WindowCompositorView *view = findView(surface);
+ view->setPosition(position);
+ triggerRender();
+}
+
void WindowCompositor::triggerRender()
{
m_window->requestUpdate();
@@ -288,8 +318,35 @@ void WindowCompositor::handleDrag(WindowCompositorView *target, QMouseEvent *me)
currentDrag->drop();
}
+// We only have a flat list of views, plus pointers from child to parent,
+// so maintaining a stacking order gets a bit complex. A better data
+// structure is left as an exercise for the reader.
+
+static int findEndOfChildTree(const QList<WindowCompositorView*> &list, int index)
+{
+ int n = list.count();
+ WindowCompositorView *parent = list.at(index);
+ while (index + 1 < n) {
+ if (list.at(index+1)->parentView() != parent)
+ break;
+ index = findEndOfChildTree(list, index + 1);
+ }
+ return index;
+}
+
void WindowCompositor::raise(WindowCompositorView *view)
{
- m_views.removeOne(view);
- m_views.append(view);
+ int startPos = m_views.indexOf(view);
+ int endPos = findEndOfChildTree(m_views, startPos);
+
+ int n = m_views.count();
+ int tail = n - endPos - 1;
+
+ //bubble sort: move the child tree to the end of the list
+ for (int i = 0; i < tail; i++) {
+ int source = endPos + 1 + i;
+ int dest = startPos + i;
+ for (int j = source; j > dest; j--)
+ m_views.swap(j, j-1);
+ }
}
diff --git a/examples/wayland/qwindow-compositor/windowcompositor.h b/examples/wayland/qwindow-compositor/windowcompositor.h
index 98cc88f6a..7a4f90aad 100644
--- a/examples/wayland/qwindow-compositor/windowcompositor.h
+++ b/examples/wayland/qwindow-compositor/windowcompositor.h
@@ -56,17 +56,22 @@ class WindowCompositorView : public QWaylandView
{
Q_OBJECT
public:
- WindowCompositorView() : m_texture(0), m_shellSurface(0) {}
+ WindowCompositorView() : m_texture(0), m_shellSurface(0), m_parentView(0) {}
GLuint getTexture();
QPointF position() const { return m_position; }
void setPosition(const QPointF &pos) { m_position = pos; }
bool isCursor() const;
bool hasShell() const { return m_shellSurface; }
+ void setParentView(WindowCompositorView *parent) { m_parentView = parent; }
+ WindowCompositorView *parentView() const { return m_parentView; }
+ QPointF parentPosition() const { return m_parentView ? (m_parentView->position() + m_parentView->parentPosition()) : QPointF(); }
+
private:
friend class WindowCompositor;
GLuint m_texture;
QPointF m_position;
QWaylandShellSurface *m_shellSurface;
+ WindowCompositorView *m_parentView;
};
class WindowCompositor : public QWaylandCompositor
@@ -114,6 +119,9 @@ private slots:
void onSetTransient(QWaylandSurface *parentSurface, const QPoint &relativeToParent, QWaylandShellSurface::FocusPolicy focusPolicy);
void onSetPopup(QWaylandInputDevice *inputDevice, QWaylandSurface *parent, const QPoint &relativeToParent);
+ void onSubsurfaceChanged(QWaylandSurface *child, QWaylandSurface *parent);
+ void onSubsurfacePositionChanged(const QPoint &position);
+
void updateCursor();
private:
WindowCompositorView *findView(const QWaylandSurface *s) const;
diff --git a/examples/wayland/subsurface/main.qml b/examples/wayland/subsurface/main.qml
index fa71d4b6b..8d221401b 100644
--- a/examples/wayland/subsurface/main.qml
+++ b/examples/wayland/subsurface/main.qml
@@ -69,4 +69,22 @@ Rectangle {
anchors.horizontalCenter: parent.horizontalCenter
text: syncStatus.sync ? "sync mode" : "de-sync mode"
}
+
+ // If you can see these rectangles, something's not right
+ Rectangle {
+ //Child at (150, 70, 100, 100)
+ color: "yellow"
+ x: 150
+ y: 70
+ width:100
+ height:100
+ }
+ Rectangle {
+ //Shm at (30, 30, 50, 50)
+ color: "yellow"
+ x: 30
+ y: 30
+ width: 50
+ height: 50
+ }
}