Minimal CPP
Minimal CPP는 C++로 Wayland 컴포지터를 작성하는 방법을 보여주는 예제입니다.
Minimal CPP는 C++를 사용하여 완전한 컴포지터( Qt Wayland Compositor )를 구현한 최소한의 컴포지터 예제입니다. QtWaylandCompositor 의 C++ API는 저수준이며, 하드웨어 기능 지원이나 Qt Quick 를 사용할 수 없는 경우와 같은 특수한 용도로 설계되었습니다. QML API는 더 많은 편의성과 기능을 제공합니다. 비교해 보면, ‘Minimal QML’ 예제는 30줄의 QML 코드로 이 예제가 300줄 이상의 코드로 구현한 것보다 더 많은 기능을 구현합니다.

이 예제는 두 부분으로 나뉩니다. Wayland 관련 로직은 ` Compositor ` 클래스에 포함되어 있으며, 사용자 인터페이스는 ` Window ` 클래스에 있습니다.
Window
Window 클래스는 상당히 간단합니다. Wayland 표면을 표시하기 위해, 이 클래스는 컴포지터의 뷰를 순회하며 QOpenGLTextureBlitter 를 사용하여 화면에 렌더링합니다:
void Window::paintGL()
{
m_compositor->startRender();
QOpenGLFunctions *functions = context()->functions();
functions->glClearColor(.4f, .7f, .1f, 0.5f);
functions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLenum currentTarget = GL_TEXTURE_2D;
m_textureBlitter.bind(currentTarget);
functions->glEnable(GL_BLEND);
functions->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
const auto views = m_compositor->views();
for (View *view : views) {
auto texture = view->getTexture();
if (!texture)
continue;
if (texture->target() != currentTarget) {
currentTarget = texture->target();
m_textureBlitter.bind(currentTarget);
}
GLuint textureId = texture->textureId();
QWaylandSurface *surface = view->surface();
if (surface && surface->hasContent()) {
QSize s = surface->destinationSize();
view->initPosition(size(), s);
QPointF pos = view->globalPosition();
QRectF surfaceGeometry(pos, s);
QOpenGLTextureBlitter::Origin surfaceOrigin =
view->currentBuffer().origin() == QWaylandSurface::OriginTopLeft
? QOpenGLTextureBlitter::OriginTopLeft
: QOpenGLTextureBlitter::OriginBottomLeft;
QMatrix4x4 targetTransform = QOpenGLTextureBlitter::targetTransform(surfaceGeometry, QRect(QPoint(), size()));
m_textureBlitter.blit(textureId, targetTransform, surfaceOrigin);
}
}
m_textureBlitter.release();
m_compositor->endRender();
}모든 키보드 및 마우스 이벤트는 컴포지터로 전달됩니다. 예를 들어:
void Window::mousePressEvent(QMouseEvent *event)
{
m_compositor->handleMousePress(event->position().toPoint(), event->button());
}컴포지터
Compositor 클래스는 QML 기반 컴포지터에서 ` WaylandCompositor ` 및 ` WaylandQuickItem `가 처리할 논리의 상당 부분을 구현해야 하므로 더 복잡합니다.
create 함수는 가장 기본적인 셸 확장인 IviApplication 를 사용하여 컴포지터를 설정합니다. 이 함수는 OpenGL 컨텍스트가 초기화된 후에 호출됩니다:
void Compositor::create()
{
QWaylandOutput *output = new QWaylandOutput(this, m_window);
QWaylandOutputMode mode(m_window->size(), 60000);
output->addMode(mode, true);
QWaylandCompositor::create();
output->setCurrentMode(mode);
m_iviApplication = new QWaylandIviApplication(this);
connect(m_iviApplication, &QWaylandIviApplication::iviSurfaceCreated, this, &Compositor::onIviSurfaceCreated);
}마우스 이벤트 및 키보드 포커스에 대한 모든 로직은 암시적 마우스 그랩(초기 마우스 누름을 수신한 표면으로 모든 마우스 이동 신호를 전송하는 것)을 포함하여 수동으로 구현해야 합니다. Wayland 프로토콜의 마우스 누름 이벤트에는 마우스 위치 정보가 포함되지 않으므로, 마우스 누름 이벤트를 수신할 때마다 항상 마우스 이동 신호를 전송해야 합니다:
void Compositor::handleMousePress(const QPoint &position, Qt::MouseButton button)
{
if (!m_mouseView) {
if ((m_mouseView = viewAt(position)))
raise(m_mouseView);
}
auto *seat = defaultSeat();
seat->sendMouseMoveEvent(m_mouseView, mapToView(m_mouseView, position));
seat->sendMousePressEvent(button);
}마우스 버튼이 놓일 때는 암시적 그랩을 종료하고 현재 마우스 위치에 있는 서피스에 알립니다:
void Compositor::handleMousePress(const QPoint &position, Qt::MouseButton button)
{
if (!m_mouseView) {
if ((m_mouseView = viewAt(position)))
raise(m_mouseView);
}
auto *seat = defaultSeat();
seat->sendMouseMoveEvent(m_mouseView, mapToView(m_mouseView, position));
seat->sendMousePressEvent(button);
}새로운 서피스에 대한 알림을 받으면, 이를 추적하기 위해 ` View `를 생성하고, 업데이트를 처리할 수 있도록 신호를 연결합니다.
void Compositor::onIviSurfaceCreated(QWaylandIviSurface *iviSurface)
{
View *view = new View(iviSurface->iviId());
view->setSurface(iviSurface->surface());
view->setOutput(outputFor(m_window));
m_views << view;
connect(view, &QWaylandView::surfaceDestroyed, this, &Compositor::viewSurfaceDestroyed);
connect(iviSurface->surface(), &QWaylandSurface::redraw, this, &Compositor::triggerRender);
}View 클래스는 서페이스의 특정 뷰를 나타내는 QWaylandView 의 서브클래스입니다. advance 함수는 뷰의 현재 버퍼를 업데이트하며, 새로운 콘텐츠가 있을 경우 true를 반환합니다. getTexture 함수는 Window 클래스가 활용할 수 있도록 버퍼 내용을 OpenGL 텍스처로 제공합니다:
QOpenGLTexture *View::getTexture() {
if (advance())
m_texture = currentBuffer().toOpenGLTexture();
return m_texture;
}© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.