diff options
Diffstat (limited to 'examples/wayland/minimal-cpp/compositor.cpp')
-rw-r--r-- | examples/wayland/minimal-cpp/compositor.cpp | 105 |
1 files changed, 101 insertions, 4 deletions
diff --git a/examples/wayland/minimal-cpp/compositor.cpp b/examples/wayland/minimal-cpp/compositor.cpp index e19fb0d68..81b1be269 100644 --- a/examples/wayland/minimal-cpp/compositor.cpp +++ b/examples/wayland/minimal-cpp/compositor.cpp @@ -51,9 +51,12 @@ #include "compositor.h" #include "window.h" -#include <QtWaylandCompositor/qwaylandoutput.h> -#include <QtWaylandCompositor/qwaylandiviapplication.h> -#include <QtWaylandCompositor/qwaylandivisurface.h> +#include <QtWaylandCompositor/QWaylandOutput> +#include <QtWaylandCompositor/QWaylandIviApplication> +#include <QtWaylandCompositor/QWaylandIviSurface> +#include <QtWaylandCompositor/QWaylandSeat> + +#include <QRandomGenerator> #include <QOpenGLFunctions> QOpenGLTexture *View::getTexture() { @@ -62,9 +65,29 @@ QOpenGLTexture *View::getTexture() { return m_texture; } +QPoint View::mapToLocal(const QPoint &globalPos) const +{ + return globalPos - globalPosition(); +} + + +// Normally, an IVI based compositor would have a design where each window has +// a defined position, based on the id. In this example, we just assign a random position. + +void View::initPosition(const QSize &screenSize, const QSize &surfaceSize) +{ + if (m_positionSet) + return; + QRandomGenerator rand(iviId()); + int xrange = qMax(screenSize.width() - surfaceSize.width(), 1); + int yrange = qMax(screenSize.height() - surfaceSize.height(), 1); + setGlobalPosition(QPoint(rand.bounded(xrange), rand.bounded(yrange))); +} + Compositor::Compositor(Window *window) : m_window(window) { + window->setCompositor(this); } Compositor::~Compositor() @@ -74,7 +97,7 @@ Compositor::~Compositor() void Compositor::create() { QWaylandOutput *output = new QWaylandOutput(this, m_window); - QWaylandOutputMode mode(QSize(800, 600), 60000); + QWaylandOutputMode mode(m_window->size(), 60000); output->addMode(mode, true); QWaylandCompositor::create(); output->setCurrentMode(mode); @@ -83,11 +106,84 @@ void Compositor::create() connect(m_iviApplication, &QWaylandIviApplication::iviSurfaceCreated, this, &Compositor::onIviSurfaceCreated); } +View *Compositor::viewAt(const QPoint &position) +{ + // Since views are stored in painting order (back to front), we have to iterate backwards + // to find the topmost view at a given point. + for (auto it = m_views.crbegin(); it != m_views.crend(); ++it) { + View *view = *it; + if (view->globalGeometry().contains(position)) + return view; + } + return nullptr; +} + +void Compositor::raise(View *view) +{ + m_views.removeAll(view); + m_views.append(view); + defaultSeat()->setKeyboardFocus(view->surface()); + triggerRender(); +} + +static inline QPoint mapToView(const View *view, const QPoint &position) +{ + return view ? view->mapToLocal(position) : position; +} + +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::handleMouseRelease(const QPoint &position, Qt::MouseButton button, Qt::MouseButtons buttons) +{ + auto *seat = defaultSeat(); + seat->sendMouseMoveEvent(m_mouseView, mapToView(m_mouseView, position)); + seat->sendMouseReleaseEvent(button); + + if (buttons == Qt::NoButton) { + View *newView = viewAt(position); + if (newView != m_mouseView) + seat->sendMouseMoveEvent(newView, mapToView(newView, position)); + m_mouseView = nullptr; + } +} + +void Compositor::handleMouseMove(const QPoint &position) +{ + View *view = m_mouseView ? m_mouseView.data() : viewAt(position); + defaultSeat()->sendMouseMoveEvent(view, mapToView(view, position)); +} + +void Compositor::handleMouseWheel(Qt::Orientation orientation, int delta) +{ + defaultSeat()->sendMouseWheelEvent(orientation, delta); +} + +void Compositor::handleKeyPress(quint32 nativeScanCode) +{ + defaultSeat()->sendKeyPressEvent(nativeScanCode); +} + +void Compositor::handleKeyRelease(quint32 nativeScanCode) +{ + defaultSeat()->sendKeyReleaseEvent(nativeScanCode); +} + + 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); @@ -103,6 +199,7 @@ void Compositor::viewSurfaceDestroyed() View *view = qobject_cast<View*>(sender()); m_views.removeAll(view); delete view; + triggerRender(); } void Compositor::triggerRender() |