diff options
Diffstat (limited to 'tests/auto/gui')
22 files changed, 828 insertions, 26 deletions
diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index b84aa52465..2a9b92ed35 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -2132,6 +2132,12 @@ void tst_QImage::paintEngine() QCOMPARE(engine, img.paintEngine()); QCOMPARE(img, expected); + + { + QImage img1(16, 16, QImage::Format_ARGB32); + QImage img2 = img1; + QVERIFY(img2.paintEngine()); + } } void tst_QImage::setAlphaChannelWhilePainting() diff --git a/tests/auto/gui/kernel/kernel.pro b/tests/auto/gui/kernel/kernel.pro index 42135dae24..106e9050b8 100644 --- a/tests/auto/gui/kernel/kernel.pro +++ b/tests/auto/gui/kernel/kernel.pro @@ -4,11 +4,14 @@ SUBDIRS=\ qclipboard \ qcursor \ qdrag \ + qguiaction \ + qguiactiongroup \ qevent \ qfileopenevent \ qguieventdispatcher \ qguieventloop \ qguimetatype \ + qguishortcut \ qguitimer \ qguivariant \ qhighdpiscaling \ @@ -29,6 +32,12 @@ SUBDIRS=\ win32:!winrt:qtHaveModule(network): SUBDIRS += noqteventloop +!qtConfig(shortcut): SUBDIRS -= \ + qkeysequence \ + qguishortcut \ + qguimetatype \ + qguivariant + !qtHaveModule(widgets): SUBDIRS -= \ qmouseevent_modal \ qtouchevent @@ -36,6 +45,10 @@ win32:!winrt:qtHaveModule(network): SUBDIRS += noqteventloop !qtHaveModule(network): SUBDIRS -= \ qguieventloop +!qtConfig(action): SUBDIRS -= \ + qguiaction \ + qguiactiongroup + !qtConfig(highdpiscaling): SUBDIRS -= qhighdpiscaling !qtConfig(opengl): SUBDIRS -= qopenglwindow diff --git a/tests/auto/gui/kernel/qguiaction/.gitignore b/tests/auto/gui/kernel/qguiaction/.gitignore new file mode 100644 index 0000000000..bf81f5bf2c --- /dev/null +++ b/tests/auto/gui/kernel/qguiaction/.gitignore @@ -0,0 +1 @@ +tst_qaction diff --git a/tests/auto/gui/kernel/qguiaction/qguiaction.pro b/tests/auto/gui/kernel/qguiaction/qguiaction.pro new file mode 100644 index 0000000000..2a39636119 --- /dev/null +++ b/tests/auto/gui/kernel/qguiaction/qguiaction.pro @@ -0,0 +1,4 @@ +CONFIG += testcase +TARGET = tst_qguiaction +QT += gui-private core-private testlib +SOURCES += tst_qguiaction.cpp diff --git a/tests/auto/gui/kernel/qguiaction/tst_qguiaction.cpp b/tests/auto/gui/kernel/qguiaction/tst_qguiaction.cpp new file mode 100644 index 0000000000..9d45d4ae14 --- /dev/null +++ b/tests/auto/gui/kernel/qguiaction/tst_qguiaction.cpp @@ -0,0 +1,210 @@ +/**************************************************************************** +** +** Copyright (C) 2019 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 <QtTest/QtTest> + +#include <qguiapplication.h> +#include <qevent.h> +#include <qguiaction.h> +#include <qguiactiongroup.h> +#include <qpa/qplatformtheme.h> + +#include <private/qguiapplication_p.h> + +class tst_QGuiAction : public QObject +{ + Q_OBJECT + +public: + tst_QGuiAction(); + +private slots: + void cleanup(); + void getSetCheck(); + void setText_data(); + void setText(); + void setIconText_data() { setText_data(); } + void setIconText(); +#if QT_CONFIG(shortcut) + void setStandardKeys(); + void task200823_tooltip(); +#endif + void task229128TriggeredSignalWithoutActiongroup(); + void setData(); + +private: + const int m_keyboardScheme; +}; + +tst_QGuiAction::tst_QGuiAction() + : m_keyboardScheme(QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::KeyboardScheme).toInt()) +{ +} + +void tst_QGuiAction::cleanup() +{ + QVERIFY(QGuiApplication::topLevelWindows().isEmpty()); +} + +// Testing get/set functions +void tst_QGuiAction::getSetCheck() +{ + QGuiAction obj1(nullptr); + // QActionGroup * QAction::actionGroup() + // void QAction::setActionGroup(QActionGroup *) + auto var1 = new QGuiActionGroup(nullptr); + obj1.setActionGroup(var1); + QCOMPARE(var1, obj1.guiActionGroup()); + obj1.setActionGroup(nullptr); + QCOMPARE(obj1.guiActionGroup(), nullptr); + delete var1; + + QCOMPARE(obj1.priority(), QGuiAction::NormalPriority); + obj1.setPriority(QGuiAction::LowPriority); + QCOMPARE(obj1.priority(), QGuiAction::LowPriority); +} + +void tst_QGuiAction::setText_data() +{ + QTest::addColumn<QString>("text"); + QTest::addColumn<QString>("iconText"); + QTest::addColumn<QString>("textFromIconText"); + + //next we fill it with data + QTest::newRow("Normal") << "Action" << "Action" << "Action"; + QTest::newRow("Ampersand") << "Search && Destroy" << "Search & Destroy" << "Search && Destroy"; + QTest::newRow("Mnemonic and ellipsis") << "O&pen File ..." << "Open File" << "Open File"; +} + +void tst_QGuiAction::setText() +{ + QFETCH(QString, text); + + QGuiAction action(nullptr); + action.setText(text); + + QCOMPARE(action.text(), text); + + QFETCH(QString, iconText); + QCOMPARE(action.iconText(), iconText); +} + +void tst_QGuiAction::setIconText() +{ + QFETCH(QString, iconText); + + QGuiAction action(nullptr); + action.setIconText(iconText); + QCOMPARE(action.iconText(), iconText); + + QFETCH(QString, textFromIconText); + QCOMPARE(action.text(), textFromIconText); +} + +#if QT_CONFIG(shortcut) + +//basic testing of standard keys +void tst_QGuiAction::setStandardKeys() +{ + QGuiAction act(nullptr); + act.setShortcut(QKeySequence("CTRL+L")); + QList<QKeySequence> list; + act.setShortcuts(list); + act.setShortcuts(QKeySequence::Copy); + QCOMPARE(act.shortcut(), act.shortcuts().constFirst()); + + QList<QKeySequence> expected; + const QKeySequence ctrlC = QKeySequence(QStringLiteral("CTRL+C")); + const QKeySequence ctrlInsert = QKeySequence(QStringLiteral("CTRL+INSERT")); + switch (m_keyboardScheme) { + case QPlatformTheme::MacKeyboardScheme: + expected << ctrlC; + break; + case QPlatformTheme::WindowsKeyboardScheme: + expected << ctrlC << ctrlInsert; + break; + default: // X11 + expected << ctrlC << ctrlInsert << QKeySequence(QStringLiteral("F16")); + break; + } + + QCOMPARE(act.shortcuts(), expected); +} + +void tst_QGuiAction::task200823_tooltip() +{ + const QScopedPointer<QGuiAction> action(new QGuiAction("foo", nullptr)); + QString shortcut("ctrl+o"); + action->setShortcut(shortcut); + + // we want a non-standard tooltip that shows the shortcut + action->setToolTip(action->text() + QLatin1String(" (") + action->shortcut().toString() + QLatin1Char(')')); + + QString ref = QLatin1String("foo (") + QKeySequence(shortcut).toString() + QLatin1Char(')'); + QCOMPARE(action->toolTip(), ref); +} + +#endif // QT_CONFIG(shortcut) + +void tst_QGuiAction::task229128TriggeredSignalWithoutActiongroup() +{ + // test without a group + const QScopedPointer<QGuiAction> actionWithoutGroup(new QGuiAction("Test", nullptr)); + QSignalSpy spyWithoutGroup(actionWithoutGroup.data(), QOverload<bool>::of(&QGuiAction::triggered)); + QCOMPARE(spyWithoutGroup.count(), 0); + actionWithoutGroup->trigger(); + // signal should be emitted + QCOMPARE(spyWithoutGroup.count(), 1); + + // it is now a checkable checked action + actionWithoutGroup->setCheckable(true); + actionWithoutGroup->setChecked(true); + spyWithoutGroup.clear(); + QCOMPARE(spyWithoutGroup.count(), 0); + actionWithoutGroup->trigger(); + // signal should be emitted + QCOMPARE(spyWithoutGroup.count(), 1); +} + +void tst_QGuiAction::setData() // QTBUG-62006 +{ + QGuiAction act(nullptr); + QSignalSpy spy(&act, &QGuiAction::changed); + QCOMPARE(act.data(), QVariant()); + QCOMPARE(spy.count(), 0); + act.setData(QVariant()); + QCOMPARE(spy.count(), 0); + + act.setData(-1); + QCOMPARE(spy.count(), 1); + act.setData(-1); + QCOMPARE(spy.count(), 1); +} + +QTEST_MAIN(tst_QGuiAction) +#include "tst_qguiaction.moc" diff --git a/tests/auto/gui/kernel/qguiactiongroup/.gitignore b/tests/auto/gui/kernel/qguiactiongroup/.gitignore new file mode 100644 index 0000000000..daba003e96 --- /dev/null +++ b/tests/auto/gui/kernel/qguiactiongroup/.gitignore @@ -0,0 +1 @@ +tst_qactiongroup diff --git a/tests/auto/gui/kernel/qguiactiongroup/qguiactiongroup.pro b/tests/auto/gui/kernel/qguiactiongroup/qguiactiongroup.pro new file mode 100644 index 0000000000..7fd64e70f1 --- /dev/null +++ b/tests/auto/gui/kernel/qguiactiongroup/qguiactiongroup.pro @@ -0,0 +1,4 @@ +CONFIG += testcase +TARGET = tst_qactiongroup +QT += testlib +SOURCES += tst_qguiactiongroup.cpp diff --git a/tests/auto/gui/kernel/qguiactiongroup/tst_qguiactiongroup.cpp b/tests/auto/gui/kernel/qguiactiongroup/tst_qguiactiongroup.cpp new file mode 100644 index 0000000000..1ac14280fb --- /dev/null +++ b/tests/auto/gui/kernel/qguiactiongroup/tst_qguiactiongroup.cpp @@ -0,0 +1,235 @@ +/**************************************************************************** +** +** Copyright (C) 2019 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 <QtTest/QtTest> + +#include <qguiaction.h> +#include <qguiactiongroup.h> + +class tst_QGuiActionGroup : public QObject +{ + Q_OBJECT + +private slots: + void cleanup() { QVERIFY(QGuiApplication::topLevelWindows().isEmpty()); } + void enabledPropagation(); + void visiblePropagation(); + void exclusive(); + void exclusiveOptional(); + void testActionInTwoQActionGroup(); + void unCheckCurrentAction(); +}; + +void tst_QGuiActionGroup::enabledPropagation() +{ + QGuiActionGroup testActionGroup(nullptr); + + auto childAction = new QGuiAction( &testActionGroup ); + auto anotherChildAction = new QGuiAction( &testActionGroup ); + auto freeAction = new QGuiAction(nullptr); + + QVERIFY( testActionGroup.isEnabled() ); + QVERIFY( childAction->isEnabled() ); + + testActionGroup.setEnabled( false ); + QVERIFY( !testActionGroup.isEnabled() ); + QVERIFY( !childAction->isEnabled() ); + QVERIFY( !anotherChildAction->isEnabled() ); + + childAction->setEnabled(true); + QVERIFY( !childAction->isEnabled()); + + anotherChildAction->setEnabled( false ); + + testActionGroup.setEnabled( true ); + QVERIFY( testActionGroup.isEnabled() ); + QVERIFY( childAction->isEnabled() ); + QVERIFY( !anotherChildAction->isEnabled() ); + + testActionGroup.setEnabled( false ); + auto lastChildAction = new QGuiAction(&testActionGroup); + + QVERIFY(!lastChildAction->isEnabled()); + testActionGroup.setEnabled( true ); + QVERIFY(lastChildAction->isEnabled()); + + freeAction->setEnabled(false); + testActionGroup.addAction(freeAction); + QVERIFY(!freeAction->isEnabled()); + delete freeAction; +} + +void tst_QGuiActionGroup::visiblePropagation() +{ + QGuiActionGroup testActionGroup(nullptr); + + auto childAction = new QGuiAction( &testActionGroup ); + auto anotherChildAction = new QGuiAction( &testActionGroup ); + auto freeAction = new QGuiAction(nullptr); + + QVERIFY( testActionGroup.isVisible() ); + QVERIFY( childAction->isVisible() ); + + testActionGroup.setVisible( false ); + QVERIFY( !testActionGroup.isVisible() ); + QVERIFY( !childAction->isVisible() ); + QVERIFY( !anotherChildAction->isVisible() ); + + anotherChildAction->setVisible(false); + + testActionGroup.setVisible( true ); + QVERIFY( testActionGroup.isVisible() ); + QVERIFY( childAction->isVisible() ); + + QVERIFY( !anotherChildAction->isVisible() ); + + testActionGroup.setVisible( false ); + auto lastChildAction = new QGuiAction(&testActionGroup); + + QVERIFY(!lastChildAction->isVisible()); + testActionGroup.setVisible( true ); + QVERIFY(lastChildAction->isVisible()); + + freeAction->setVisible(false); + testActionGroup.addAction(freeAction); + QVERIFY(!freeAction->isVisible()); + delete freeAction; +} + +void tst_QGuiActionGroup::exclusive() +{ + QGuiActionGroup group(nullptr); + group.setExclusive(false); + QVERIFY( !group.isExclusive() ); + + auto actOne = new QGuiAction(&group); + actOne->setCheckable( true ); + auto actTwo = new QGuiAction(&group); + actTwo->setCheckable( true ); + auto actThree = new QGuiAction(&group); + actThree->setCheckable( true ); + + group.setExclusive( true ); + QVERIFY( !actOne->isChecked() ); + QVERIFY( !actTwo->isChecked() ); + QVERIFY( !actThree->isChecked() ); + + actOne->setChecked( true ); + QVERIFY( actOne->isChecked() ); + QVERIFY( !actTwo->isChecked() ); + QVERIFY( !actThree->isChecked() ); + + actTwo->setChecked( true ); + QVERIFY( !actOne->isChecked() ); + QVERIFY( actTwo->isChecked() ); + QVERIFY( !actThree->isChecked() ); +} + +void tst_QGuiActionGroup::exclusiveOptional() +{ + QGuiActionGroup group(0); + group.setExclusive(true); + QVERIFY( group.isExclusive() ); + + auto actOne = new QGuiAction(&group); + actOne->setCheckable( true ); + auto actTwo = new QGuiAction(&group); + actTwo->setCheckable( true ); + auto actThree = new QGuiAction(&group); + actThree->setCheckable( true ); + + QVERIFY( !actOne->isChecked() ); + QVERIFY( !actTwo->isChecked() ); + QVERIFY( !actThree->isChecked() ); + + actOne->trigger(); + QVERIFY( actOne->isChecked() ); + QVERIFY( !actTwo->isChecked() ); + QVERIFY( !actThree->isChecked() ); + + actOne->trigger(); + QVERIFY( actOne->isChecked() ); + QVERIFY( !actTwo->isChecked() ); + QVERIFY( !actThree->isChecked() ); + + group.setExclusionPolicy(QGuiActionGroup::ExclusionPolicy::ExclusiveOptional); + QVERIFY( group.isExclusive() ); + + actOne->trigger(); + QVERIFY( !actOne->isChecked() ); + QVERIFY( !actTwo->isChecked() ); + QVERIFY( !actThree->isChecked() ); + + actTwo->trigger(); + QVERIFY( !actOne->isChecked() ); + QVERIFY( actTwo->isChecked() ); + QVERIFY( !actThree->isChecked() ); + + actTwo->trigger(); + QVERIFY( !actOne->isChecked() ); + QVERIFY( !actTwo->isChecked() ); + QVERIFY( !actThree->isChecked() ); +} + +void tst_QGuiActionGroup::testActionInTwoQActionGroup() +{ + QGuiAction action1("Action 1", this); + + QGuiActionGroup group1(this); + QGuiActionGroup group2(this); + + group1.addAction(&action1); + group2.addAction(&action1); + + QCOMPARE(action1.guiActionGroup(), &group2); + QCOMPARE(group2.guiActions().constFirst(), &action1); + QCOMPARE(group1.guiActions().isEmpty(), true); +} + +void tst_QGuiActionGroup::unCheckCurrentAction() +{ + QGuiActionGroup group(nullptr); + QGuiAction action1(&group) ,action2(&group); + action1.setCheckable(true); + action2.setCheckable(true); + QVERIFY(!action1.isChecked()); + QVERIFY(!action2.isChecked()); + action1.setChecked(true); + QVERIFY(action1.isChecked()); + QVERIFY(!action2.isChecked()); + auto current = group.checkedGuiAction(); + QCOMPARE(current, &action1); + current->setChecked(false); + QVERIFY(!action1.isChecked()); + QVERIFY(!action2.isChecked()); + QVERIFY(!group.checkedGuiAction()); +} + + +QTEST_MAIN(tst_QGuiActionGroup) +#include "tst_qguiactiongroup.moc" diff --git a/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp b/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp index 3ce65a6785..2645bb111e 100644 --- a/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp +++ b/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp @@ -181,9 +181,13 @@ template<> struct TestValueFactory<QMetaType::QCursor> { static QCursor *create() { return new QCursor(Qt::WaitCursor); } }; #endif + +#if QT_CONFIG(shortcut) template<> struct TestValueFactory<QMetaType::QKeySequence> { static QKeySequence *create() { return new QKeySequence(QKeySequence::Close); } }; +#endif + template<> struct TestValueFactory<QMetaType::QPen> { static QPen *create() { return new QPen(Qt::DashDotDotLine); } }; @@ -312,30 +316,10 @@ void tst_QGuiMetaType::sizeOf() QCOMPARE(QMetaType::sizeOf(type), size); } -#ifndef Q_ALIGNOF -template<uint N> -struct RoundToNextHighestPowerOfTwo -{ -private: - enum { V1 = N-1 }; - enum { V2 = V1 | (V1 >> 1) }; - enum { V3 = V2 | (V2 >> 2) }; - enum { V4 = V3 | (V3 >> 4) }; - enum { V5 = V4 | (V4 >> 8) }; - enum { V6 = V5 | (V5 >> 16) }; -public: - enum { Value = V6 + 1 }; -}; -#endif - template<class T> struct TypeAlignment { -#ifdef Q_ALIGNOF - enum { Value = Q_ALIGNOF(T) }; -#else - enum { Value = RoundToNextHighestPowerOfTwo<sizeof(T)>::Value }; -#endif + enum { Value = alignof(T) }; }; void tst_QGuiMetaType::flags_data() diff --git a/tests/auto/gui/kernel/qguishortcut/qguishortcut.pro b/tests/auto/gui/kernel/qguishortcut/qguishortcut.pro new file mode 100644 index 0000000000..1417dee213 --- /dev/null +++ b/tests/auto/gui/kernel/qguishortcut/qguishortcut.pro @@ -0,0 +1,4 @@ +CONFIG += testcase +TARGET = tst_qguishortcut +QT += testlib +SOURCES += tst_qguishortcut.cpp diff --git a/tests/auto/gui/kernel/qguishortcut/tst_qguishortcut.cpp b/tests/auto/gui/kernel/qguishortcut/tst_qguishortcut.cpp new file mode 100644 index 0000000000..bc3fb9862d --- /dev/null +++ b/tests/auto/gui/kernel/qguishortcut/tst_qguishortcut.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2019 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 <QtTest/QtTest> +#include <QtGui/qguiapplication.h> +#include <QtGui/qguishortcut.h> +#include <QtGui/qpainter.h> +#include <QtGui/qrasterwindow.h> +#include <QtGui/qscreen.h> +#include <QtGui/qwindow.h> + +class tst_QGuiShortcut : public QObject +{ + Q_OBJECT +public: + +private slots: + void trigger(); +}; + +class ColoredWindow : public QRasterWindow { +public: + ColoredWindow(QColor c) : m_color(c) {} + +protected: + void paintEvent(QPaintEvent *event) override; + +private: + const QColor m_color; +}; + +void ColoredWindow::paintEvent(QPaintEvent *) +{ + QPainter p(this); + p.fillRect(QRect(QPoint(), size()), m_color); +} + +static void sendKey(QWindow *target, Qt::Key k, char c, Qt::KeyboardModifiers modifiers) +{ + QTest::sendKeyEvent(QTest::Press, target, k, c, modifiers); + QTest::sendKeyEvent(QTest::Release, target, k, c, modifiers); +} + +void tst_QGuiShortcut::trigger() +{ + ColoredWindow w(Qt::yellow); + w.setTitle(QTest::currentTestFunction()); + w.resize(QGuiApplication::primaryScreen()->size() / 4); + new QGuiShortcut(Qt::CTRL + Qt::Key_Q, &w, SLOT(close())); + w.show(); + QVERIFY(QTest::qWaitForWindowExposed(&w)); + sendKey(&w, Qt::Key_Q, 'q', Qt::ControlModifier); + QTRY_VERIFY(!w.isVisible()); +} + +QTEST_MAIN(tst_QGuiShortcut) +#include "tst_qguishortcut.moc" diff --git a/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp b/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp index 87a47bd93b..6a928cac7a 100644 --- a/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp +++ b/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp @@ -64,8 +64,10 @@ public: private slots: void basicEventDelivery(); +#if QT_CONFIG(shortcut) void modifiers_data(); void modifiers(); +#endif }; tst_QKeyEvent::tst_QKeyEvent() @@ -128,6 +130,8 @@ static QByteArray modifiersTestRowName(const QString &keySequence) return result; } +#if QT_CONFIG(shortcut) + void tst_QKeyEvent::modifiers_data() { struct Modifier @@ -198,5 +202,7 @@ void tst_QKeyEvent::modifiers() } } +#endif // QT_CONFIG(shortcut) + QTEST_MAIN(tst_QKeyEvent) #include "tst_qkeyevent.moc" diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index d2a4dfc3e9..6e48439944 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -157,10 +157,10 @@ private slots: void clippedLines(); void clippedPolygon_data(); void clippedPolygon(); - void clippedText(); void clipBoundingRect(); + void transformedClip(); void setOpacity_data(); void setOpacity(); @@ -4589,6 +4589,53 @@ void tst_QPainter::clipBoundingRect() } +void tst_QPainter::transformedClip() +{ + QImage img(8, 4, QImage::Format_ARGB32_Premultiplied); + QImage img2(img.size(), img.format()); + QRect clip(0, 0, 2, 1); + QTransform xf; + xf.translate(0.2, 0); + xf.scale(2.2, 1); + // setClipRect(QRectF) + { + img.fill(Qt::green); + QPainter p(&img); + p.setTransform(xf); + p.setClipRect(QRectF(clip)); + p.fillRect(img.rect(), Qt::white); + } + // setClipRect(QRect) + { + img2.fill(Qt::green); + QPainter p(&img2); + p.setTransform(xf); + p.setClipRect(clip); + p.fillRect(img2.rect(), Qt::white); + QCOMPARE(img, img2); + } + // setClipRegion + { + img2.fill(Qt::green); + QPainter p(&img2); + p.setTransform(xf); + p.setClipRegion(QRegion(clip) + QRect(0, 3, 1, 1)); // dummy extra rect to avoid single-rect codepath + p.fillRect(img2.rect(), Qt::white); + QCOMPARE(img.copy(0, 0, 8, 2), img2.copy(0, 0, 8, 2)); + } + // setClipPath + { + img2.fill(Qt::green); + QPainter p(&img2); + p.setTransform(xf); + QPainterPath path; + path.addRect(clip); + p.setClipPath(path); + p.fillRect(img2.rect(), Qt::white); + QCOMPARE(img, img2); + } +} + #if defined(Q_OS_MAC) // Only Mac supports sub pixel positions in raster engine currently void tst_QPainter::drawText_subPixelPositionsInRaster_qtbug5053() diff --git a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp index 768b227ecd..533d6b17b1 100644 --- a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp +++ b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp @@ -1590,6 +1590,9 @@ void tst_QRhi::renderToWindowSimple() QScopedPointer<QWindow> window(new QWindow); switch (impl) { case QRhi::OpenGLES2: +#if QT_CONFIG(opengl) + window->setFormat(QRhiGles2InitParams::adjustedFormat()); +#endif Q_FALLTHROUGH(); case QRhi::D3D11: window->setSurfaceType(QSurface::OpenGLSurface); diff --git a/tests/auto/gui/rhi/qshader/data/README b/tests/auto/gui/rhi/qshader/data/README new file mode 100644 index 0000000000..3d89f2a0c5 --- /dev/null +++ b/tests/auto/gui/rhi/qshader/data/README @@ -0,0 +1,15 @@ +Warning: Do NOT regenerate the .qsb files without proper planning and understanding +the following. + +Among other things, we are also testing backwards compatibility for QShader +deserialization. + +.qsb files with _v1 in the name were produced with an older qtshadertools +and have a QSB_VERSION of 1. + +Files with _v2 are generated with a newer qsb, those have QSB_VERSION 2. +The difference is the support for nativeResourceBindingMap() which is only +present in v2. + +Files with _v3 come from an even newer qsb, and have QSB_VERSION 3. The +difference to 2 is the use of CBOR instead of binary JSON for QShaderDescription. diff --git a/tests/auto/gui/rhi/qshader/data/color.vert.qsb b/tests/auto/gui/rhi/qshader/data/color_all_v1.vert.qsb Binary files differindex 7d02d823d2..7d02d823d2 100644 --- a/tests/auto/gui/rhi/qshader/data/color.vert.qsb +++ b/tests/auto/gui/rhi/qshader/data/color_all_v1.vert.qsb diff --git a/tests/auto/gui/rhi/qshader/data/color_simple.vert.qsb b/tests/auto/gui/rhi/qshader/data/color_spirv_v1.vert.qsb Binary files differindex c82ba7e8e7..c82ba7e8e7 100644 --- a/tests/auto/gui/rhi/qshader/data/color_simple.vert.qsb +++ b/tests/auto/gui/rhi/qshader/data/color_spirv_v1.vert.qsb diff --git a/tests/auto/gui/rhi/qshader/data/texture.frag b/tests/auto/gui/rhi/qshader/data/texture.frag new file mode 100644 index 0000000000..bd22f817e0 --- /dev/null +++ b/tests/auto/gui/rhi/qshader/data/texture.frag @@ -0,0 +1,16 @@ +#version 440 + +layout(location = 0) in vec2 qt_TexCoord; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float opacity; +} ubuf; + +layout(binding = 1) uniform sampler2D qt_Texture; + +void main() +{ + fragColor = texture(qt_Texture, qt_TexCoord) * ubuf.opacity; +} diff --git a/tests/auto/gui/rhi/qshader/data/texture_all_v2.frag.qsb b/tests/auto/gui/rhi/qshader/data/texture_all_v2.frag.qsb Binary files differnew file mode 100644 index 0000000000..79f5486945 --- /dev/null +++ b/tests/auto/gui/rhi/qshader/data/texture_all_v2.frag.qsb diff --git a/tests/auto/gui/rhi/qshader/data/texture_all_v3.frag.qsb b/tests/auto/gui/rhi/qshader/data/texture_all_v3.frag.qsb Binary files differnew file mode 100644 index 0000000000..b6e49aa03d --- /dev/null +++ b/tests/auto/gui/rhi/qshader/data/texture_all_v3.frag.qsb diff --git a/tests/auto/gui/rhi/qshader/tst_qshader.cpp b/tests/auto/gui/rhi/qshader/tst_qshader.cpp index 21f0cc7895..a0082f1e3b 100644 --- a/tests/auto/gui/rhi/qshader/tst_qshader.cpp +++ b/tests/auto/gui/rhi/qshader/tst_qshader.cpp @@ -40,6 +40,9 @@ private slots: void genVariants(); void shaderDescImplicitSharing(); void bakedShaderImplicitSharing(); + void mslResourceMapping(); + void loadV3(); + void serializeShaderDesc(); }; static QShader getShader(const QString &name) @@ -53,8 +56,9 @@ static QShader getShader(const QString &name) void tst_QShader::simpleCompileCheckResults() { - QShader s = getShader(QLatin1String(":/data/color_simple.vert.qsb")); + QShader s = getShader(QLatin1String(":/data/color_spirv_v1.vert.qsb")); QVERIFY(s.isValid()); + QCOMPARE(QShaderPrivate::get(&s)->qsbVersion, 1); QCOMPARE(s.availableShaders().count(), 1); const QShaderCode shader = s.shader(QShaderKey(QShader::SpirvShader, @@ -125,10 +129,11 @@ void tst_QShader::simpleCompileCheckResults() void tst_QShader::genVariants() { - QShader s = getShader(QLatin1String(":/data/color.vert.qsb")); + QShader s = getShader(QLatin1String(":/data/color_all_v1.vert.qsb")); // spirv, glsl 100, glsl 330, glsl 120, hlsl 50, msl 12 // + batchable variants QVERIFY(s.isValid()); + QCOMPARE(QShaderPrivate::get(&s)->qsbVersion, 1); QCOMPARE(s.availableShaders().count(), 2 * 6); int batchableVariantCount = 0; @@ -149,8 +154,9 @@ void tst_QShader::genVariants() void tst_QShader::shaderDescImplicitSharing() { - QShader s = getShader(QLatin1String(":/data/color_simple.vert.qsb")); + QShader s = getShader(QLatin1String(":/data/color_spirv_v1.vert.qsb")); QVERIFY(s.isValid()); + QCOMPARE(QShaderPrivate::get(&s)->qsbVersion, 1); QCOMPARE(s.availableShaders().count(), 1); QVERIFY(s.availableShaders().contains(QShaderKey(QShader::SpirvShader, QShaderVersion(100)))); @@ -168,6 +174,7 @@ void tst_QShader::shaderDescImplicitSharing() QCOMPARE(d1.inputVariables().count(), 2); QCOMPARE(d1.outputVariables().count(), 1); QCOMPARE(d1.uniformBlocks().count(), 1); + QCOMPARE(d0, d1); d1.detach(); QVERIFY(QShaderDescriptionPrivate::get(&d0) != QShaderDescriptionPrivate::get(&d1)); @@ -177,12 +184,17 @@ void tst_QShader::shaderDescImplicitSharing() QCOMPARE(d1.inputVariables().count(), 2); QCOMPARE(d1.outputVariables().count(), 1); QCOMPARE(d1.uniformBlocks().count(), 1); + QCOMPARE(d0, d1); + + d1 = QShaderDescription(); + QVERIFY(d0 != d1); } void tst_QShader::bakedShaderImplicitSharing() { - QShader s0 = getShader(QLatin1String(":/data/color_simple.vert.qsb")); + QShader s0 = getShader(QLatin1String(":/data/color_spirv_v1.vert.qsb")); QVERIFY(s0.isValid()); + QCOMPARE(QShaderPrivate::get(&s0)->qsbVersion, 1); QCOMPARE(s0.availableShaders().count(), 1); QVERIFY(s0.availableShaders().contains(QShaderKey(QShader::SpirvShader, QShaderVersion(100)))); @@ -229,5 +241,159 @@ void tst_QShader::bakedShaderImplicitSharing() } } +void tst_QShader::mslResourceMapping() +{ + QShader s = getShader(QLatin1String(":/data/texture_all_v2.frag.qsb")); + QVERIFY(s.isValid()); + QCOMPARE(QShaderPrivate::get(&s)->qsbVersion, 2); + + const QVector<QShaderKey> availableShaders = s.availableShaders(); + QCOMPARE(availableShaders.count(), 7); + QVERIFY(availableShaders.contains(QShaderKey(QShader::SpirvShader, QShaderVersion(100)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::MslShader, QShaderVersion(12)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::HlslShader, QShaderVersion(50)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(100, QShaderVersion::GlslEs)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(120)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(150)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(330)))); + + const QShader::NativeResourceBindingMap *resMap = + s.nativeResourceBindingMap(QShaderKey(QShader::GlslShader, QShaderVersion(330))); + QVERIFY(!resMap); + + // The Metal shader must come with a mapping table for binding points 0 + // (uniform buffer) and 1 (combined image sampler mapped to a texture and + // sampler in the shader). + resMap = s.nativeResourceBindingMap(QShaderKey(QShader::MslShader, QShaderVersion(12))); + QVERIFY(resMap); + + QCOMPARE(resMap->count(), 2); + QCOMPARE(resMap->value(0).first, 0); // mapped to native buffer index 0 + QCOMPARE(resMap->value(1), qMakePair(0, 0)); // mapped to native texture index 0 and sampler index 0 +} + +void tst_QShader::loadV3() +{ + // qsb version 3: QShaderDescription is serialized as CBOR. Ensure the deserialized data is as expected. + QShader s = getShader(QLatin1String(":/data/texture_all_v3.frag.qsb")); + QVERIFY(s.isValid()); + QCOMPARE(QShaderPrivate::get(&s)->qsbVersion, 3); + + const QVector<QShaderKey> availableShaders = s.availableShaders(); + QCOMPARE(availableShaders.count(), 7); + QVERIFY(availableShaders.contains(QShaderKey(QShader::SpirvShader, QShaderVersion(100)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::MslShader, QShaderVersion(12)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::HlslShader, QShaderVersion(50)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(100, QShaderVersion::GlslEs)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(120)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(150)))); + QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(330)))); + + const QShaderDescription desc = s.description(); + QVERIFY(desc.isValid()); + QCOMPARE(desc.inputVariables().count(), 1); + for (const QShaderDescription::InOutVariable &v : desc.inputVariables()) { + switch (v.location) { + case 0: + QCOMPARE(v.name, QLatin1String("qt_TexCoord")); + QCOMPARE(v.type, QShaderDescription::Vec2); + break; + default: + QVERIFY(false); + break; + } + } + QCOMPARE(desc.outputVariables().count(), 1); + for (const QShaderDescription::InOutVariable &v : desc.outputVariables()) { + switch (v.location) { + case 0: + QCOMPARE(v.name, QLatin1String("fragColor")); + QCOMPARE(v.type, QShaderDescription::Vec4); + break; + default: + QVERIFY(false); + break; + } + } + QCOMPARE(desc.uniformBlocks().count(), 1); + const QShaderDescription::UniformBlock blk = desc.uniformBlocks().first(); + QCOMPARE(blk.blockName, QLatin1String("buf")); + QCOMPARE(blk.structName, QLatin1String("ubuf")); + QCOMPARE(blk.size, 68); + QCOMPARE(blk.binding, 0); + QCOMPARE(blk.descriptorSet, 0); + QCOMPARE(blk.members.count(), 2); + for (int i = 0; i < blk.members.count(); ++i) { + const QShaderDescription::BlockVariable v = blk.members[i]; + switch (i) { + case 0: + QCOMPARE(v.offset, 0); + QCOMPARE(v.size, 64); + QCOMPARE(v.name, QLatin1String("qt_Matrix")); + QCOMPARE(v.type, QShaderDescription::Mat4); + QCOMPARE(v.matrixStride, 16); + break; + case 1: + QCOMPARE(v.offset, 64); + QCOMPARE(v.size, 4); + QCOMPARE(v.name, QLatin1String("opacity")); + QCOMPARE(v.type, QShaderDescription::Float); + break; + default: + QVERIFY(false); + break; + } + } +} + +void tst_QShader::serializeShaderDesc() +{ + // default constructed QShaderDescription + { + QShaderDescription desc; + QVERIFY(!desc.isValid()); + + const QByteArray data = desc.toCbor(); + QVERIFY(!data.isEmpty()); + + QShaderDescription desc2 = QShaderDescription::fromCbor(data); + QVERIFY(!desc2.isValid()); + } + + // a QShaderDescription with inputs, outputs, uniform block and combined image sampler + { + QShader s = getShader(QLatin1String(":/data/texture_all_v3.frag.qsb")); + QVERIFY(s.isValid()); + const QShaderDescription desc = s.description(); + QVERIFY(desc.isValid()); + + const QByteArray data = desc.toCbor(); + QVERIFY(!data.isEmpty()); + + QShaderDescription desc2; + QVERIFY(!desc2.isValid()); + QVERIFY(!(desc == desc2)); + QVERIFY(desc != desc2); + + desc2 = QShaderDescription::fromCbor(data); + QVERIFY(desc2.isValid()); + QCOMPARE(desc, desc2); + } + + // exercise QShader and QShaderDescription comparisons + { + QShader s1 = getShader(QLatin1String(":/data/texture_all_v3.frag.qsb")); + QVERIFY(s1.isValid()); + QShader s2 = getShader(QLatin1String(":/data/color_all_v1.vert.qsb")); + QVERIFY(s2.isValid()); + + QVERIFY(s1.description().isValid()); + QVERIFY(s2.description().isValid()); + + QVERIFY(s1 != s2); + QVERIFY(s1.description() != s2.description()); + } +} + #include <tst_qshader.moc> QTEST_MAIN(tst_QShader) diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp index a474acd790..2dcca0209e 100644 --- a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp @@ -2068,7 +2068,12 @@ void tst_QTextLayout::cursorInLigatureWithMultipleLines() void tst_QTextLayout::xToCursorForLigatures() { +#if defined(Q_OS_WIN32) + QTextLayout layout("fi", QFont("Calibri", 20)); +#else QTextLayout layout("fi", QFont("Times", 20)); +#endif + layout.setCacheEnabled(true); layout.beginLayout(); QTextLine line = layout.createLine(); |