summaryrefslogtreecommitdiffstats
path: root/examples/wayland/qwindow-compositor/compositorwindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'examples/wayland/qwindow-compositor/compositorwindow.cpp')
-rw-r--r--examples/wayland/qwindow-compositor/compositorwindow.cpp220
1 files changed, 206 insertions, 14 deletions
diff --git a/examples/wayland/qwindow-compositor/compositorwindow.cpp b/examples/wayland/qwindow-compositor/compositorwindow.cpp
index 7d855016f..a902a7d0d 100644
--- a/examples/wayland/qwindow-compositor/compositorwindow.cpp
+++ b/examples/wayland/qwindow-compositor/compositorwindow.cpp
@@ -39,23 +39,215 @@
****************************************************************************/
#include "compositorwindow.h"
-#include <QTouchEvent>
-CompositorWindow::CompositorWindow(const QSurfaceFormat &format, const QRect &geometry)
- : m_format(format)
+#include <QMouseEvent>
+#include <QOpenGLWindow>
+#include <QOpenGLTexture>
+#include <QOpenGLFunctions>
+#include <QMatrix4x4>
+
+#include "windowcompositor.h"
+#include <QtWaylandCompositor/qwaylandinput.h>
+
+CompositorWindow::CompositorWindow()
+ : m_backgroundTexture(0)
+ , m_compositor(0)
+ , m_grabState(NoGrab)
+ , m_dragIconView(0)
+{
+}
+
+void CompositorWindow::setCompositor(WindowCompositor *comp) {
+ m_compositor = comp;
+ connect(m_compositor, &WindowCompositor::startMove, this, &CompositorWindow::startMove);
+ connect(m_compositor, &WindowCompositor::startResize, this, &CompositorWindow::startResize);
+ connect(m_compositor, &WindowCompositor::dragStarted, this, &CompositorWindow::startDrag);
+ connect(m_compositor, &WindowCompositor::frameOffset, this, &CompositorWindow::setFrameOffset);
+}
+
+void CompositorWindow::initializeGL()
+{
+ QImage backgroundImage = QImage(QLatin1String(":/background.jpg"));
+ m_backgroundTexture = new QOpenGLTexture(backgroundImage, QOpenGLTexture::DontGenerateMipMaps);
+ m_backgroundTexture->setMinificationFilter(QOpenGLTexture::Nearest);
+ m_backgroundImageSize = backgroundImage.size();
+ m_textureBlitter.create();
+}
+
+void CompositorWindow::drawBackground()
+{
+ for (int y = 0; y < height(); y += m_backgroundImageSize.height()) {
+ for (int x = 0; x < width(); x += m_backgroundImageSize.width()) {
+ QMatrix4x4 targetTransform = QOpenGLTextureBlitter::targetTransform(QRect(QPoint(x,y), m_backgroundImageSize), QRect(QPoint(0,0), size()));
+ m_textureBlitter.blit(m_backgroundTexture->textureId(),
+ targetTransform,
+ QOpenGLTextureBlitter::OriginTopLeft);
+ }
+ }
+}
+
+void CompositorWindow::paintGL()
+{
+ m_compositor->startRender();
+ QOpenGLFunctions *functions = context()->functions();
+ functions->glClearColor(1.f, .6f, .0f, 0.5f);
+ functions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ m_textureBlitter.bind();
+ drawBackground();
+
+ functions->glEnable(GL_BLEND);
+ functions->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ Q_FOREACH (WindowCompositorView *view, m_compositor->views()) {
+ if (view->isCursor())
+ continue;
+ GLuint textureId = view->getTexture();
+ QWaylandSurface *surface = view->surface();
+ if (surface && surface->isMapped()) {
+ QSize s = surface->size();
+ if (!s.isEmpty()) {
+ QRectF surfaceGeometry(view->position(), 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);
+ }
+ }
+ }
+ functions->glDisable(GL_BLEND);
+
+ m_textureBlitter.release();
+ m_compositor->endRender();
+}
+
+WindowCompositorView *CompositorWindow::viewAt(const QPointF &point)
+{
+ WindowCompositorView *ret = 0;
+ Q_FOREACH (WindowCompositorView *view, m_compositor->views()) {
+ if (view == m_dragIconView)
+ continue;
+ QPointF topLeft = view->position();
+ QWaylandSurface *surface = view->surface();
+ QRectF geo(topLeft, surface->size());
+ if (geo.contains(point))
+ ret = view;
+ }
+ return ret;
+}
+
+void CompositorWindow::startMove()
+{
+ m_grabState = MoveGrab;
+}
+
+void CompositorWindow::startResize(int edge)
+{
+ m_initialSize = m_mouseView->surface()->size();
+ m_grabState = ResizeGrab;
+ m_resizeEdge = edge;
+}
+
+void CompositorWindow::startDrag(WindowCompositorView *dragIcon)
+{
+ m_grabState = DragGrab;
+ m_dragIconView = dragIcon;
+ m_compositor->raise(dragIcon);
+}
+
+void CompositorWindow::setFrameOffset(const QPoint &offset)
+{
+ if (m_mouseView)
+ m_mouseView->setPosition(m_mouseView->position() + offset);
+}
+
+void CompositorWindow::mousePressEvent(QMouseEvent *e)
+{
+ if (mouseGrab())
+ return;
+ if (m_mouseView.isNull()) {
+ m_mouseView = viewAt(e->localPos());
+ if (!m_mouseView) {
+ m_compositor->closePopups();
+ return;
+ }
+ if (e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::MetaModifier)
+ m_grabState = MoveGrab; //start move
+ else
+ m_compositor->raise(m_mouseView);
+ m_initialMousePos = e->localPos();
+ m_mouseOffset = e->localPos() - m_mouseView->position();
+
+ QMouseEvent moveEvent(QEvent::MouseMove, e->localPos(), e->globalPos(), Qt::NoButton, Qt::NoButton, e->modifiers());
+ sendMouseEvent(&moveEvent, m_mouseView);
+ }
+ sendMouseEvent(e, m_mouseView);
+}
+
+void CompositorWindow::mouseReleaseEvent(QMouseEvent *e)
+{
+ if (!mouseGrab())
+ sendMouseEvent(e, m_mouseView);
+ if (e->buttons() == Qt::NoButton) {
+ if (m_grabState == DragGrab) {
+ WindowCompositorView *view = viewAt(e->localPos());
+ m_compositor->handleDrag(view, e);
+ }
+ m_mouseView = 0;
+ m_grabState = NoGrab;
+ }
+}
+
+void CompositorWindow::mouseMoveEvent(QMouseEvent *e)
+{
+ switch (m_grabState) {
+ case NoGrab: {
+ WindowCompositorView *view = m_mouseView ? m_mouseView.data() : viewAt(e->localPos());
+ sendMouseEvent(e, view);
+ if (!view)
+ setCursor(Qt::ArrowCursor);
+ }
+ break;
+ case MoveGrab: {
+ m_mouseView->setPosition(e->localPos() - m_mouseOffset);
+ update();
+ }
+ break;
+ case ResizeGrab: {
+ QPoint delta = (e->localPos() - m_initialMousePos).toPoint();
+ m_compositor->handleResize(m_mouseView, m_initialSize, delta, m_resizeEdge);
+ }
+ break;
+ case DragGrab: {
+ WindowCompositorView *view = viewAt(e->localPos());
+ m_compositor->handleDrag(view, e);
+ if (m_dragIconView) {
+ m_dragIconView->setPosition(e->localPos());
+ update();
+ }
+ }
+ break;
+ }
+}
+
+void CompositorWindow::sendMouseEvent(QMouseEvent *e, WindowCompositorView *target)
+{
+ if (!target)
+ return;
+
+ QPointF mappedPos = e->localPos() - target->position();
+ QMouseEvent viewEvent(e->type(), mappedPos, e->localPos(), e->button(), e->buttons(), e->modifiers());
+ m_compositor->handleMouseEvent(target, &viewEvent);
+}
+
+void CompositorWindow::keyPressEvent(QKeyEvent *e)
{
- setSurfaceType(QWindow::OpenGLSurface);
- setGeometry(geometry);
- setFormat(format);
- create();
- m_context = new QOpenGLContext;
- m_context->setFormat(format);
- m_context->create();
+ m_compositor->defaultInputDevice()->sendKeyPressEvent(e->nativeScanCode());
}
-void CompositorWindow::touchEvent(QTouchEvent *event)
+void CompositorWindow::keyReleaseEvent(QKeyEvent *e)
{
- // Do not want any automatically synthesized mouse events
- // so make sure the touch is always accepted.
- event->accept();
+ m_compositor->defaultInputDevice()->sendKeyReleaseEvent(e->nativeScanCode());
}