summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Olav Tvete <paul.tvete@qt.io>2023-02-08 14:22:06 +0100
committerPaul Olav Tvete <paul.tvete@qt.io>2023-02-13 12:00:37 +0000
commit90e2ade38721febbf2cb8897779153de4d789a10 (patch)
treeaa4bee60736d838235cb2bdfe2186c6ead0031f4
parent8403a0a20121bab3c655b43cbfc11c794992af60 (diff)
downloadqtwayland-90e2ade38721febbf2cb8897779153de4d789a10.tar.gz
Documentation for the minimal-cpp example
Change-Id: Ib06f5360c19e7656dcda5555e04b0f8f8a8e8d50 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> (cherry picked from commit c492d61165f83cf1cbade21f4483131f979f3e04) Reviewed-by: Inho Lee <inho.lee@qt.io>
-rw-r--r--examples/wayland/minimal-cpp/compositor.cpp20
-rw-r--r--examples/wayland/minimal-cpp/compositor.h2
-rw-r--r--examples/wayland/minimal-cpp/doc/images/minimal-cpp.jpgbin0 -> 34734 bytes
-rw-r--r--examples/wayland/minimal-cpp/doc/src/minimal-cpp.qdoc66
-rw-r--r--examples/wayland/minimal-cpp/window.cpp6
5 files changed, 85 insertions, 9 deletions
diff --git a/examples/wayland/minimal-cpp/compositor.cpp b/examples/wayland/minimal-cpp/compositor.cpp
index c07068db..83b773b2 100644
--- a/examples/wayland/minimal-cpp/compositor.cpp
+++ b/examples/wayland/minimal-cpp/compositor.cpp
@@ -12,11 +12,13 @@
#include <QRandomGenerator>
#include <QOpenGLFunctions>
+//! [getTexture]
QOpenGLTexture *View::getTexture() {
if (advance())
m_texture = currentBuffer().toOpenGLTexture();
return m_texture;
}
+//! [getTexture]
QPoint View::mapToLocal(const QPoint &globalPos) const
{
@@ -48,6 +50,7 @@ Compositor::~Compositor()
{
}
+//! [create]
void Compositor::create()
{
QWaylandOutput *output = new QWaylandOutput(this, m_window);
@@ -59,6 +62,7 @@ void Compositor::create()
m_iviApplication = new QWaylandIviApplication(this);
connect(m_iviApplication, &QWaylandIviApplication::iviSurfaceCreated, this, &Compositor::onIviSurfaceCreated);
}
+//! [create]
View *Compositor::viewAt(const QPoint &position)
{
@@ -85,17 +89,20 @@ static inline QPoint mapToView(const View *view, const QPoint &position)
return view ? view->mapToLocal(position) : position;
}
+//! [handleMousePress]
void Compositor::handleMousePress(const QPoint &position, Qt::MouseButton button)
{
if (!m_mouseView) {
- if (m_mouseView = viewAt(position))
+ if ((m_mouseView = viewAt(position)))
raise(m_mouseView);
}
auto *seat = defaultSeat();
seat->sendMouseMoveEvent(m_mouseView, mapToView(m_mouseView, position));
seat->sendMousePressEvent(button);
}
+//! [handleMousePress]
+//! [handleMouseRelease]
void Compositor::handleMouseRelease(const QPoint &position, Qt::MouseButton button, Qt::MouseButtons buttons)
{
auto *seat = defaultSeat();
@@ -109,6 +116,7 @@ void Compositor::handleMouseRelease(const QPoint &position, Qt::MouseButton butt
m_mouseView = nullptr;
}
}
+//! [handleMouseRelease]
void Compositor::handleMouseMove(const QPoint &position)
{
@@ -135,7 +143,7 @@ void Compositor::handleKeyRelease(quint32 nativeScanCode)
defaultSeat()->sendKeyReleaseEvent(nativeScanCode);
}
-
+//! [surfaceCreated]
void Compositor::onIviSurfaceCreated(QWaylandIviSurface *iviSurface)
{
View *view = new View(iviSurface->iviId());
@@ -146,12 +154,9 @@ void Compositor::onIviSurfaceCreated(QWaylandIviSurface *iviSurface)
connect(view, &QWaylandView::surfaceDestroyed, this, &Compositor::viewSurfaceDestroyed);
connect(iviSurface->surface(), &QWaylandSurface::redraw, this, &Compositor::triggerRender);
}
+//! [surfaceCreated]
-void Compositor::onSurfaceDestroyed()
-{
- triggerRender();
-}
-
+//! [surfaceDestroyed]
void Compositor::viewSurfaceDestroyed()
{
View *view = qobject_cast<View*>(sender());
@@ -159,6 +164,7 @@ void Compositor::viewSurfaceDestroyed()
delete view;
triggerRender();
}
+//! [surfaceDestroyed]
void Compositor::triggerRender()
{
diff --git a/examples/wayland/minimal-cpp/compositor.h b/examples/wayland/minimal-cpp/compositor.h
index c010a796..8ba6c8d1 100644
--- a/examples/wayland/minimal-cpp/compositor.h
+++ b/examples/wayland/minimal-cpp/compositor.h
@@ -33,7 +33,6 @@ public:
void initPosition(const QSize &screenSize, const QSize &surfaceSize);
private:
- friend class Compositor;
QOpenGLTexture *m_texture = nullptr;
bool m_positionSet = false;
QPoint m_pos;
@@ -65,7 +64,6 @@ public:
private slots:
void onIviSurfaceCreated(QWaylandIviSurface *iviSurface);
- void onSurfaceDestroyed();
void triggerRender();
void viewSurfaceDestroyed();
diff --git a/examples/wayland/minimal-cpp/doc/images/minimal-cpp.jpg b/examples/wayland/minimal-cpp/doc/images/minimal-cpp.jpg
new file mode 100644
index 00000000..d7c8a1cf
--- /dev/null
+++ b/examples/wayland/minimal-cpp/doc/images/minimal-cpp.jpg
Binary files differ
diff --git a/examples/wayland/minimal-cpp/doc/src/minimal-cpp.qdoc b/examples/wayland/minimal-cpp/doc/src/minimal-cpp.qdoc
new file mode 100644
index 00000000..a9092170
--- /dev/null
+++ b/examples/wayland/minimal-cpp/doc/src/minimal-cpp.qdoc
@@ -0,0 +1,66 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \title Qt Wayland Compositor Examples - Minimal CPP
+ \example minimal-cpp
+ \brief Minimal CPP is an example that demonstrates how to write a Wayland compositor in C++.
+ \ingroup qtwaylandcompositor-examples
+
+ Minimal CPP is a minimalistic compositor example implementing a complete Qt Wayland Compositor
+ using C++. The C++ API of QtWaylandCompositor is low-level and intended for specialized
+ applications, such as supporting hardware features, or if Qt Quick is not available. The QML API
+ offers more convenience and functionality. For comparison, the
+ \l{Qt Wayland Compositor Examples - Minimal QML}{Minimal QML example} implements more
+ functionality with 30 lines of QML than this example does in 300+ lines.
+
+ \image minimal-cpp.jpg
+
+ This example is split in two parts. The Wayland logic is contained in the \c Compositor class,
+ and the user interface is in the \c Window class.
+
+ \section1 Window
+
+ The \c Window class is fairly straight-forward. To display the Wayland surfaces, it iterates
+ through the compositor's views and renders them on the screen using \l QOpenGLTextureBlitter:
+
+ \snippet minimal-cpp/window.cpp paintGL
+
+ All keyboard and mouse events are delivered to the compositor. For example:
+
+ \snippet minimal-cpp/window.cpp mousePressEvent
+
+ \section1 Compositor
+
+ The \c Compositor class is more complex, since it has to implement much of the logic that would
+ be handled by \l[QML]{WaylandCompositor} and \l[QML]{WaylandQuickItem} in a QML-based compositor.
+
+ The \c create function sets up the compositor, using the IviApplication, which is the most basic
+ shell extension. The function is called after the OpenGL context has been initialized:
+
+ \snippet minimal-cpp/compositor.cpp create
+
+ All the logic for mouse events and keyboard focus has to be implemented manually, including
+ implicit mouse grabs (sending all mouse moves to the surface that received the initial mouse
+ press). Note that mouse press events in the Wayland protocol do not contain the mouse position,
+ so we always have to send a mouse move when we reveive a mouse press:
+
+ \snippet minimal-cpp/compositor.cpp handleMousePress
+
+ For a mouse release, we end the implicit grab and notify the surface at the current mouse position:
+
+ \snippet minimal-cpp/compositor.cpp handleMousePress
+
+ When we are notified of a new surface, we create a \c View to keep track of it, and connect
+ signals so we can handle updates.
+
+ \snippet minimal-cpp/compositor.cpp surfaceCreated
+
+ The \c View class subclasses QWaylandView, which represents a specific view of a surface. The
+ \l {QWaylandView::advance}{advance} function updates the view's current buffer and returns true
+ if there is new content. The \c getTexture function makes the buffer contents available as an
+ OpenGL texture for the benefit of the \c Window class:
+
+ \snippet minimal-cpp/compositor.cpp getTexture
+
+*/
diff --git a/examples/wayland/minimal-cpp/window.cpp b/examples/wayland/minimal-cpp/window.cpp
index 4c39505d..68f0a25d 100644
--- a/examples/wayland/minimal-cpp/window.cpp
+++ b/examples/wayland/minimal-cpp/window.cpp
@@ -24,6 +24,7 @@ void Window::initializeGL()
emit glReady();
}
+//! [paintGL]
void Window::paintGL()
{
m_compositor->startRender();
@@ -64,11 +65,14 @@ void Window::paintGL()
m_textureBlitter.release();
m_compositor->endRender();
}
+//! [paintGL]
+//! [mousePressEvent]
void Window::mousePressEvent(QMouseEvent *event)
{
m_compositor->handleMousePress(event->position().toPoint(), event->button());
}
+//! [mousePressEvent]
void Window::mouseReleaseEvent(QMouseEvent *event)
{
@@ -85,10 +89,12 @@ void Window::wheelEvent(QWheelEvent *event)
m_compositor->handleMouseWheel(event->angleDelta());
}
+//! [keyPressEvent]
void Window::keyPressEvent(QKeyEvent *e)
{
m_compositor->handleKeyPress(e->nativeScanCode());
}
+//! [keyPressEvent]
void Window::keyReleaseEvent(QKeyEvent *e)
{