summaryrefslogtreecommitdiffstats
path: root/tests/auto/client/client/tst_client.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/client/client/tst_client.cpp')
-rw-r--r--tests/auto/client/client/tst_client.cpp355
1 files changed, 355 insertions, 0 deletions
diff --git a/tests/auto/client/client/tst_client.cpp b/tests/auto/client/client/tst_client.cpp
new file mode 100644
index 000000000..74363ef5f
--- /dev/null
+++ b/tests/auto/client/client/tst_client.cpp
@@ -0,0 +1,355 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mockcompositor.h"
+
+#include <QBackingStore>
+#include <QPainter>
+#include <QScreen>
+#include <QWindow>
+#include <QMimeData>
+#include <QPixmap>
+#include <QDrag>
+
+#include <QtTest/QtTest>
+
+static const QSize screenSize(1600, 1200);
+
+class TestWindow : public QWindow
+{
+public:
+ TestWindow()
+ : focusInEventCount(0)
+ , focusOutEventCount(0)
+ , keyPressEventCount(0)
+ , keyReleaseEventCount(0)
+ , mousePressEventCount(0)
+ , mouseReleaseEventCount(0)
+ , touchEventCount(0)
+ , keyCode(0)
+ {
+ setSurfaceType(QSurface::RasterSurface);
+ setGeometry(0, 0, 32, 32);
+ create();
+ }
+
+ void focusInEvent(QFocusEvent *)
+ {
+ ++focusInEventCount;
+ }
+
+ void focusOutEvent(QFocusEvent *)
+ {
+ ++focusOutEventCount;
+ }
+
+ void keyPressEvent(QKeyEvent *event)
+ {
+ ++keyPressEventCount;
+ keyCode = event->nativeScanCode();
+ }
+
+ void keyReleaseEvent(QKeyEvent *event)
+ {
+ ++keyReleaseEventCount;
+ keyCode = event->nativeScanCode();
+ }
+
+ void mousePressEvent(QMouseEvent *event)
+ {
+ ++mousePressEventCount;
+ mousePressPos = event->pos();
+ }
+
+ void mouseReleaseEvent(QMouseEvent *)
+ {
+ ++mouseReleaseEventCount;
+ }
+
+ void touchEvent(QTouchEvent *event) Q_DECL_OVERRIDE
+ {
+ ++touchEventCount;
+ }
+
+ int focusInEventCount;
+ int focusOutEventCount;
+ int keyPressEventCount;
+ int keyReleaseEventCount;
+ int mousePressEventCount;
+ int mouseReleaseEventCount;
+ int touchEventCount;
+
+ uint keyCode;
+ QPoint mousePressPos;
+};
+
+class tst_WaylandClient : public QObject
+{
+ Q_OBJECT
+public:
+ tst_WaylandClient(MockCompositor *c)
+ : compositor(c)
+ {
+ QSocketNotifier *notifier = new QSocketNotifier(compositor->waylandFileDescriptor(), QSocketNotifier::Read, this);
+ connect(notifier, SIGNAL(activated(int)), this, SLOT(processWaylandEvents()));
+ // connect to the event dispatcher to make sure to flush out the outgoing message queue
+ connect(QCoreApplication::eventDispatcher(), &QAbstractEventDispatcher::awake, this, &tst_WaylandClient::processWaylandEvents);
+ connect(QCoreApplication::eventDispatcher(), &QAbstractEventDispatcher::aboutToBlock, this, &tst_WaylandClient::processWaylandEvents);
+ }
+
+public slots:
+ void processWaylandEvents()
+ {
+ compositor->processWaylandEvents();
+ }
+
+ void cleanup()
+ {
+ // make sure the surfaces from the last test are properly cleaned up
+ // and don't show up as false positives in the next test
+ QTRY_VERIFY(!compositor->surface());
+ }
+
+private slots:
+ void screen();
+ void createDestroyWindow();
+ void events();
+ void backingStore();
+ void touchDrag();
+ void mouseDrag();
+
+private:
+ MockCompositor *compositor;
+};
+
+void tst_WaylandClient::screen()
+{
+ QTRY_COMPARE(QGuiApplication::primaryScreen()->size(), screenSize);
+}
+
+void tst_WaylandClient::createDestroyWindow()
+{
+ TestWindow window;
+ window.show();
+
+ QTRY_VERIFY(compositor->surface());
+
+ window.destroy();
+ QTRY_VERIFY(!compositor->surface());
+}
+
+void tst_WaylandClient::events()
+{
+ TestWindow window;
+ window.show();
+
+ QSharedPointer<MockSurface> surface;
+ QTRY_VERIFY(surface = compositor->surface());
+
+ QCOMPARE(window.focusInEventCount, 0);
+ compositor->setKeyboardFocus(surface);
+ QTRY_COMPARE(window.focusInEventCount, 1);
+ QTRY_COMPARE(QGuiApplication::focusWindow(), &window);
+
+ QCOMPARE(window.focusOutEventCount, 0);
+ compositor->setKeyboardFocus(QSharedPointer<MockSurface>(0));
+ QTRY_COMPARE(window.focusOutEventCount, 1);
+ QTRY_COMPARE(QGuiApplication::focusWindow(), static_cast<QWindow *>(0));
+
+ compositor->setKeyboardFocus(surface);
+ QTRY_COMPARE(window.focusInEventCount, 2);
+ QTRY_COMPARE(QGuiApplication::focusWindow(), &window);
+
+ uint keyCode = 80; // arbitrarily chosen
+ QCOMPARE(window.keyPressEventCount, 0);
+ compositor->sendKeyPress(surface, keyCode);
+ QTRY_COMPARE(window.keyPressEventCount, 1);
+ QTRY_COMPARE(window.keyCode, keyCode);
+
+ QCOMPARE(window.keyReleaseEventCount, 0);
+ compositor->sendKeyRelease(surface, keyCode);
+ QTRY_COMPARE(window.keyReleaseEventCount, 1);
+ QCOMPARE(window.keyCode, keyCode);
+
+ QPoint mousePressPos(16, 16);
+ QCOMPARE(window.mousePressEventCount, 0);
+ compositor->sendMousePress(surface, mousePressPos);
+ QTRY_COMPARE(window.mousePressEventCount, 1);
+ QTRY_COMPARE(window.mousePressPos, mousePressPos);
+
+ QCOMPARE(window.mouseReleaseEventCount, 0);
+ compositor->sendMouseRelease(surface);
+ QTRY_COMPARE(window.mouseReleaseEventCount, 1);
+
+ const int touchId = 0;
+ compositor->sendTouchDown(surface, QPoint(10, 10), touchId);
+ compositor->sendTouchFrame(surface);
+ QTRY_COMPARE(window.touchEventCount, 1);
+
+ compositor->sendTouchUp(surface, touchId);
+ compositor->sendTouchFrame(surface);
+ QTRY_COMPARE(window.touchEventCount, 2);
+}
+
+void tst_WaylandClient::backingStore()
+{
+ TestWindow window;
+ window.show();
+
+ QSharedPointer<MockSurface> surface;
+ QTRY_VERIFY(surface = compositor->surface());
+
+ QRect rect(QPoint(), window.size());
+
+ QBackingStore backingStore(&window);
+ backingStore.resize(rect.size());
+
+ backingStore.beginPaint(rect);
+
+ QColor color = Qt::magenta;
+
+ QPainter p(backingStore.paintDevice());
+ p.fillRect(rect, color);
+ p.end();
+
+ backingStore.endPaint();
+
+ QVERIFY(surface->image.isNull());
+
+ backingStore.flush(rect);
+
+ QTRY_COMPARE(surface->image.size(), window.frameGeometry().size());
+ QTRY_COMPARE(surface->image.pixel(window.frameMargins().left(), window.frameMargins().top()), color.rgba());
+
+ window.hide();
+
+ // hiding the window should detach the buffer
+ QTRY_VERIFY(surface->image.isNull());
+}
+
+class DndWindow : public QWindow
+{
+ Q_OBJECT
+
+public:
+ DndWindow(QWindow *parent = 0)
+ : QWindow(parent)
+ , dragStarted(false)
+ {
+ QImage cursorImage(64,64,QImage::Format_ARGB32);
+ cursorImage.fill(Qt::blue);
+ m_dragIcon = QPixmap::fromImage(cursorImage);
+ }
+ ~DndWindow(){}
+ bool dragStarted;
+
+protected:
+ void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE
+ {
+ if (dragStarted)
+ return;
+ dragStarted = true;
+
+ QByteArray dataBytes;
+ QMimeData *mimeData = new QMimeData;
+ mimeData->setData("application/x-dnditemdata", dataBytes);
+ QDrag *drag = new QDrag(this);
+ drag->setMimeData(mimeData);
+ drag->setPixmap(m_dragIcon);
+ drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction);
+ }
+private:
+ QPixmap m_dragIcon;
+};
+
+void tst_WaylandClient::touchDrag()
+{
+ DndWindow window;
+ window.show();
+
+ QSharedPointer<MockSurface> surface;
+ QTRY_VERIFY(surface = compositor->surface());
+
+ compositor->setKeyboardFocus(surface);
+ QTRY_COMPARE(QGuiApplication::focusWindow(), &window);
+
+ const int id = 0;
+ compositor->sendTouchDown(surface, QPoint(10, 10), id);
+ compositor->sendTouchMotion(surface, QPoint(20, 20), id);
+ compositor->sendTouchFrame(surface);
+ compositor->waitForStartDrag();
+ compositor->sendDataDeviceDataOffer(surface);
+ compositor->sendDataDeviceEnter(surface, QPoint(20, 20));
+ compositor->sendDataDeviceMotion( QPoint(21, 21));
+ compositor->sendDataDeviceDrop(surface);
+ compositor->sendDataDeviceLeave(surface);
+ QTRY_VERIFY(window.dragStarted);
+}
+
+void tst_WaylandClient::mouseDrag()
+{
+ DndWindow window;
+ window.show();
+
+ QSharedPointer<MockSurface> surface;
+ QTRY_VERIFY(surface = compositor->surface());
+
+ compositor->setKeyboardFocus(surface);
+ QTRY_COMPARE(QGuiApplication::focusWindow(), &window);
+
+ compositor->sendMousePress(surface, QPoint(10, 10));
+ compositor->sendDataDeviceDataOffer(surface);
+ compositor->sendDataDeviceEnter(surface, QPoint(20, 20));
+ compositor->sendDataDeviceMotion( QPoint(21, 21));
+ compositor->waitForStartDrag();
+ compositor->sendDataDeviceDrop(surface);
+ compositor->sendDataDeviceLeave(surface);
+ QTRY_VERIFY(window.dragStarted);
+}
+
+int main(int argc, char **argv)
+{
+ setenv("XDG_RUNTIME_DIR", ".", 1);
+ setenv("QT_QPA_PLATFORM", "wayland", 1); // force QGuiApplication to use wayland plugin
+
+ // wayland-egl hangs in the test setup when we try to initialize. Until it gets
+ // figured out, avoid clientBufferIntegration() from being called in
+ // QWaylandWindow::createDecorations().
+ setenv("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1", 1);
+
+ MockCompositor compositor;
+ compositor.setOutputGeometry(QRect(QPoint(), screenSize));
+
+ QGuiApplication app(argc, argv);
+ compositor.applicationInitialized();
+
+ tst_WaylandClient tc(&compositor);
+ return QTest::qExec(&tc, argc, argv);
+}
+
+#include <tst_client.moc>