diff options
author | Paul Olav Tvete <paul.tvete@theqtcompany.com> | 2015-09-11 12:38:31 +0200 |
---|---|---|
committer | Jørgen Lind <jorgen.lind@theqtcompany.com> | 2015-09-15 13:39:03 +0000 |
commit | 96275f64afd66161f8bb8b4b86ed3cd252826323 (patch) | |
tree | f2f82d63df56d15500828c05cbf4806b69c7b6d6 /examples | |
parent | 29fdcebc636b038553e1bf60a6df83577486b910 (diff) | |
download | qtwayland-96275f64afd66161f8bb8b4b86ed3cd252826323.tar.gz |
Adapt example to new API without global coordinates
Also including:
Move windows on alt/meta + mousepress
Send mouse events also when no buttons are pressed
Add cursor support to the QWindow compositor
Implement resize
Change-Id: Ib4b64b2e474e519d2061e65954e53fa9d52fd85c
Reviewed-by: Jørgen Lind <jorgen.lind@theqtcompany.com>
Diffstat (limited to 'examples')
5 files changed, 160 insertions, 51 deletions
diff --git a/examples/wayland/qwindow-compositor/compositorwindow.cpp b/examples/wayland/qwindow-compositor/compositorwindow.cpp index 95ab1c63..94bb10e2 100644 --- a/examples/wayland/qwindow-compositor/compositorwindow.cpp +++ b/examples/wayland/qwindow-compositor/compositorwindow.cpp @@ -49,6 +49,21 @@ #include "windowcompositor.h" #include <QtWaylandCompositor/qwaylandinput.h> +CompositorWindow::CompositorWindow() + : m_backgroundTexture(0) + , m_compositor(0) + , m_moveState(false) + , m_resizeState(false) +{ +} + +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::frameOffset, this, &CompositorWindow::setFrameOffset); +} + void CompositorWindow::initializeGL() { QImage backgroundImage = QImage(QLatin1String(":/background.jpg")); @@ -88,8 +103,7 @@ void CompositorWindow::paintGL() if (surface && surface->isMapped()) { QSize s = surface->size(); if (!s.isEmpty()) { - QRectF surfaceGeometry(view->requestedPosition(), s); - //qDebug() << surface << surface->views().first() << view << s; + QRectF surfaceGeometry(view->position(), s); QOpenGLTextureBlitter::Origin surfaceOrigin = view->currentBuffer().origin() == QWaylandSurface::OriginTopLeft ? QOpenGLTextureBlitter::OriginTopLeft @@ -105,15 +119,11 @@ void CompositorWindow::paintGL() m_compositor->endRender(); } -void resizeGL(int w, int h) -{ -} - WindowCompositorView *CompositorWindow::viewAt(const QPointF &point) { WindowCompositorView *ret = 0; Q_FOREACH (WindowCompositorView *view, m_compositor->views()) { - QPointF topLeft = view->requestedPosition(); + QPointF topLeft = view->position(); QWaylandSurface *surface = view->surface(); QRectF geo(topLeft, surface->size()); if (geo.contains(point)) @@ -122,10 +132,41 @@ WindowCompositorView *CompositorWindow::viewAt(const QPointF &point) return ret; } +void CompositorWindow::startMove() +{ + m_moveState = true; +} + +void CompositorWindow::startResize(int edge) +{ + m_initialSize = m_mouseView->surface()->size(); + m_resizeState = true; + m_resizeEdge = edge; +} + +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) + return; + + if (m_mouseView && (e->modifiers() == Qt::AltModifier || + e->modifiers() == Qt::MetaModifier)) { + //start move + m_moveState = true; + } + 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); } @@ -134,22 +175,39 @@ void CompositorWindow::mousePressEvent(QMouseEvent *e) void CompositorWindow::mouseReleaseEvent(QMouseEvent *e) { - sendMouseEvent(e, m_mouseView); - if (e->buttons() == Qt::NoButton) + if (!mouseGrab()) + sendMouseEvent(e, m_mouseView); + if (e->buttons() == Qt::NoButton) { m_mouseView = 0; + m_moveState = false; + m_resizeState = false; + } } void CompositorWindow::mouseMoveEvent(QMouseEvent *e) { - sendMouseEvent(e, m_mouseView); + if (mouseGrab()) { + if (m_moveState) { + m_mouseView->setPosition(e->localPos() - m_mouseOffset); + update(); + } else if (m_resizeState) { + QPoint delta = (e->localPos() - m_initialMousePos).toPoint(); + m_compositor->handleResize(m_mouseView, m_initialSize, delta, m_resizeEdge); + } + } else { + WindowCompositorView *view = m_mouseView ? m_mouseView.data() : viewAt(e->localPos()); + sendMouseEvent(e, view); + if (!view) + setCursor(Qt::ArrowCursor); + } } -void CompositorWindow::sendMouseEvent(QMouseEvent *e, QWaylandView *target) +void CompositorWindow::sendMouseEvent(QMouseEvent *e, WindowCompositorView *target) { if (!target) return; - QPointF mappedPos = e->localPos() - target->requestedPosition(); + QPointF mappedPos = e->localPos() - target->position(); QMouseEvent viewEvent(e->type(), mappedPos, e->localPos(), e->button(), e->buttons(), e->modifiers()); m_compositor->handleMouseEvent(target, &viewEvent); } diff --git a/examples/wayland/qwindow-compositor/compositorwindow.h b/examples/wayland/qwindow-compositor/compositorwindow.h index 57395d8a..8ca9eccc 100644 --- a/examples/wayland/qwindow-compositor/compositorwindow.h +++ b/examples/wayland/qwindow-compositor/compositorwindow.h @@ -44,7 +44,6 @@ #include <QOpenGLWindow> #include <QPointer> #include <QtGui/private/qopengltextureblitter_p.h> -#include <QtWaylandCompositor/QWaylandView> QT_BEGIN_NAMESPACE @@ -55,31 +54,45 @@ class QOpenGLTexture; class CompositorWindow : public QOpenGLWindow { public: - CompositorWindow() : m_backgroundTexture(0), m_compositor(0) {} - void setCompositor(WindowCompositor *comp) { - m_compositor = comp; - } + CompositorWindow(); + + void setCompositor(WindowCompositor *comp); + protected: void initializeGL() Q_DECL_OVERRIDE; void paintGL() Q_DECL_OVERRIDE; -// void resizeGL(int w, int h) Q_DECL_OVERRIDE; - void mousePressEvent(QMouseEvent *e); - void mouseReleaseEvent(QMouseEvent *e); - void mouseMoveEvent(QMouseEvent *e); + void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE; + void mouseReleaseEvent(QMouseEvent *e) Q_DECL_OVERRIDE; + void mouseMoveEvent(QMouseEvent *e) Q_DECL_OVERRIDE; + + void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE; + void keyReleaseEvent(QKeyEvent *e) Q_DECL_OVERRIDE; + + QSize sizeHint() const Q_DECL_OVERRIDE; + +private slots: + void startMove(); + void startResize(int edge); + void setFrameOffset(const QPoint &offset); - void keyPressEvent(QKeyEvent *e); - void keyReleaseEvent(QKeyEvent *e); private: WindowCompositorView *viewAt(const QPointF &point); + bool mouseGrab() const { return m_moveState || m_resizeState; } void drawBackground(); - void sendMouseEvent(QMouseEvent *e, QWaylandView *target); + void sendMouseEvent(QMouseEvent *e, WindowCompositorView *target); QOpenGLTextureBlitter m_textureBlitter; QSize m_backgroundImageSize; QOpenGLTexture *m_backgroundTexture; WindowCompositor *m_compositor; - QPointer<QWaylandView> m_mouseView; + QPointer<WindowCompositorView> m_mouseView; + bool m_moveState; + bool m_resizeState; + QSize m_initialSize; + int m_resizeEdge; + QPointF m_mouseOffset; + QPointF m_initialMousePos; }; QT_END_NAMESPACE diff --git a/examples/wayland/qwindow-compositor/main.cpp b/examples/wayland/qwindow-compositor/main.cpp index 7f939a03..101367cf 100644 --- a/examples/wayland/qwindow-compositor/main.cpp +++ b/examples/wayland/qwindow-compositor/main.cpp @@ -47,11 +47,9 @@ int main(int argc, char *argv[]) QGuiApplication app(argc, argv); CompositorWindow window; - window.resize(1500,800); - - WindowCompositor comp(&window); - window.setCompositor(&comp); - comp.create(); + WindowCompositor compositor(&window); + window.setCompositor(&compositor); + compositor.create(); window.show(); return app.exec(); diff --git a/examples/wayland/qwindow-compositor/windowcompositor.cpp b/examples/wayland/qwindow-compositor/windowcompositor.cpp index ac637e62..b9e675f3 100644 --- a/examples/wayland/qwindow-compositor/windowcompositor.cpp +++ b/examples/wayland/qwindow-compositor/windowcompositor.cpp @@ -86,18 +86,16 @@ void WindowCompositor::create() void WindowCompositor::onSurfaceCreated(QWaylandSurface *surface) { - qDebug() << "onSurfaceCreated" << surface; - connect(surface, &QWaylandSurface::surfaceDestroyed, this, &WindowCompositor::surfaceDestroyed); connect(surface, &QWaylandSurface::mappedChanged, this, &WindowCompositor::surfaceMappedChanged); connect(surface, &QWaylandSurface::redraw, this, &WindowCompositor::triggerRender); + connect(surface, &QWaylandSurface::offsetForNextFrame, this, &WindowCompositor::frameOffset); } void WindowCompositor::surfaceMappedChanged() { QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender()); - qDebug() << "surfaceMappedChanged()" << surface << surface->isMapped(); - if (surface->isMapped()) {\ + if (surface->isMapped()) { if (!surface->isCursorSurface()) defaultInputDevice()->setKeyboardFocus(surface); } @@ -106,34 +104,23 @@ void WindowCompositor::surfaceMappedChanged() void WindowCompositor::surfaceDestroyed() { - // QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender()); - qDebug() << "surfaceDestroyed()"; - // Q_FOREACH (QWaylandView *view, surface->views()) { - // int n = m_views.removeAll(static_cast<WindowCompositorView*>(view)); - // qDebug() << n << view; - // } triggerRender(); } void WindowCompositor::viewSurfaceDestroyed() { WindowCompositorView *view = qobject_cast<WindowCompositorView*>(sender()); - int n = m_views.removeAll(view); - qDebug() << n << view; + m_views.removeAll(view); delete view; } void WindowCompositor::surfaceCommittedSlot() { - QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender()); - -// qDebug() << "surfaceCommittedSlot()" << surface; triggerRender(); } void WindowCompositor::onCreateShellSurface(QWaylandSurface *s, QWaylandClient *client, uint id) { - qDebug() << "onCreateShellSurface" << s << client << id; QWaylandSurface *surface = s; WindowCompositorView *view = new WindowCompositorView; @@ -141,9 +128,16 @@ void WindowCompositor::onCreateShellSurface(QWaylandSurface *s, QWaylandClient * view->setOutput(output(m_window)); m_views << view; connect(view, &QWaylandView::surfaceDestroyed, this, &WindowCompositor::viewSurfaceDestroyed); - connect(view, &QWaylandView::requestedPositionChanged, this, &WindowCompositor::triggerRender); - QWaylandShellSurface *shellSurface = new QWaylandShellSurface(m_shell, surface, view, client, id); + QWaylandShellSurface *shellSurface = new QWaylandShellSurface(m_shell, surface, client, id); + connect(shellSurface, &QWaylandShellSurface::startMove, this, &WindowCompositor::startMove); + connect(shellSurface, &QWaylandShellSurface::startResize, this, &WindowCompositor::onStartResize); + view->m_shellSurface = shellSurface; +} + +void WindowCompositor::onStartResize(QWaylandInputDevice *, QWaylandShellSurface::ResizeEdge edges) +{ + emit startResize(int(edges)); } void WindowCompositor::triggerRender() @@ -154,7 +148,6 @@ void WindowCompositor::triggerRender() void WindowCompositor::startRender() { defaultOutput()->frameStarted(); - cleanupGraphicsResources(); } void WindowCompositor::endRender() @@ -162,9 +155,26 @@ void WindowCompositor::endRender() defaultOutput()->sendFrameCallbacks(); } +void WindowCompositor::updateCursor() +{ + m_cursorView.advance(); + QImage image = m_cursorView.currentBuffer().image(); + if (!image.isNull()) + m_window->setCursor(QCursor(QPixmap::fromImage(image), m_cursorHotspotX, m_cursorHotspotY)); +} + void WindowCompositor::adjustCursorSurface(QWaylandSurface *surface, int hotspotX, int hotspotY) { - //qDebug() << "adjustCursorSurface" << surface << hotspotY << hotspotY; + if ((m_cursorView.surface() != surface)) { + if (m_cursorView.surface()) + disconnect(m_cursorView.surface(), &QWaylandSurface::redraw, this, &WindowCompositor::updateCursor); + if (surface) + connect(surface, &QWaylandSurface::redraw, this, &WindowCompositor::updateCursor); + } + + m_cursorView.setSurface(surface); + m_cursorHotspotX = hotspotX; + m_cursorHotspotY = hotspotY; } void WindowCompositor::handleMouseEvent(QWaylandView *target, QMouseEvent *me) @@ -183,3 +193,13 @@ void WindowCompositor::handleMouseEvent(QWaylandView *target, QMouseEvent *me) break; } } + +void WindowCompositor::handleResize(WindowCompositorView *target, const QSize &initialSize, const QPoint &delta, int edge) +{ + QWaylandShellSurface *shellSurface = target->m_shellSurface; + if (!shellSurface) + return; + QWaylandShellSurface::ResizeEdge edges = QWaylandShellSurface::ResizeEdge(edge); + QSize newSize = shellSurface->sizeForResize(initialSize, delta, edges); + shellSurface->sendConfigure(newSize, edges); +} diff --git a/examples/wayland/qwindow-compositor/windowcompositor.h b/examples/wayland/qwindow-compositor/windowcompositor.h index 31ddf737..18db41c2 100644 --- a/examples/wayland/qwindow-compositor/windowcompositor.h +++ b/examples/wayland/qwindow-compositor/windowcompositor.h @@ -44,20 +44,27 @@ #include <QtWaylandCompositor/QWaylandCompositor> #include <QtWaylandCompositor/QWaylandSurface> #include <QtWaylandCompositor/QWaylandView> +#include <QtWaylandCompositor/QWaylandShellSurface> #include <QTimer> QT_BEGIN_NAMESPACE class QWaylandShell; +class QWaylandShellSurface; class WindowCompositorView : public QWaylandView { Q_OBJECT public: - WindowCompositorView() : m_texture(0) {} + WindowCompositorView() : m_texture(0), m_shellSurface(0) {} GLuint getTexture(); + QPointF position() const { return m_position; } + void setPosition(const QPointF &pos) { m_position = pos; } private: + friend class WindowCompositor; GLuint m_texture; + QPointF m_position; + QWaylandShellSurface *m_shellSurface; }; class WindowCompositor : public QWaylandCompositor @@ -74,23 +81,36 @@ public: QList<WindowCompositorView*> views() const { return m_views; } void handleMouseEvent(QWaylandView *target, QMouseEvent *me); + void handleResize(WindowCompositorView *target, const QSize &initialSize, const QPoint &delta, int edge); + protected: void adjustCursorSurface(QWaylandSurface *surface, int hotspotX, int hotspotY); +signals: + void startMove(); + void startResize(int edge); + void frameOffset(const QPoint &offset); + private slots: void surfaceMappedChanged(); void surfaceDestroyed(); void surfaceCommittedSlot(); void viewSurfaceDestroyed(); + void onStartResize(QWaylandInputDevice *inputDevice, QWaylandShellSurface::ResizeEdge edges); void triggerRender(); void onSurfaceCreated(QWaylandSurface *surface); void onCreateShellSurface(QWaylandSurface *s, QWaylandClient *client, uint id); + void updateCursor(); private: QWindow *m_window; QList<WindowCompositorView*> m_views; QWaylandShell *m_shell; + + QWaylandView m_cursorView; + int m_cursorHotspotX; + int m_cursorHotspotY; }; |