summaryrefslogtreecommitdiffstats
path: root/tests/auto/macgui
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commit38be0d13830efd2d98281c645c3a60afe05ffece (patch)
tree6ea73f3ec77f7d153333779883e8120f82820abe /tests/auto/macgui
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'tests/auto/macgui')
-rw-r--r--tests/auto/macgui/.gitignore1
-rw-r--r--tests/auto/macgui/guitest.cpp350
-rw-r--r--tests/auto/macgui/guitest.h186
-rw-r--r--tests/auto/macgui/macgui.pro11
-rw-r--r--tests/auto/macgui/tst_macgui.cpp251
5 files changed, 799 insertions, 0 deletions
diff --git a/tests/auto/macgui/.gitignore b/tests/auto/macgui/.gitignore
new file mode 100644
index 0000000000..2b13357fac
--- /dev/null
+++ b/tests/auto/macgui/.gitignore
@@ -0,0 +1 @@
+tst_macgui
diff --git a/tests/auto/macgui/guitest.cpp b/tests/auto/macgui/guitest.cpp
new file mode 100644
index 0000000000..a4cdeb5cab
--- /dev/null
+++ b/tests/auto/macgui/guitest.cpp
@@ -0,0 +1,350 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "guitest.h"
+#include <QDebug>
+#include <QWidget>
+#include <QStack>
+#include <QTimer>
+#include <QtTest/QtTest>
+
+#ifdef Q_OS_MAC
+# include <private/qt_mac_p.h>
+#endif
+
+
+/*
+ Not really a test, just prints interface info.
+*/
+class PrintTest : public TestBase
+{
+public:
+ bool operator()(InterfaceChildPair candidate)
+ {
+ qDebug() << "";
+ qDebug() << "Name" << candidate.iface->text(QAccessible::Name, candidate.possibleChild);
+ qDebug() << "Pos" << candidate.iface->rect(candidate.possibleChild);
+ if (candidate.possibleChild == 0)
+ qDebug() << "Number of children" << candidate.iface->childCount();
+ return false;
+ }
+};
+
+class NameTest : public TestBase
+{
+public:
+ NameTest(const QString &text, QAccessible::Text textType) : text(text), textType(textType) {}
+ QString text;
+ QAccessible::Text textType;
+
+ bool operator()(InterfaceChildPair candidate)
+ {
+ return (candidate.iface->text(textType, candidate.possibleChild) == text);
+ }
+};
+
+void WidgetNavigator::printAll(QWidget *widget)
+{
+ QAccessibleInterface * const iface = QAccessible::queryAccessibleInterface(widget);
+ deleteInDestructor(iface);
+ printAll(InterfaceChildPair(iface, 0));
+}
+
+void WidgetNavigator::printAll(InterfaceChildPair interface)
+{
+ PrintTest printTest;
+ recursiveSearch(&printTest, interface.iface, interface.possibleChild);
+}
+
+InterfaceChildPair WidgetNavigator::find(QAccessible::Text textType, const QString &text, QWidget *start)
+{
+ QAccessibleInterface * const iface = QAccessible::queryAccessibleInterface(start);
+ deleteInDestructor(iface);
+ return find(textType, text, iface);
+}
+
+InterfaceChildPair WidgetNavigator::find(QAccessible::Text textType, const QString &text, QAccessibleInterface *start)
+{
+ NameTest nameTest(text, textType);
+ return recursiveSearch(&nameTest, start, 0);
+}
+
+/*
+ Recursiveley navigates the accessible hiearchy looking for an interfafce that
+ passsed the Test (meaning it returns true).
+*/
+InterfaceChildPair WidgetNavigator::recursiveSearch(TestBase *test, QAccessibleInterface *iface, int possibleChild)
+{
+ QStack<InterfaceChildPair> todoInterfaces;
+ todoInterfaces.push(InterfaceChildPair(iface, possibleChild));
+
+ while (todoInterfaces.isEmpty() == false) {
+ InterfaceChildPair testInterface = todoInterfaces.pop();
+
+ if ((*test)(testInterface))
+ return testInterface;
+
+ if (testInterface.possibleChild != 0)
+ continue;
+
+ const int numChildren = testInterface.iface->childCount();
+ for (int i = 0; i < numChildren; ++i) {
+ QAccessibleInterface *childInterface = 0;
+ int newPossibleChild = testInterface.iface->navigate(QAccessible::Child, i + 1, &childInterface);
+ if (childInterface) {
+ todoInterfaces.push(InterfaceChildPair(childInterface, newPossibleChild));
+ deleteInDestructor(childInterface);
+ } else if (newPossibleChild != -1) {
+ todoInterfaces.push(InterfaceChildPair(testInterface.iface, newPossibleChild));
+ }
+ }
+ }
+ return InterfaceChildPair();
+}
+
+void WidgetNavigator::deleteInDestructor(QAccessibleInterface * interface)
+{
+ interfaces.insert(interface);
+}
+
+QWidget *WidgetNavigator::getWidget(InterfaceChildPair interface)
+{
+ return qobject_cast<QWidget *>(interface.iface->object());
+}
+
+WidgetNavigator::~WidgetNavigator()
+{
+ foreach(QAccessibleInterface *interface, interfaces) {
+ delete interface;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace NativeEvents {
+#ifdef Q_OS_MAC
+ void mouseClick(const QPoint &globalPos, Qt::MouseButtons buttons, MousePosition updateMouse)
+ {
+ CGPoint position;
+ position.x = globalPos.x();
+ position.y = globalPos.y();
+
+ const bool updateMousePosition = (updateMouse == UpdatePosition);
+
+ // Mouse down.
+ CGPostMouseEvent(position, updateMousePosition, 3,
+ (buttons & Qt::LeftButton) ? true : false,
+ (buttons & Qt::MidButton/* Middlebutton! */) ? true : false,
+ (buttons & Qt::RightButton) ? true : false);
+
+ // Mouse up.
+ CGPostMouseEvent(position, updateMousePosition, 3, false, false, false);
+ }
+#else
+# error Oops, NativeEvents::mouseClick() is not implemented on this platform.
+#endif
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+GuiTester::GuiTester()
+{
+ clearSequence();
+}
+
+GuiTester::~GuiTester()
+{
+ foreach(DelayedAction *action, actions)
+ delete action;
+}
+
+bool checkPixel(QColor pixel, QColor expected)
+{
+ const int allowedDiff = 20;
+
+ return !(qAbs(pixel.red() - expected.red()) > allowedDiff ||
+ qAbs(pixel.green() - expected.green()) > allowedDiff ||
+ qAbs(pixel.blue() - expected.blue()) > allowedDiff);
+}
+
+/*
+ Tests that the pixels inside rect in image all have the given color.
+*/
+bool GuiTester::isFilled(const QImage image, const QRect &rect, const QColor &color)
+{
+ for (int y = rect.top(); y <= rect.bottom(); ++y)
+ for (int x = rect.left(); x <= rect.right(); ++x) {
+ const QColor pixel = image.pixel(x, y);
+ if (checkPixel(pixel, color) == false) {
+// qDebug()<< "Wrong pixel value at" << x << y << pixel.red() << pixel.green() << pixel.blue();
+ return false;
+ }
+ }
+ return true;
+}
+
+
+/*
+ Tests that stuff is painted to the pixels inside rect.
+ This test fails if any lines in the given direction have pixels
+ of only one color.
+*/
+bool GuiTester::isContent(const QImage image, const QRect &rect, Directions directions)
+{
+ if (directions & Horizontal) {
+ for (int y = rect.top(); y <= rect.bottom(); ++y) {
+ QColor currentColor = image.pixel(rect.left(), y);
+ bool fullRun = true;
+ for (int x = rect.left() + 1; x <= rect.right(); ++x) {
+ if (checkPixel(image.pixel(x, y), currentColor) == false) {
+ fullRun = false;
+ break;
+ }
+ }
+ if (fullRun) {
+// qDebug() << "Single-color line at horizontal line " << y << currentColor;
+ return false;
+ }
+ }
+ return true;
+ }
+
+ if (directions & Vertical) {
+ for (int x = rect.left(); x <= rect.right(); ++x) {
+ QRgb currentColor = image.pixel(x, rect.top());
+ bool fullRun = true;
+ for (int y = rect.top() + 1; y <= rect.bottom(); ++y) {
+ if (checkPixel(image.pixel(x, y), currentColor) == false) {
+ fullRun = false;
+ break;
+ }
+ }
+ if (fullRun) {
+// qDebug() << "Single-color line at vertical line" << x << currentColor;
+ return false;
+ }
+ }
+ return true;
+ }
+ return false; // shut the compiler up.
+}
+
+void DelayedAction::run()
+{
+ if (next)
+ QTimer::singleShot(next->delay, next, SLOT(run()));
+};
+
+/*
+ Schedules a mouse click at an interface using a singleShot timer.
+ Only one click can be scheduled at a time.
+*/
+ClickLaterAction::ClickLaterAction(InterfaceChildPair interface, Qt::MouseButtons buttons)
+{
+ this->useInterface = true;
+ this->interface = interface;
+ this->buttons = buttons;
+}
+
+/*
+ Schedules a mouse click at a widget using a singleShot timer.
+ Only one click can be scheduled at a time.
+*/
+ClickLaterAction::ClickLaterAction(QWidget *widget, Qt::MouseButtons buttons)
+{
+ this->useInterface = false;
+ this->widget = widget;
+ this->buttons = buttons;
+}
+
+void ClickLaterAction::run()
+{
+ if (useInterface) {
+ const QPoint globalCenter = interface.iface->rect(interface.possibleChild).center();
+ NativeEvents::mouseClick(globalCenter, buttons);
+ } else { // use widget
+ const QSize halfSize = widget->size() / 2;
+ const QPoint globalCenter = widget->mapToGlobal(QPoint(halfSize.width(), halfSize.height()));
+ NativeEvents::mouseClick(globalCenter, buttons);
+ }
+ DelayedAction::run();
+}
+
+void GuiTester::clickLater(InterfaceChildPair interface, Qt::MouseButtons buttons, int delay)
+{
+ clearSequence();
+ addToSequence(new ClickLaterAction(interface, buttons), delay);
+ runSequence();
+}
+
+void GuiTester::clickLater(QWidget *widget, Qt::MouseButtons buttons, int delay)
+{
+ clearSequence();
+ addToSequence(new ClickLaterAction(widget, buttons), delay);
+ runSequence();
+}
+
+void GuiTester::clearSequence()
+{
+ startAction = new DelayedAction();
+ actions.insert(startAction);
+ lastAction = startAction;
+}
+
+void GuiTester::addToSequence(DelayedAction *action, int delay)
+{
+ actions.insert(action);
+ action->delay = delay;
+ lastAction->next = action;
+ lastAction = action;
+}
+
+void GuiTester::runSequence()
+{
+ QTimer::singleShot(0, startAction, SLOT(run()));
+}
+
+void GuiTester::exitLoopSlot()
+{
+ QTestEventLoop::instance().exitLoop();
+}
+
diff --git a/tests/auto/macgui/guitest.h b/tests/auto/macgui/guitest.h
new file mode 100644
index 0000000000..2ebe4dceb3
--- /dev/null
+++ b/tests/auto/macgui/guitest.h
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef GUITEST_H
+#define GUITEST_H
+
+#include <QAccessibleInterface>
+#include <QSet>
+#include <QWidget>
+#include <QPainter>
+
+QT_USE_NAMESPACE
+
+/*
+ GuiTest provides tools for:
+ - navigating the Qt Widget hiearchy using the accessibilty APIs.
+ - Simulating platform mouse and keybord events.
+*/
+
+/*
+ InterfaceChildPair specifies an accessibilty interface item.
+*/
+class InterfaceChildPair {
+public:
+ InterfaceChildPair() : iface(0), possibleChild(0) {}
+ InterfaceChildPair(QAccessibleInterface *iface, int possibleChild)
+ :iface(iface), possibleChild(possibleChild)
+ { }
+
+ QAccessibleInterface *iface;
+ int possibleChild;
+};
+
+class TestBase {
+public:
+ virtual bool operator()(InterfaceChildPair candidate) = 0;
+ virtual ~TestBase() {}
+};
+
+/*
+ WidgetNavigator navigates a Qt GUI hierarchy using the QAccessibility APIs.
+*/
+class WidgetNavigator {
+public:
+ WidgetNavigator() {};
+ ~WidgetNavigator();
+
+ void printAll(QWidget *widget);
+ void printAll(InterfaceChildPair interface);
+
+ InterfaceChildPair find(QAccessible::Text textType, const QString &text, QWidget *start);
+ InterfaceChildPair find(QAccessible::Text textType, const QString &text, QAccessibleInterface *start);
+
+ InterfaceChildPair recursiveSearch(TestBase *test, QAccessibleInterface *iface, int possibleChild);
+
+ void deleteInDestructor(QAccessibleInterface * interface);
+ static QWidget *getWidget(InterfaceChildPair interface);
+private:
+ QSet<QAccessibleInterface *> interfaces;
+};
+
+/*
+ NativeEvents contains platform-specific code for simulating mouse and keybord events.
+ (Implemented so far: mouseClick on Mac)
+*/
+namespace NativeEvents {
+ enum MousePosition { UpdatePosition, DontUpdatePosition };
+ /*
+ Simulates a mouse click with button at globalPos.
+ */
+ void mouseClick(const QPoint &globalPos, Qt::MouseButtons buttons, MousePosition updateMouse = DontUpdatePosition);
+};
+
+class ColorWidget : public QWidget
+{
+public:
+ ColorWidget(QWidget *parent = 0, QColor color = QColor(Qt::red))
+ : QWidget(parent), color(color) {}
+
+ QColor color;
+
+protected:
+ void paintEvent(QPaintEvent *)
+ {
+ QPainter p(this);
+ p.fillRect(this->rect(), color);
+ }
+};
+
+class DelayedAction : public QObject
+{
+Q_OBJECT
+public:
+ DelayedAction() : delay(0), next(0) {}
+ virtual ~DelayedAction(){}
+public slots:
+ virtual void run();
+public:
+ int delay;
+ DelayedAction *next;
+};
+
+class ClickLaterAction : public DelayedAction
+{
+Q_OBJECT
+public:
+ ClickLaterAction(InterfaceChildPair interface, Qt::MouseButtons buttons = Qt::LeftButton);
+ ClickLaterAction(QWidget *widget, Qt::MouseButtons buttons = Qt::LeftButton);
+protected slots:
+ void run();
+private:
+ bool useInterface;
+ InterfaceChildPair interface;
+ QWidget *widget;
+ Qt::MouseButtons buttons;
+};
+
+/*
+
+*/
+class GuiTester : public QObject
+{
+Q_OBJECT
+public:
+ GuiTester();
+ ~GuiTester();
+ enum Direction {Horizontal = 1, Vertical = 2, HorizontalAndVertical = 3};
+ Q_DECLARE_FLAGS(Directions, Direction)
+ bool isFilled(const QImage image, const QRect &rect, const QColor &color);
+ bool isContent(const QImage image, const QRect &rect, Directions directions = HorizontalAndVertical);
+protected slots:
+ void exitLoopSlot();
+protected:
+ void clickLater(InterfaceChildPair interface, Qt::MouseButtons buttons = Qt::LeftButton, int delay = 300);
+ void clickLater(QWidget *widget, Qt::MouseButtons buttons = Qt::LeftButton, int delay = 300);
+
+ void clearSequence();
+ void addToSequence(DelayedAction *action, int delay = 0);
+ void runSequence();
+ WidgetNavigator wn;
+private:
+ QSet<DelayedAction *> actions;
+ DelayedAction *startAction;
+ DelayedAction *lastAction;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(GuiTester::Directions)
+
+#endif
diff --git a/tests/auto/macgui/macgui.pro b/tests/auto/macgui/macgui.pro
new file mode 100644
index 0000000000..0ed2350a48
--- /dev/null
+++ b/tests/auto/macgui/macgui.pro
@@ -0,0 +1,11 @@
+load(qttest_p4)
+TEMPLATE = app
+DEPENDPATH += .
+INCLUDEPATH += .
+
+# Input
+SOURCES += tst_macgui.cpp guitest.cpp
+HEADERS += guitest.h
+
+requires(mac)
+
diff --git a/tests/auto/macgui/tst_macgui.cpp b/tests/auto/macgui/tst_macgui.cpp
new file mode 100644
index 0000000000..9daf8a8034
--- /dev/null
+++ b/tests/auto/macgui/tst_macgui.cpp
@@ -0,0 +1,251 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QApplication>
+#include <QMessageBox>
+#include <QtTest/QtTest>
+#include <QSplashScreen>
+#include <QScrollBar>
+#include <QProgressDialog>
+#include <QSpinBox>
+
+#include <guitest.h>
+
+#ifdef Q_OS_MAC
+
+class tst_MacGui : public GuiTester
+{
+Q_OBJECT
+private slots:
+ void scrollbarPainting();
+
+ void dummy();
+ void splashScreenModality();
+ void nonModalOrder();
+
+ void spinBoxArrowButtons();
+};
+
+
+QPixmap grabWindowContents(QWidget * widget)
+{
+ return QPixmap::grabWindow(widget->winId());
+}
+
+/*
+ Test that vertical and horizontal mac-style scrollbars paint their
+ entire area.
+*/
+void tst_MacGui::scrollbarPainting()
+{
+ ColorWidget colorWidget;
+ colorWidget.resize(400, 400);
+
+ QSize scrollBarSize;
+
+ QScrollBar verticalScrollbar(&colorWidget);
+ verticalScrollbar.move(10, 10);
+ scrollBarSize = verticalScrollbar.sizeHint();
+ scrollBarSize.setHeight(200);
+ verticalScrollbar.resize(scrollBarSize);
+
+ QScrollBar horizontalScrollbar(&colorWidget);
+ horizontalScrollbar.move(30, 10);
+ horizontalScrollbar.setOrientation(Qt::Horizontal);
+ scrollBarSize = horizontalScrollbar.sizeHint();
+ scrollBarSize.setWidth(200);
+ horizontalScrollbar.resize(scrollBarSize);
+
+ colorWidget.show();
+ colorWidget.raise();
+ QTest::qWait(100);
+
+ QPixmap pixmap = grabWindowContents(&colorWidget);
+
+ QVERIFY(isContent(pixmap.toImage(), verticalScrollbar.geometry(), GuiTester::Horizontal));
+ QVERIFY(isContent(pixmap.toImage(), horizontalScrollbar.geometry(), GuiTester::Vertical));
+}
+
+// When running the auto-tests on scruffy, the first enter-the-event-loop-and-wait-for-a-click
+// test that runs always times out, so we have this dummy test.
+void tst_MacGui::dummy()
+{
+ QPixmap pix(100, 100);
+ QSplashScreen splash(pix);
+ splash.show();
+
+ QMessageBox *box = new QMessageBox();
+ box->setText("accessible?");
+ box->show();
+
+ // Find the "OK" button and schedule a press.
+ InterfaceChildPair interface = wn.find(QAccessible::Name, "OK", box);
+ QVERIFY(interface.iface);
+ const int delay = 1000;
+ clickLater(interface, Qt::LeftButton, delay);
+
+ // Show dialog and and enter event loop.
+ connect(wn.getWidget(interface), SIGNAL(clicked()), SLOT(exitLoopSlot()));
+ const int timeout = 4;
+ QTestEventLoop::instance().enterLoop(timeout);
+}
+
+/*
+ Test that a message box pops up in front of a QSplashScreen.
+*/
+void tst_MacGui::splashScreenModality()
+{
+ QPixmap pix(300, 300);
+ QSplashScreen splash(pix);
+ splash.show();
+
+ QMessageBox box;
+ //box.setWindowFlags(box.windowFlags() | Qt::WindowStaysOnTopHint);
+ box.setText("accessible?");
+ box.show();
+
+ // Find the "OK" button and schedule a press.
+ InterfaceChildPair interface = wn.find(QAccessible::Name, "OK", &box);
+ QVERIFY(interface.iface);
+ const int delay = 1000;
+ clickLater(interface, Qt::LeftButton, delay);
+
+ // Show dialog and and enter event loop.
+ connect(wn.getWidget(interface), SIGNAL(clicked()), SLOT(exitLoopSlot()));
+ const int timeout = 4;
+ QTestEventLoop::instance().enterLoop(timeout);
+ QVERIFY(QTestEventLoop::instance().timeout() == false);
+}
+
+class PrimaryWindowDialog : public QDialog
+{
+Q_OBJECT
+public:
+ PrimaryWindowDialog();
+ QWidget *secondaryWindow;
+ QWidget *frontWidget;
+public slots:
+ void showSecondaryWindow();
+ void test();
+};
+
+PrimaryWindowDialog::PrimaryWindowDialog() : QDialog(0)
+{
+ frontWidget = 0;
+ secondaryWindow = new ColorWidget(this);
+ secondaryWindow->setWindowFlags(Qt::Window);
+ secondaryWindow->resize(400, 400);
+ secondaryWindow->move(100, 100);
+ QTimer::singleShot(1000, this, SLOT(showSecondaryWindow()));
+ QTimer::singleShot(2000, this, SLOT(test()));
+ QTimer::singleShot(3000, this, SLOT(close()));
+}
+
+void PrimaryWindowDialog::showSecondaryWindow()
+{
+ secondaryWindow->show();
+}
+
+void PrimaryWindowDialog::test()
+{
+ frontWidget = QApplication::widgetAt(secondaryWindow->mapToGlobal(QPoint(100, 100)));
+}
+
+/*
+ Test that a non-modal child window of a modal dialog is shown in front
+ of the dialog even if the dialog becomes modal after the child window
+ is created.
+*/
+void tst_MacGui::nonModalOrder()
+{
+ clearSequence();
+ PrimaryWindowDialog primary;
+ primary.resize(400, 400);
+ primary.move(100, 100);
+ primary.exec();
+ QCOMPARE(primary.frontWidget, primary.secondaryWindow);
+}
+
+/*
+ Test that the QSpinBox buttons are correctly positioned with the Mac style.
+*/
+void tst_MacGui::spinBoxArrowButtons()
+{
+ ColorWidget colorWidget;
+ colorWidget.resize(200, 200);
+ QSpinBox spinBox(&colorWidget);
+ QSpinBox spinBox2(&colorWidget);
+ spinBox2.move(0, 100);
+ colorWidget.show();
+ QTest::qWait(100);
+
+ // Grab an unfocused spin box.
+ const QImage noFocus = grabWindowContents(&colorWidget).toImage();
+
+ // Set focus by clicking the less button.
+ InterfaceChildPair lessInterface = wn.find(QAccessible::Name, "Less", &spinBox);
+ QVERIFY(lessInterface.iface);
+ const int delay = 500;
+ clickLater(lessInterface, Qt::LeftButton, delay);
+ const int timeout = 1;
+ QTestEventLoop::instance().enterLoop(timeout);
+
+ // Grab a focused spin box.
+ const QImage focus = grabWindowContents(&colorWidget).toImage();
+
+ // Compare the arrow area of the less button to see if it moved.
+ const QRect lessRect = lessInterface.iface->rect(lessInterface.possibleChild);
+ const QRect lessLocalRect(colorWidget.mapFromGlobal(lessRect.topLeft()), colorWidget.mapFromGlobal(lessRect.bottomRight()));
+ const QRect compareRect = lessLocalRect.adjusted(5, 3, -5, -7);
+ QVERIFY(noFocus.copy(compareRect) == focus.copy(compareRect));
+}
+
+QTEST_MAIN(tst_MacGui)
+
+#else
+
+QTEST_NOOP_MAIN
+
+#endif
+
+#include "tst_macgui.moc"
+