최소 CPP
Minimal CPP는 C++로 Wayland 컴포저를 작성하는 방법을 보여주는 예제입니다.
Minimal CPP는 C++를 사용하여 완전한 Qt Wayland Compositor 을 구현하는 최소한의 컴포저 예제입니다. QtWaylandCompositor 의 C++ API는 저수준이며 하드웨어 기능을 지원하거나 Qt Quick 을 사용할 수 없는 경우와 같은 특수한 애플리케이션을 위한 것입니다. QML API는 더 많은 편의성과 기능을 제공합니다. 비교를 위해 최소한의 QML 예제는 이 예제가 300개 이상의 줄로 구현하는 것보다 30줄의 QML로 더 많은 기능을 구현합니다.
이 예제는 두 부분으로 나뉩니다. Wayland 로직은 Compositor
클래스에 포함되어 있고, 사용자 인터페이스는 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
Compositor
클래스는 WaylandCompositor 및 WaylandQuickItem 에서 처리할 로직의 대부분을 QML 기반 컴포저에서 구현해야 하므로 더 복잡합니다.
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); }
마우스 이벤트와 키보드 포커스에 대한 모든 로직은 수동으로 구현해야 하며, 여기에는 암시적 마우스 잡기(모든 마우스 움직임을 초기 마우스 프레스를 받은 표면으로 전송)가 포함됩니다. 웨이랜드 프로토콜의 마우스 누름 이벤트에는 마우스 위치가 포함되지 않으므로 마우스 누름을 드러낼 때는 항상 마우스 이동을 전송해야 합니다:
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 함수는 뷰의 현재 버퍼를 업데이트하고 새 콘텐츠가 있으면 참을 반환합니다. getTexture
함수는 Window
클래스의 이점을 위해 버퍼 콘텐츠를 OpenGL 텍스처로 사용할 수 있도록 합니다:
QOpenGLTexture *View::getTexture() { if (advance()) m_texture = currentBuffer().toOpenGLTexture(); return m_texture; }
© 2025 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.