summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorPaul Olav Tvete <paul.tvete@qt.io>2018-08-15 13:31:21 +0200
committerPaul Olav Tvete <paul.tvete@qt.io>2018-08-16 12:56:52 +0000
commitbc9fc09caf4f638005977281dc57e7d9c99cfddf (patch)
tree1ab1396a264c28afcc5b260cdc9445c44bb87a27 /examples
parent70f0f02568e3d577452e45b49deee47cf7d465b3 (diff)
Add mouse and keyboard handling to minimal-cpp example
...and do some other minor cleanups. Change-Id: I7fe2c70d8b2de37cee5cc114cc0148d31821e10f Reviewed-by: Johan Helsing <johan.helsing@qt.io>
Diffstat (limited to 'examples')
-rw-r--r--examples/wayland/minimal-cpp/compositor.cpp105
-rw-r--r--examples/wayland/minimal-cpp/compositor.h25
-rw-r--r--examples/wayland/minimal-cpp/main.cpp3
-rw-r--r--examples/wayland/minimal-cpp/window.cpp46
-rw-r--r--examples/wayland/minimal-cpp/window.h7
5 files changed, 168 insertions, 18 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()
diff --git a/examples/wayland/minimal-cpp/compositor.h b/examples/wayland/minimal-cpp/compositor.h
index e804ac02f..f06421320 100644
--- a/examples/wayland/minimal-cpp/compositor.h
+++ b/examples/wayland/minimal-cpp/compositor.h
@@ -54,6 +54,7 @@
#include <QtWaylandCompositor/QWaylandCompositor>
#include <QtWaylandCompositor/QWaylandSurface>
#include <QtWaylandCompositor/QWaylandView>
+#include <QtCore/QPointer>
QT_BEGIN_NAMESPACE
@@ -66,12 +67,23 @@ class View : public QWaylandView
{
Q_OBJECT
public:
- View(int iviId) : m_iviId(iviId) {}
+ explicit View(int iviId) : m_iviId(iviId) {}
QOpenGLTexture *getTexture();
int iviId() const { return m_iviId; }
+
+ QRect globalGeometry() const { return QRect(globalPosition(), surface()->size()); }
+ void setGlobalPosition(const QPoint &globalPos) { m_pos = globalPos; m_positionSet = true; }
+ QPoint globalPosition() const { return m_pos; }
+ QPoint mapToLocal(const QPoint &globalPos) const;
+ QSize size() const { return surface() ? surface()->size() : QSize(); }
+
+ void initPosition(const QSize &screenSize, const QSize &surfaceSize);
+
private:
friend class Compositor;
QOpenGLTexture *m_texture = nullptr;
+ bool m_positionSet = false;
+ QPoint m_pos;
int m_iviId;
};
@@ -84,6 +96,16 @@ public:
void create() override;
QList<View*> views() const { return m_views; }
+ View *viewAt(const QPoint &position);
+ void raise(View *view);
+
+ void handleMousePress(const QPoint &position, Qt::MouseButton button);
+ void handleMouseRelease(const QPoint &position, Qt::MouseButton button, Qt::MouseButtons buttons);
+ void handleMouseMove(const QPoint &position);
+ void handleMouseWheel(Qt::Orientation orientation, int delta);
+
+ void handleKeyPress(quint32 nativeScanCode);
+ void handleKeyRelease(quint32 nativeScanCode);
void startRender();
void endRender();
@@ -98,6 +120,7 @@ private:
Window *m_window = nullptr;
QWaylandIviApplication *m_iviApplication = nullptr;
QList<View*> m_views;
+ QPointer<View> m_mouseView;
};
QT_END_NAMESPACE
diff --git a/examples/wayland/minimal-cpp/main.cpp b/examples/wayland/minimal-cpp/main.cpp
index f2b00e889..0b0b4b9d8 100644
--- a/examples/wayland/minimal-cpp/main.cpp
+++ b/examples/wayland/minimal-cpp/main.cpp
@@ -57,10 +57,9 @@ int main(int argc, char *argv[])
QGuiApplication app(argc, argv);
Window window;
+ window.resize(800,600);
Compositor compositor(&window);
- window.setCompositor(&compositor);
compositor.create();
- window.resize(800,600);
window.show();
return app.exec();
diff --git a/examples/wayland/minimal-cpp/window.cpp b/examples/wayland/minimal-cpp/window.cpp
index c43255dfc..673e15fd8 100644
--- a/examples/wayland/minimal-cpp/window.cpp
+++ b/examples/wayland/minimal-cpp/window.cpp
@@ -55,7 +55,7 @@
#include <QMatrix4x4>
#include <QOpenGLFunctions>
#include <QOpenGLTexture>
-#include <QRandomGenerator>
+#include <QMouseEvent>
Window::Window()
{
@@ -70,14 +70,6 @@ void Window::initializeGL()
m_textureBlitter.create();
}
-static QPoint sillyrandom(int seed, QSize screenSize, QSize surfaceSize)
-{
- QRandomGenerator rand(seed);
- int xrange = qMax(screenSize.width() - surfaceSize.width(), 200);
- int yrange = qMax(screenSize.height() - surfaceSize.height(), 200);
- return QPoint(rand.bounded(xrange), rand.bounded(yrange));
-}
-
void Window::paintGL()
{
m_compositor->startRender();
@@ -91,7 +83,8 @@ void Window::paintGL()
functions->glEnable(GL_BLEND);
functions->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- Q_FOREACH (View *view, m_compositor->views()) {
+ const auto views = m_compositor->views();
+ for (View *view : views) {
auto texture = view->getTexture();
if (!texture)
continue;
@@ -103,7 +96,8 @@ void Window::paintGL()
QWaylandSurface *surface = view->surface();
if (surface && surface->hasContent()) {
QSize s = surface->size();
- QPointF pos = sillyrandom(view->iviId(), size(), s);
+ view->initPosition(size(), s);
+ QPointF pos = view->globalPosition();
QRectF surfaceGeometry(pos, s);
QOpenGLTextureBlitter::Origin surfaceOrigin =
view->currentBuffer().origin() == QWaylandSurface::OriginTopLeft
@@ -116,3 +110,33 @@ void Window::paintGL()
m_textureBlitter.release();
m_compositor->endRender();
}
+
+void Window::mousePressEvent(QMouseEvent *event)
+{
+ m_compositor->handleMousePress(event->localPos().toPoint(), event->button());
+}
+
+void Window::mouseReleaseEvent(QMouseEvent *event)
+{
+ m_compositor->handleMouseRelease(event->localPos().toPoint(), event->button(), event->buttons());
+}
+
+void Window::mouseMoveEvent(QMouseEvent *event)
+{
+ m_compositor->handleMouseMove(event->localPos().toPoint());
+}
+
+void Window::wheelEvent(QWheelEvent *event)
+{
+ m_compositor->handleMouseWheel(event->orientation(), event->delta());
+}
+
+void Window::keyPressEvent(QKeyEvent *e)
+{
+ m_compositor->handleKeyPress(e->nativeScanCode());
+}
+
+void Window::keyReleaseEvent(QKeyEvent *e)
+{
+ m_compositor->handleKeyRelease(e->nativeScanCode());
+}
diff --git a/examples/wayland/minimal-cpp/window.h b/examples/wayland/minimal-cpp/window.h
index 2a7a1109a..1a106da9c 100644
--- a/examples/wayland/minimal-cpp/window.h
+++ b/examples/wayland/minimal-cpp/window.h
@@ -67,6 +67,13 @@ public:
protected:
void initializeGL() override;
void paintGL() override;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void wheelEvent(QWheelEvent *) override;
+
+ void keyPressEvent(QKeyEvent *e) override;
+ void keyReleaseEvent(QKeyEvent *e) override;
private:
QOpenGLTextureBlitter m_textureBlitter;