summaryrefslogtreecommitdiffstats
path: root/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/gui/kernel/qwindow/tst_qwindow.cpp')
-rw-r--r--tests/auto/gui/kernel/qwindow/tst_qwindow.cpp194
1 files changed, 143 insertions, 51 deletions
diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
index d361aa12a6..a89f0da4d2 100644
--- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
+++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
@@ -35,6 +35,7 @@
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformintegration.h>
#include <private/qguiapplication_p.h>
+#include <private/qhighdpiscaling_p.h>
#include <QtGui/QPainter>
#include <QtTest/QtTest>
@@ -94,6 +95,8 @@ private slots:
void windowsTransientChildren();
void requestUpdate();
void initTestCase();
+ void stateChange_data();
+ void stateChange();
void cleanup();
private:
@@ -265,6 +268,38 @@ void tst_QWindow::positioning_data()
#endif
}
+// Compare a window position that may go through scaling in the platform plugin with fuzz.
+static inline bool qFuzzyCompareWindowPosition(const QPoint &p1, const QPoint p2, int fuzz)
+{
+ return (p1 - p2).manhattanLength() <= fuzz;
+}
+
+static inline bool qFuzzyCompareWindowSize(const QSize &s1, const QSize &s2, int fuzz)
+{
+ const int manhattanLength = qAbs(s1.width() - s2.width()) + qAbs(s1.height() - s2.height());
+ return manhattanLength <= fuzz;
+}
+
+static inline bool qFuzzyCompareWindowGeometry(const QRect &r1, const QRect &r2, int fuzz)
+{
+ return qFuzzyCompareWindowPosition(r1.topLeft(), r2.topLeft(), fuzz)
+ && qFuzzyCompareWindowSize(r1.size(), r2.size(), fuzz);
+}
+
+static QString msgPointMismatch(const QPoint &p1, const QPoint p2)
+{
+ QString result;
+ QDebug(&result) << p1 << "!=" << p2 << ", manhattanLength=" << (p1 - p2).manhattanLength();
+ return result;
+}
+
+static QString msgRectMismatch(const QRect &r1, const QRect &r2)
+{
+ QString result;
+ QDebug(&result) << r1 << "!=" << r2;
+ return result;
+}
+
void tst_QWindow::positioning()
{
if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(
@@ -272,7 +307,7 @@ void tst_QWindow::positioning()
QSKIP("This platform does not support non-fullscreen windows");
}
- if (qApp->platformName().toLower() == QLatin1String("wayland"))
+ if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
QSKIP("Wayland: This fails. Figure out why.");
// Some platforms enforce minimum widths for windows, which can cause extra resize
@@ -327,21 +362,25 @@ void tst_QWindow::positioning()
// if our positioning is actually fully respected by the window manager
// test whether it correctly handles frame positioning as well
if (originalPos == geometry.topLeft() && (originalMargins.top() != 0 || originalMargins.left() != 0)) {
- QPoint framePos = QPlatformScreen::platformScreenForWindow(&window)->availableGeometry().center();
+ const QScreen *screen = window.screen();
+ const QRect availableGeometry = screen->availableGeometry();
+ const QPoint framePos = availableGeometry.center();
window.reset();
const QPoint oldFramePos = window.framePosition();
window.setFramePosition(framePos);
QTRY_VERIFY(window.received(QEvent::Move));
- if (window.framePosition() != framePos) {
+ const int fuzz = int(QHighDpiScaling::factor(&window));
+ if (!qFuzzyCompareWindowPosition(window.framePosition(), framePos, fuzz)) {
qDebug() << "About to fail auto-test. Here is some additional information:";
qDebug() << "window.framePosition() == " << window.framePosition();
qDebug() << "old frame position == " << oldFramePos;
qDebug() << "We received " << window.received(QEvent::Move) << " move events";
qDebug() << "frame positions after each move event:" << window.m_framePositionsOnMove;
}
- QTRY_COMPARE(framePos, window.framePosition());
+ QTRY_VERIFY2(qFuzzyCompareWindowPosition(window.framePosition(), framePos, fuzz),
+ qPrintable(msgPointMismatch(window.framePosition(), framePos)));
QTRY_COMPARE(originalMargins, window.frameMargins());
QCOMPARE(window.position(), window.framePosition() + QPoint(originalMargins.left(), originalMargins.top()));
@@ -357,7 +396,8 @@ void tst_QWindow::positioning()
void tst_QWindow::positioningDuringMinimized()
{
// QTBUG-39544, setting a geometry in minimized state should work as well.
- if (QGuiApplication::platformName().compare("windows", Qt::CaseInsensitive))
+ if (QGuiApplication::platformName().compare("windows", Qt::CaseInsensitive) != 0
+ && QGuiApplication::platformName().compare("cocoa", Qt::CaseInsensitive) != 0)
QSKIP("Not supported on this platform");
Window window;
window.setTitle(QStringLiteral("positioningDuringMinimized"));
@@ -375,6 +415,52 @@ void tst_QWindow::positioningDuringMinimized()
QTRY_COMPARE(window.geometry(), newGeometry);
}
+// QTBUG-49709: Verify that the normal geometry is correctly restored
+// when executing a sequence of window state changes. So far, Windows
+// only where state changes have immediate effect.
+
+typedef QList<Qt::WindowState> WindowStateList;
+
+Q_DECLARE_METATYPE(WindowStateList)
+
+void tst_QWindow::stateChange_data()
+{
+ QTest::addColumn<WindowStateList>("stateSequence");
+
+ QTest::newRow("normal->min->normal") <<
+ (WindowStateList() << Qt::WindowMinimized << Qt::WindowNoState);
+ QTest::newRow("normal->maximized->normal") <<
+ (WindowStateList() << Qt::WindowMaximized << Qt::WindowNoState);
+ QTest::newRow("normal->fullscreen->normal") <<
+ (WindowStateList() << Qt::WindowFullScreen << Qt::WindowNoState);
+ QTest::newRow("normal->maximized->fullscreen->normal") <<
+ (WindowStateList() << Qt::WindowMaximized << Qt::WindowFullScreen << Qt::WindowNoState);
+}
+
+void tst_QWindow::stateChange()
+{
+ QFETCH(WindowStateList, stateSequence);
+
+ if (QGuiApplication::platformName().compare(QLatin1String("windows"), Qt::CaseInsensitive))
+ QSKIP("Windows-only test");
+
+ Window window;
+ window.setTitle(QLatin1String(QTest::currentTestFunction()) + QLatin1Char(' ') + QLatin1String(QTest::currentDataTag()));
+ const QRect normalGeometry(m_availableTopLeft + QPoint(40, 40), m_testWindowSize);
+ window.setGeometry(normalGeometry);
+ // explicitly use non-fullscreen show. show() can be fullscreen on some platforms
+ window.showNormal();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+ foreach (Qt::WindowState state, stateSequence) {
+ window.setWindowState(state);
+ QCoreApplication::processEvents();
+ }
+ const QRect geometry = window.geometry();
+ const int fuzz = int(QHighDpiScaling::factor(&window));
+ QVERIFY2(qFuzzyCompareWindowGeometry(geometry, normalGeometry, fuzz),
+ qPrintable(msgRectMismatch(geometry, normalGeometry)));
+}
+
class PlatformWindowFilter : public QObject
{
Q_OBJECT
@@ -418,14 +504,14 @@ void tst_QWindow::platformSurface()
QCOMPARE(window.geometry(), geometry);
window.create();
- QTRY_VERIFY(window.received(QEvent::PlatformSurface) == 1);
- QTRY_VERIFY(window.surfaceEventType() == QPlatformSurfaceEvent::SurfaceCreated);
+ QTRY_COMPARE(window.received(QEvent::PlatformSurface), 1);
+ QTRY_COMPARE(window.surfaceEventType(), QPlatformSurfaceEvent::SurfaceCreated);
QTRY_VERIFY(window.handle() != Q_NULLPTR);
window.destroy();
- QTRY_VERIFY(window.received(QEvent::PlatformSurface) == 2);
- QTRY_VERIFY(window.surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed);
- QTRY_VERIFY(window.handle() == Q_NULLPTR);
+ QTRY_COMPARE(window.received(QEvent::PlatformSurface), 2);
+ QTRY_COMPARE(window.surfaceEventType(), QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed);
+ QTRY_VERIFY(!window.handle());
// Check for synchronous delivery of platform surface events and that the platform
// surface always existed upon event delivery
@@ -457,7 +543,7 @@ void tst_QWindow::isExposed()
window.hide();
- if (qApp->platformName().toLower() == QLatin1String("wayland"))
+ if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
QSKIP("Wayland: This is flaky. Figure out why.");
QCoreApplication::processEvents();
@@ -468,7 +554,7 @@ void tst_QWindow::isExposed()
void tst_QWindow::isActive()
{
- if (qApp->platformName().toLower() == QLatin1String("wayland"))
+ if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
QSKIP("Wayland: This fails. Figure out why.");
Window window;
@@ -487,7 +573,7 @@ void tst_QWindow::isActive()
context.swapBuffers(&window);
#endif
QTRY_COMPARE(window.received(QEvent::Resize), 1);
- QTRY_VERIFY(QGuiApplication::focusWindow() == &window);
+ QTRY_COMPARE(QGuiApplication::focusWindow(), &window);
QVERIFY(window.isActive());
Window child;
@@ -499,7 +585,7 @@ void tst_QWindow::isActive()
child.requestActivate();
- QTRY_VERIFY(QGuiApplication::focusWindow() == &child);
+ QTRY_COMPARE(QGuiApplication::focusWindow(), &child);
QVERIFY(child.isActive());
// parent shouldn't receive new resize events from child being shown
@@ -522,7 +608,7 @@ void tst_QWindow::isActive()
QTRY_VERIFY(dialog.isExposed());
QCoreApplication::processEvents();
QTRY_COMPARE(dialog.received(QEvent::Resize), 1);
- QTRY_VERIFY(QGuiApplication::focusWindow() == &dialog);
+ QTRY_COMPARE(QGuiApplication::focusWindow(), &dialog);
QVERIFY(dialog.isActive());
// transient child has focus
@@ -533,7 +619,7 @@ void tst_QWindow::isActive()
window.requestActivate();
- QTRY_VERIFY(QGuiApplication::focusWindow() == &window);
+ QTRY_COMPARE(QGuiApplication::focusWindow(), &window);
QCoreApplication::processEvents();
QTRY_COMPARE(dialog.received(QEvent::FocusOut), 1);
QTRY_COMPARE(window.received(QEvent::FocusIn), 2);
@@ -654,15 +740,13 @@ void tst_QWindow::testInputEvents()
window.showNormal();
QVERIFY(QTest::qWaitForWindowExposed(&window));
- QWindowSystemInterface::handleKeyEvent(&window, QEvent::KeyPress, Qt::Key_A, Qt::NoModifier);
- QWindowSystemInterface::handleKeyEvent(&window, QEvent::KeyRelease, Qt::Key_A, Qt::NoModifier);
+ QTest::keyClick(&window, Qt::Key_A, Qt::NoModifier);
QCoreApplication::processEvents();
QCOMPARE(window.keyPressCode, int(Qt::Key_A));
QCOMPARE(window.keyReleaseCode, int(Qt::Key_A));
QPointF local(12, 34);
- QWindowSystemInterface::handleMouseEvent(&window, local, local, Qt::LeftButton);
- QWindowSystemInterface::handleMouseEvent(&window, local, local, Qt::NoButton);
+ QTest::mouseClick(&window, Qt::LeftButton, Qt::NoModifier, local.toPoint());
QCoreApplication::processEvents();
QCOMPARE(window.mousePressButton, int(Qt::LeftButton));
QCOMPARE(window.mouseReleaseButton, int(Qt::LeftButton));
@@ -688,15 +772,17 @@ void tst_QWindow::testInputEvents()
// Now with null pointer as window. local param should not be utilized:
// handleMouseEvent() with tlw == 0 means the event is in global coords only.
window.mousePressButton = window.mouseReleaseButton = 0;
- QPointF nonWindowGlobal(window.geometry().topRight() + QPoint(200, 50)); // not inside the window
- QWindowSystemInterface::handleMouseEvent(0, nonWindowGlobal, nonWindowGlobal, Qt::LeftButton);
- QWindowSystemInterface::handleMouseEvent(0, nonWindowGlobal, nonWindowGlobal, Qt::NoButton);
+ const QPointF nonWindowGlobal(window.geometry().topRight() + QPoint(200, 50)); // not inside the window
+ const QPointF deviceNonWindowGlobal = QHighDpi::toNativePixels(nonWindowGlobal, window.screen());
+ QWindowSystemInterface::handleMouseEvent(0, deviceNonWindowGlobal, deviceNonWindowGlobal, Qt::LeftButton);
+ QWindowSystemInterface::handleMouseEvent(0, deviceNonWindowGlobal, deviceNonWindowGlobal, Qt::NoButton);
QCoreApplication::processEvents();
QCOMPARE(window.mousePressButton, 0);
QCOMPARE(window.mouseReleaseButton, 0);
- QPointF windowGlobal = window.mapToGlobal(local.toPoint());
- QWindowSystemInterface::handleMouseEvent(0, windowGlobal, windowGlobal, Qt::LeftButton);
- QWindowSystemInterface::handleMouseEvent(0, windowGlobal, windowGlobal, Qt::NoButton);
+ const QPointF windowGlobal = window.mapToGlobal(local.toPoint());
+ const QPointF deviceWindowGlobal = QHighDpi::toNativePixels(windowGlobal, window.screen());
+ QWindowSystemInterface::handleMouseEvent(0, deviceWindowGlobal, deviceWindowGlobal, Qt::LeftButton);
+ QWindowSystemInterface::handleMouseEvent(0, deviceWindowGlobal, deviceWindowGlobal, Qt::NoButton);
QCoreApplication::processEvents();
QCOMPARE(window.mousePressButton, int(Qt::LeftButton));
QCOMPARE(window.mouseReleaseButton, int(Qt::LeftButton));
@@ -718,7 +804,7 @@ void tst_QWindow::touchToMouseTranslation()
const QRectF moveArea(105, 108, 4, 4);
tp1.id = 1;
tp1.state = Qt::TouchPointPressed;
- tp1.area = pressArea;
+ tp1.area = QHighDpi::toNativePixels(pressArea, &window);
tp2.id = 2;
tp2.state = Qt::TouchPointPressed;
points << tp1 << tp2;
@@ -729,7 +815,7 @@ void tst_QWindow::touchToMouseTranslation()
tp1.state = Qt::TouchPointStationary;
tp2.id = 1;
tp2.state = Qt::TouchPointMoved;
- tp2.area = moveArea;
+ tp2.area = QHighDpi::toNativePixels(moveArea, &window);
points.clear();
points << tp1 << tp2;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
@@ -946,12 +1032,15 @@ void tst_QWindow::touchCancelWithTouchToMouse()
tp1.id = 1;
tp1.state = Qt::TouchPointPressed;
- tp1.area = QRect(100, 100, 4, 4);
+ const QRect area(100, 100, 4, 4);
+ tp1.area = QHighDpi::toNativePixels(area, &window);
points << tp1;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
QCoreApplication::processEvents();
QTRY_COMPARE(window.mousePressButton, int(Qt::LeftButton));
- QTRY_COMPARE(window.mousePressScreenPos, points[0].area.center());
+ const int fuzz = 2 * int(QHighDpiScaling::factor(&window));
+ QTRY_VERIFY2(qFuzzyCompareWindowPosition(window.mousePressScreenPos.toPoint(), area.center(), fuzz),
+ qPrintable(msgPointMismatch(window.mousePressScreenPos.toPoint(), area.center())));
// Cancel the touch. Should result in a mouse release for windows that have
// have an active touch-to-mouse sequence.
@@ -1112,7 +1201,7 @@ void tst_QWindow::close()
void tst_QWindow::activateAndClose()
{
- if (qApp->platformName().toLower() == QLatin1String("wayland"))
+ if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
QSKIP("Wayland: This fails. Figure out why.");
for (int i = 0; i < 10; ++i) {
@@ -1149,8 +1238,9 @@ void tst_QWindow::mouseEventSequence()
ulong timestamp = 0;
QPointF local(12, 34);
- QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton);
- QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton);
+ const QPointF deviceLocal = QHighDpi::toNativePixels(local, &window);
+ QWindowSystemInterface::handleMouseEvent(&window, timestamp++, deviceLocal, deviceLocal, Qt::LeftButton);
+ QWindowSystemInterface::handleMouseEvent(&window, timestamp++, deviceLocal, deviceLocal, Qt::NoButton);
QCoreApplication::processEvents();
QCOMPARE(window.mousePressedCount, 1);
QCOMPARE(window.mouseReleasedCount, 1);
@@ -1308,14 +1398,14 @@ void tst_QWindow::inputReentrancy()
class TabletTestWindow : public QWindow
{
public:
- TabletTestWindow() : eventType(0) { }
+ TabletTestWindow() : eventType(QEvent::None) { }
void tabletEvent(QTabletEvent *ev) {
eventType = ev->type();
eventGlobal = ev->globalPosF();
eventLocal = ev->posF();
eventDevice = ev->device();
}
- int eventType;
+ QEvent::Type eventType;
QPointF eventGlobal, eventLocal;
int eventDevice;
bool eventFilter(QObject *obj, QEvent *ev) {
@@ -1337,25 +1427,27 @@ void tst_QWindow::tabletEvents()
window.setGeometry(QRect(m_availableTopLeft + QPoint(10, 10), m_testWindowSize));
qGuiApp->installEventFilter(&window);
- QPoint local(10, 10);
- QPoint global = window.mapToGlobal(local);
- QWindowSystemInterface::handleTabletEvent(&window, true, local, global, 1, 2, 0.5, 1, 2, 0.1, 0, 0, 0);
+ const QPoint local(10, 10);
+ const QPoint global = window.mapToGlobal(local);
+ const QPoint deviceLocal = QHighDpi::toNativeLocalPosition(local, &window);
+ const QPoint deviceGlobal = QHighDpi::toNativePixels(global, window.screen());
+ QWindowSystemInterface::handleTabletEvent(&window, true, deviceLocal, deviceGlobal, 1, 2, 0.5, 1, 2, 0.1, 0, 0, 0);
QCoreApplication::processEvents();
QTRY_VERIFY(window.eventType == QEvent::TabletPress);
QTRY_COMPARE(window.eventGlobal.toPoint(), global);
QTRY_COMPARE(window.eventLocal.toPoint(), local);
- QWindowSystemInterface::handleTabletEvent(&window, false, local, global, 1, 2, 0.5, 1, 2, 0.1, 0, 0, 0);
+ QWindowSystemInterface::handleTabletEvent(&window, false, deviceLocal, deviceGlobal, 1, 2, 0.5, 1, 2, 0.1, 0, 0, 0);
QCoreApplication::processEvents();
- QTRY_VERIFY(window.eventType == QEvent::TabletRelease);
+ QTRY_COMPARE(window.eventType, QEvent::TabletRelease);
QWindowSystemInterface::handleTabletEnterProximityEvent(1, 2, 3);
QCoreApplication::processEvents();
- QTRY_VERIFY(window.eventType == QEvent::TabletEnterProximity);
+ QTRY_COMPARE(window.eventType, QEvent::TabletEnterProximity);
QTRY_COMPARE(window.eventDevice, 1);
QWindowSystemInterface::handleTabletLeaveProximityEvent(1, 2, 3);
QCoreApplication::processEvents();
- QTRY_VERIFY(window.eventType == QEvent::TabletLeaveProximity);
+ QTRY_COMPARE(window.eventType, QEvent::TabletLeaveProximity);
QTRY_COMPARE(window.eventDevice, 1);
#endif
@@ -1363,7 +1455,7 @@ void tst_QWindow::tabletEvents()
void tst_QWindow::windowModality_QTBUG27039()
{
- if (qApp->platformName().toLower() == QLatin1String("wayland"))
+ if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
QSKIP("Wayland: This fails. Figure out why.");
QWindow parent;
@@ -1458,7 +1550,7 @@ void tst_QWindow::mask()
void tst_QWindow::initialSize()
{
- if (qApp->platformName().toLower() == QLatin1String("wayland"))
+ if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
QSKIP("Wayland: This fails. Figure out why.");
QSize defaultSize(0,0);
@@ -1499,7 +1591,7 @@ void tst_QWindow::initialSize()
void tst_QWindow::modalDialog()
{
- if (qApp->platformName().toLower() == QLatin1String("wayland"))
+ if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
QSKIP("Wayland: This fails. Figure out why.");
QWindow normalWindow;
@@ -1525,7 +1617,7 @@ void tst_QWindow::modalDialog()
void tst_QWindow::modalDialogClosingOneOfTwoModal()
{
- if (qApp->platformName().toLower() == QLatin1String("wayland"))
+ if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
QSKIP("Wayland: This fails. Figure out why.");
QWindow normalWindow;
@@ -1563,7 +1655,7 @@ void tst_QWindow::modalDialogClosingOneOfTwoModal()
void tst_QWindow::modalWithChildWindow()
{
- if (qApp->platformName().toLower() == QLatin1String("wayland"))
+ if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
QSKIP("Wayland: This fails. Figure out why.");
QWindow normalWindow;
@@ -1597,7 +1689,7 @@ void tst_QWindow::modalWithChildWindow()
void tst_QWindow::modalWindowModallity()
{
- if (qApp->platformName().toLower() == QLatin1String("wayland"))
+ if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
QSKIP("Wayland: This fails. Figure out why.");
QWindow normal_window;
@@ -1703,13 +1795,13 @@ void tst_QWindow::requestUpdate()
QCoreApplication::processEvents();
QTRY_VERIFY(window.isExposed());
- QVERIFY(window.received(QEvent::UpdateRequest) == 0);
+ QCOMPARE(window.received(QEvent::UpdateRequest), 0);
window.requestUpdate();
- QTRY_VERIFY(window.received(QEvent::UpdateRequest) == 1);
+ QTRY_COMPARE(window.received(QEvent::UpdateRequest), 1);
window.requestUpdate();
- QTRY_VERIFY(window.received(QEvent::UpdateRequest) == 2);
+ QTRY_COMPARE(window.received(QEvent::UpdateRequest), 2);
}
#include <tst_qwindow.moc>