summaryrefslogtreecommitdiffstats
path: root/examples/wayland/minimal-cpp/compositor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'examples/wayland/minimal-cpp/compositor.cpp')
-rw-r--r--examples/wayland/minimal-cpp/compositor.cpp105
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()