2011-08-29 06:26:37 +00:00
|
|
|
/****************************************************************************
|
|
|
|
**
|
2016-01-15 12:36:27 +00:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2011-08-29 06:26:37 +00:00
|
|
|
**
|
|
|
|
** This file is part of the test suite of the Qt Toolkit.
|
|
|
|
**
|
2016-01-15 12:36:27 +00:00
|
|
|
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
2012-09-19 12:28:29 +00:00
|
|
|
** 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
|
2015-01-28 08:44:43 +00:00
|
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
2016-01-15 12:36:27 +00:00
|
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
2012-09-19 12:28:29 +00:00
|
|
|
**
|
2016-01-15 12:36:27 +00:00
|
|
|
** 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.
|
2011-08-29 06:26:37 +00:00
|
|
|
**
|
|
|
|
** $QT_END_LICENSE$
|
|
|
|
**
|
|
|
|
****************************************************************************/
|
|
|
|
|
2014-08-28 10:59:14 +00:00
|
|
|
#include <qrasterwindow.h>
|
2012-07-26 11:23:28 +00:00
|
|
|
#include <qpa/qwindowsysteminterface.h>
|
2013-03-11 13:41:52 +00:00
|
|
|
#include <qpa/qplatformintegration.h>
|
|
|
|
#include <private/qguiapplication_p.h>
|
2015-06-18 15:01:01 +00:00
|
|
|
#include <private/qhighdpiscaling_p.h>
|
2014-08-28 10:59:14 +00:00
|
|
|
#include <QtGui/QPainter>
|
2011-09-22 12:37:58 +00:00
|
|
|
|
|
|
|
#include <QtTest/QtTest>
|
|
|
|
|
2011-12-12 15:24:33 +00:00
|
|
|
#include <QEvent>
|
2012-03-24 08:48:12 +00:00
|
|
|
#include <QStyleHints>
|
2011-12-12 15:24:33 +00:00
|
|
|
|
2014-03-18 16:18:04 +00:00
|
|
|
#if defined(Q_OS_QNX)
|
|
|
|
#include <QOpenGLContext>
|
2014-08-28 10:59:14 +00:00
|
|
|
#elif defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
|
|
|
|
# include <QtCore/qt_windows.h>
|
2014-03-18 16:18:04 +00:00
|
|
|
#endif
|
|
|
|
|
2012-02-16 11:50:22 +00:00
|
|
|
// For QSignalSpy slot connections.
|
|
|
|
Q_DECLARE_METATYPE(Qt::ScreenOrientation)
|
2013-02-08 09:49:52 +00:00
|
|
|
Q_DECLARE_METATYPE(QWindow::Visibility)
|
2012-02-16 11:50:22 +00:00
|
|
|
|
2011-08-29 06:26:37 +00:00
|
|
|
class tst_QWindow: public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
private slots:
|
2015-10-16 13:04:49 +00:00
|
|
|
void create();
|
2015-10-16 13:28:31 +00:00
|
|
|
void setParent();
|
2015-10-16 14:41:34 +00:00
|
|
|
void setVisible();
|
2012-03-14 16:55:43 +00:00
|
|
|
void eventOrderOnShow();
|
2013-07-26 15:51:42 +00:00
|
|
|
void resizeEventAfterResize();
|
2011-08-29 06:26:37 +00:00
|
|
|
void mapGlobal();
|
2014-01-03 13:11:27 +00:00
|
|
|
void positioning_data();
|
2011-09-22 12:37:58 +00:00
|
|
|
void positioning();
|
2014-06-19 11:45:06 +00:00
|
|
|
void positioningDuringMinimized();
|
2015-10-16 15:36:20 +00:00
|
|
|
void childWindowPositioning_data();
|
|
|
|
void childWindowPositioning();
|
2014-11-15 11:40:51 +00:00
|
|
|
void platformSurface();
|
2012-03-14 16:55:43 +00:00
|
|
|
void isExposed();
|
2011-09-29 16:02:54 +00:00
|
|
|
void isActive();
|
2011-12-12 15:24:33 +00:00
|
|
|
void testInputEvents();
|
2012-01-12 07:53:13 +00:00
|
|
|
void touchToMouseTranslation();
|
2014-12-09 15:52:24 +00:00
|
|
|
void touchToMouseTranslationForDevices();
|
2012-01-12 07:53:13 +00:00
|
|
|
void mouseToTouchTranslation();
|
|
|
|
void mouseToTouchLoop();
|
2012-02-09 12:39:40 +00:00
|
|
|
void touchCancel();
|
|
|
|
void touchCancelWithTouchToMouse();
|
2014-03-11 21:10:05 +00:00
|
|
|
void touchInterruptedByPopup();
|
2012-01-13 09:31:11 +00:00
|
|
|
void orientation();
|
2012-11-01 16:03:45 +00:00
|
|
|
void sizes();
|
2012-01-20 12:08:42 +00:00
|
|
|
void close();
|
2012-02-24 17:05:06 +00:00
|
|
|
void activateAndClose();
|
2012-03-24 08:48:12 +00:00
|
|
|
void mouseEventSequence();
|
2012-04-04 10:11:40 +00:00
|
|
|
void windowModality();
|
2012-04-23 13:18:01 +00:00
|
|
|
void inputReentrancy();
|
2012-05-23 12:07:39 +00:00
|
|
|
void tabletEvents();
|
2012-09-21 10:12:01 +00:00
|
|
|
void windowModality_QTBUG27039();
|
2013-02-08 09:49:52 +00:00
|
|
|
void visibility();
|
2013-02-25 07:54:30 +00:00
|
|
|
void mask();
|
2014-01-09 11:45:14 +00:00
|
|
|
void initialSize();
|
2014-04-03 11:11:59 +00:00
|
|
|
void modalDialog();
|
|
|
|
void modalDialogClosingOneOfTwoModal();
|
|
|
|
void modalWithChildWindow();
|
|
|
|
void modalWindowModallity();
|
2014-05-19 17:58:35 +00:00
|
|
|
void modalWindowPosition();
|
2016-01-19 21:32:52 +00:00
|
|
|
#ifndef QT_NO_CURSOR
|
|
|
|
void modalWindowEnterEventOnHide_QTBUG35109();
|
|
|
|
#endif
|
2014-08-28 10:59:14 +00:00
|
|
|
void windowsTransientChildren();
|
2015-02-12 14:28:12 +00:00
|
|
|
void requestUpdate();
|
2014-07-31 11:48:15 +00:00
|
|
|
void initTestCase();
|
2015-12-09 17:06:20 +00:00
|
|
|
void stateChange_data();
|
|
|
|
void stateChange();
|
2014-07-24 13:11:27 +00:00
|
|
|
void cleanup();
|
2012-01-12 07:53:13 +00:00
|
|
|
|
|
|
|
private:
|
2014-07-31 11:48:15 +00:00
|
|
|
QPoint m_availableTopLeft;
|
|
|
|
QSize m_testWindowSize;
|
2012-01-12 07:53:13 +00:00
|
|
|
QTouchDevice *touchDevice;
|
2011-08-29 06:26:37 +00:00
|
|
|
};
|
|
|
|
|
2014-07-31 11:48:15 +00:00
|
|
|
void tst_QWindow::initTestCase()
|
|
|
|
{
|
|
|
|
// Size of reference window, 200 for < 2000, scale up for larger screens
|
|
|
|
// to avoid Windows warnings about minimum size for decorated windows.
|
|
|
|
int width = 200;
|
|
|
|
const QScreen *screen = QGuiApplication::primaryScreen();
|
|
|
|
m_availableTopLeft = screen->availableGeometry().topLeft();
|
|
|
|
const int screenWidth = screen->geometry().width();
|
|
|
|
if (screenWidth > 2000)
|
|
|
|
width = 100 * ((screenWidth + 500) / 1000);
|
|
|
|
m_testWindowSize = QSize(width, width);
|
|
|
|
touchDevice = new QTouchDevice;
|
|
|
|
touchDevice->setType(QTouchDevice::TouchScreen);
|
|
|
|
QWindowSystemInterface::registerTouchDevice(touchDevice);
|
|
|
|
}
|
|
|
|
|
2014-07-24 13:11:27 +00:00
|
|
|
void tst_QWindow::cleanup()
|
|
|
|
{
|
|
|
|
QVERIFY(QGuiApplication::allWindows().isEmpty());
|
|
|
|
}
|
|
|
|
|
2015-10-16 13:04:49 +00:00
|
|
|
void tst_QWindow::create()
|
|
|
|
{
|
|
|
|
QWindow a;
|
|
|
|
QVERIFY2(!a.handle(), "QWindow should lazy init the platform window");
|
|
|
|
|
|
|
|
a.create();
|
|
|
|
QVERIFY2(a.handle(), "Explicitly creating a platform window should never fail");
|
|
|
|
|
|
|
|
QWindow b;
|
|
|
|
QWindow c(&b);
|
|
|
|
b.create();
|
|
|
|
QVERIFY(b.handle());
|
|
|
|
QVERIFY2(!c.handle(), "Creating a parent window should not automatically create children");
|
|
|
|
|
|
|
|
QWindow d;
|
|
|
|
QWindow e(&d);
|
|
|
|
e.create();
|
|
|
|
QVERIFY(e.handle());
|
|
|
|
QVERIFY2(d.handle(), "Creating a child window should automatically create parents");
|
|
|
|
|
|
|
|
QWindow f;
|
|
|
|
QWindow g(&f);
|
|
|
|
f.create();
|
|
|
|
QVERIFY(f.handle());
|
|
|
|
QPlatformWindow *platformWindow = f.handle();
|
|
|
|
g.create();
|
|
|
|
QVERIFY(g.handle());
|
|
|
|
QVERIFY2(f.handle() == platformWindow, "Creating a child window should not affect parent if already created");
|
|
|
|
}
|
|
|
|
|
2015-10-16 13:28:31 +00:00
|
|
|
void tst_QWindow::setParent()
|
|
|
|
{
|
|
|
|
QWindow a;
|
|
|
|
QWindow b(&a);
|
|
|
|
QVERIFY2(b.parent() == &a, "Setting parent at construction time should work");
|
|
|
|
QVERIFY2(a.children().contains(&b), "Parent should have child in list of children");
|
|
|
|
|
|
|
|
QWindow c;
|
|
|
|
QWindow d;
|
|
|
|
d.setParent(&c);
|
|
|
|
QVERIFY2(d.parent() == &c, "Setting parent after construction should work");
|
|
|
|
QVERIFY2(c.children().contains(&d), "Parent should have child in list of children");
|
|
|
|
|
|
|
|
a.create();
|
|
|
|
b.setParent(0);
|
|
|
|
QVERIFY2(!b.handle(), "Making window top level shouild not automatically create it");
|
|
|
|
|
|
|
|
QWindow e;
|
|
|
|
c.create();
|
|
|
|
e.setParent(&c);
|
|
|
|
QVERIFY2(!e.handle(), "Making window a child of a created window should not automatically create it");
|
|
|
|
|
|
|
|
QWindow f;
|
|
|
|
QWindow g;
|
|
|
|
g.create();
|
|
|
|
QVERIFY(g.handle());
|
|
|
|
g.setParent(&f);
|
|
|
|
QVERIFY2(f.handle(), "Making a created window a child of a non-created window should automatically create it");
|
|
|
|
}
|
|
|
|
|
2015-10-16 14:41:34 +00:00
|
|
|
void tst_QWindow::setVisible()
|
|
|
|
{
|
|
|
|
QWindow a;
|
|
|
|
QWindow b(&a);
|
|
|
|
a.setVisible(true);
|
|
|
|
QVERIFY2(!b.handle(), "Making a top level window visible doesn't create its children");
|
|
|
|
QVERIFY2(!b.isVisible(), "Making a top level window visible doesn't make its children visible");
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&a));
|
|
|
|
|
|
|
|
QWindow c;
|
|
|
|
QWindow d(&c);
|
|
|
|
d.setVisible(true);
|
|
|
|
QVERIFY2(!c.handle(), "Making a child window visible doesn't create parent window if parent is hidden");
|
|
|
|
QVERIFY2(!c.isVisible(), "Making a child window visible doesn't make its parent visible");
|
|
|
|
|
|
|
|
QVERIFY2(!d.handle(), "Making a child window visible doesn't create platform window if parent is hidden");
|
|
|
|
|
|
|
|
c.create();
|
|
|
|
QVERIFY(c.handle());
|
|
|
|
QVERIFY2(d.handle(), "Creating a parent window should automatically create children if they are visible");
|
|
|
|
QVERIFY2(!c.isVisible(), "Creating a parent window should not make it visible just because it has visible children");
|
|
|
|
|
|
|
|
QWindow e;
|
|
|
|
QWindow f(&e);
|
|
|
|
f.setVisible(true);
|
|
|
|
QVERIFY(!f.handle());
|
|
|
|
QVERIFY(!e.handle());
|
|
|
|
f.setParent(0);
|
|
|
|
QVERIFY2(f.handle(), "Making a visible but not created child window top level should create it");
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&f));
|
|
|
|
|
|
|
|
QWindow g;
|
|
|
|
QWindow h;
|
|
|
|
QWindow i(&g);
|
|
|
|
i.setVisible(true);
|
|
|
|
h.setVisible(true);
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&h));
|
|
|
|
QVERIFY(!i.handle());
|
|
|
|
QVERIFY(!g.handle());
|
|
|
|
QVERIFY(h.handle());
|
|
|
|
i.setParent(&h);
|
|
|
|
QVERIFY2(i.handle(), "Making a visible but not created child window child of a created window should create it");
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&i));
|
|
|
|
}
|
|
|
|
|
2011-08-29 06:26:37 +00:00
|
|
|
void tst_QWindow::mapGlobal()
|
|
|
|
{
|
|
|
|
QWindow a;
|
|
|
|
QWindow b(&a);
|
|
|
|
QWindow c(&b);
|
|
|
|
|
|
|
|
a.setGeometry(10, 10, 300, 300);
|
|
|
|
b.setGeometry(20, 20, 200, 200);
|
|
|
|
c.setGeometry(40, 40, 100, 100);
|
|
|
|
|
|
|
|
QCOMPARE(a.mapToGlobal(QPoint(100, 100)), QPoint(110, 110));
|
|
|
|
QCOMPARE(b.mapToGlobal(QPoint(100, 100)), QPoint(130, 130));
|
|
|
|
QCOMPARE(c.mapToGlobal(QPoint(100, 100)), QPoint(170, 170));
|
|
|
|
|
|
|
|
QCOMPARE(a.mapFromGlobal(QPoint(100, 100)), QPoint(90, 90));
|
|
|
|
QCOMPARE(b.mapFromGlobal(QPoint(100, 100)), QPoint(70, 70));
|
|
|
|
QCOMPARE(c.mapFromGlobal(QPoint(100, 100)), QPoint(30, 30));
|
|
|
|
}
|
|
|
|
|
2011-09-22 12:37:58 +00:00
|
|
|
class Window : public QWindow
|
|
|
|
{
|
|
|
|
public:
|
2014-01-03 13:11:27 +00:00
|
|
|
Window(const Qt::WindowFlags flags = Qt::Window | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint)
|
2011-09-22 12:37:58 +00:00
|
|
|
{
|
2011-09-29 16:02:54 +00:00
|
|
|
reset();
|
2014-01-03 13:11:27 +00:00
|
|
|
setFlags(flags);
|
2014-03-18 16:18:04 +00:00
|
|
|
#if defined(Q_OS_QNX)
|
|
|
|
setSurfaceType(QSurface::OpenGLSurface);
|
|
|
|
#endif
|
2011-09-22 12:37:58 +00:00
|
|
|
}
|
|
|
|
|
2011-09-29 16:02:54 +00:00
|
|
|
void reset()
|
|
|
|
{
|
|
|
|
m_received.clear();
|
2014-12-17 12:47:19 +00:00
|
|
|
m_framePositionsOnMove.clear();
|
2011-09-29 16:02:54 +00:00
|
|
|
}
|
|
|
|
|
2011-09-22 12:37:58 +00:00
|
|
|
bool event(QEvent *event)
|
|
|
|
{
|
2011-09-29 16:02:54 +00:00
|
|
|
m_received[event->type()]++;
|
2012-03-14 16:55:43 +00:00
|
|
|
m_order << event->type();
|
2014-11-15 11:40:51 +00:00
|
|
|
switch (event->type()) {
|
|
|
|
case QEvent::Expose:
|
2014-07-28 13:55:56 +00:00
|
|
|
m_exposeRegion = static_cast<QExposeEvent *>(event)->region();
|
2014-11-15 11:40:51 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case QEvent::PlatformSurface:
|
|
|
|
m_surfaceventType = static_cast<QPlatformSurfaceEvent *>(event)->surfaceEventType();
|
|
|
|
break;
|
|
|
|
|
2014-12-18 11:12:58 +00:00
|
|
|
case QEvent::Move:
|
2014-12-17 12:47:19 +00:00
|
|
|
m_framePositionsOnMove << framePosition();
|
2014-12-18 11:12:58 +00:00
|
|
|
break;
|
2014-11-15 11:40:51 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2011-09-22 12:37:58 +00:00
|
|
|
|
|
|
|
return QWindow::event(event);
|
|
|
|
}
|
|
|
|
|
2011-09-29 16:02:54 +00:00
|
|
|
int received(QEvent::Type type)
|
|
|
|
{
|
|
|
|
return m_received.value(type, 0);
|
|
|
|
}
|
|
|
|
|
2012-03-14 16:55:43 +00:00
|
|
|
int eventIndex(QEvent::Type type)
|
|
|
|
{
|
|
|
|
return m_order.indexOf(type);
|
|
|
|
}
|
|
|
|
|
2014-07-28 13:55:56 +00:00
|
|
|
QRegion exposeRegion() const
|
|
|
|
{
|
|
|
|
return m_exposeRegion;
|
|
|
|
}
|
|
|
|
|
2014-11-15 11:40:51 +00:00
|
|
|
QPlatformSurfaceEvent::SurfaceEventType surfaceEventType() const
|
|
|
|
{
|
|
|
|
return m_surfaceventType;
|
|
|
|
}
|
|
|
|
|
2014-12-17 12:47:19 +00:00
|
|
|
QVector<QPoint> m_framePositionsOnMove;
|
2011-09-29 16:02:54 +00:00
|
|
|
private:
|
|
|
|
QHash<QEvent::Type, int> m_received;
|
2012-03-14 16:55:43 +00:00
|
|
|
QVector<QEvent::Type> m_order;
|
2014-07-28 13:55:56 +00:00
|
|
|
QRegion m_exposeRegion;
|
2014-11-15 11:40:51 +00:00
|
|
|
QPlatformSurfaceEvent::SurfaceEventType m_surfaceventType;
|
2011-09-22 12:37:58 +00:00
|
|
|
};
|
|
|
|
|
2015-10-16 15:36:20 +00:00
|
|
|
class ColoredWindow : public QRasterWindow {
|
|
|
|
public:
|
|
|
|
explicit ColoredWindow(const QColor &color, QWindow *parent = 0) : QRasterWindow(parent), m_color(color) {}
|
|
|
|
void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE
|
|
|
|
{
|
|
|
|
QPainter p(this);
|
|
|
|
p.fillRect(QRect(QPoint(0, 0), size()), m_color);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
const QColor m_color;
|
|
|
|
};
|
|
|
|
|
2012-03-14 16:55:43 +00:00
|
|
|
void tst_QWindow::eventOrderOnShow()
|
|
|
|
{
|
2012-04-27 13:45:24 +00:00
|
|
|
// Some platforms enforce minimum widths for windows, which can cause extra resize
|
|
|
|
// events, so set the width to suitably large value to avoid those.
|
2014-07-31 11:48:15 +00:00
|
|
|
QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize);
|
2012-03-14 16:55:43 +00:00
|
|
|
|
|
|
|
Window window;
|
|
|
|
window.setGeometry(geometry);
|
|
|
|
window.show();
|
2012-04-27 13:45:24 +00:00
|
|
|
QCoreApplication::processEvents();
|
2012-03-14 16:55:43 +00:00
|
|
|
|
|
|
|
QTRY_COMPARE(window.received(QEvent::Show), 1);
|
|
|
|
QTRY_COMPARE(window.received(QEvent::Resize), 1);
|
|
|
|
QTRY_VERIFY(window.isExposed());
|
|
|
|
|
|
|
|
QVERIFY(window.eventIndex(QEvent::Show) < window.eventIndex(QEvent::Resize));
|
|
|
|
QVERIFY(window.eventIndex(QEvent::Resize) < window.eventIndex(QEvent::Expose));
|
|
|
|
}
|
|
|
|
|
2013-07-26 15:51:42 +00:00
|
|
|
void tst_QWindow::resizeEventAfterResize()
|
|
|
|
{
|
|
|
|
// Some platforms enforce minimum widths for windows, which can cause extra resize
|
|
|
|
// events, so set the width to suitably large value to avoid those.
|
2014-07-31 11:48:15 +00:00
|
|
|
QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize * 2);
|
2013-07-26 15:51:42 +00:00
|
|
|
|
|
|
|
Window window;
|
|
|
|
window.setGeometry(geometry);
|
2013-11-15 16:55:25 +00:00
|
|
|
window.showNormal();
|
2013-07-26 15:51:42 +00:00
|
|
|
|
|
|
|
QTRY_COMPARE(window.received(QEvent::Resize), 1);
|
|
|
|
|
|
|
|
// QTBUG-32706
|
|
|
|
// Make sure we get a resizeEvent after calling resize
|
2014-07-31 11:48:15 +00:00
|
|
|
window.resize(m_testWindowSize);
|
2013-07-26 15:51:42 +00:00
|
|
|
|
|
|
|
QTRY_COMPARE(window.received(QEvent::Resize), 2);
|
|
|
|
}
|
|
|
|
|
2014-01-03 13:11:27 +00:00
|
|
|
void tst_QWindow::positioning_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<int>("windowflags");
|
|
|
|
|
2014-12-03 11:09:50 +00:00
|
|
|
QTest::newRow("default") << int(Qt::Window | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | Qt::WindowFullscreenButtonHint);
|
2014-01-03 13:11:27 +00:00
|
|
|
|
|
|
|
#ifdef Q_OS_OSX
|
2014-12-03 11:09:50 +00:00
|
|
|
QTest::newRow("fake") << int(Qt::Window | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
|
2014-01-03 13:11:27 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-06-18 15:01:01 +00:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2015-12-09 17:06:20 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2015-06-18 15:01:01 +00:00
|
|
|
static QString msgPointMismatch(const QPoint &p1, const QPoint p2)
|
|
|
|
{
|
|
|
|
QString result;
|
|
|
|
QDebug(&result) << p1 << "!=" << p2 << ", manhattanLength=" << (p1 - p2).manhattanLength();
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2015-12-09 17:06:20 +00:00
|
|
|
static QString msgRectMismatch(const QRect &r1, const QRect &r2)
|
|
|
|
{
|
|
|
|
QString result;
|
|
|
|
QDebug(&result) << r1 << "!=" << r2;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2011-09-22 12:37:58 +00:00
|
|
|
void tst_QWindow::positioning()
|
|
|
|
{
|
2013-05-31 18:27:50 +00:00
|
|
|
if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(
|
|
|
|
QPlatformIntegration::NonFullScreenWindows)) {
|
|
|
|
QSKIP("This platform does not support non-fullscreen windows");
|
|
|
|
}
|
|
|
|
|
2015-09-24 07:25:25 +00:00
|
|
|
if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
|
2014-08-21 11:23:25 +00:00
|
|
|
QSKIP("Wayland: This fails. Figure out why.");
|
|
|
|
|
2012-04-27 13:45:24 +00:00
|
|
|
// Some platforms enforce minimum widths for windows, which can cause extra resize
|
|
|
|
// events, so set the width to suitably large value to avoid those.
|
2014-07-31 11:48:15 +00:00
|
|
|
const QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize);
|
2011-09-22 12:37:58 +00:00
|
|
|
|
2014-01-03 13:11:27 +00:00
|
|
|
QFETCH(int, windowflags);
|
|
|
|
Window window((Qt::WindowFlags)windowflags);
|
2014-07-31 11:48:15 +00:00
|
|
|
window.setGeometry(QRect(m_availableTopLeft + QPoint(20, 20), m_testWindowSize));
|
|
|
|
window.setFramePosition(m_availableTopLeft + QPoint(40, 40)); // Move window around before show, size must not change.
|
|
|
|
QCOMPARE(window.geometry().size(), m_testWindowSize);
|
2011-09-22 12:37:58 +00:00
|
|
|
window.setGeometry(geometry);
|
|
|
|
QCOMPARE(window.geometry(), geometry);
|
2013-05-31 18:27:50 +00:00
|
|
|
// explicitly use non-fullscreen show. show() can be fullscreen on some platforms
|
|
|
|
window.showNormal();
|
2012-04-27 13:45:24 +00:00
|
|
|
QCoreApplication::processEvents();
|
2011-09-22 12:37:58 +00:00
|
|
|
|
2014-12-03 11:09:50 +00:00
|
|
|
QTest::qWaitForWindowExposed(&window);
|
2011-09-22 12:37:58 +00:00
|
|
|
|
|
|
|
QMargins originalMargins = window.frameMargins();
|
|
|
|
|
2012-11-27 13:57:19 +00:00
|
|
|
QCOMPARE(window.position(), window.framePosition() + QPoint(originalMargins.left(), originalMargins.top()));
|
2011-09-22 12:37:58 +00:00
|
|
|
QVERIFY(window.frameGeometry().contains(window.geometry()));
|
|
|
|
|
2012-10-22 15:06:23 +00:00
|
|
|
QPoint originalPos = window.position();
|
2012-11-27 13:57:19 +00:00
|
|
|
QPoint originalFramePos = window.framePosition();
|
2011-09-22 12:37:58 +00:00
|
|
|
|
2014-12-03 11:09:50 +00:00
|
|
|
window.reset();
|
2011-09-22 12:37:58 +00:00
|
|
|
window.setWindowState(Qt::WindowFullScreen);
|
2012-04-27 13:45:24 +00:00
|
|
|
QCoreApplication::processEvents();
|
2011-09-22 12:37:58 +00:00
|
|
|
|
2015-10-15 13:24:54 +00:00
|
|
|
QTRY_VERIFY(window.received(QEvent::Resize) > 0);
|
2014-01-03 13:11:27 +00:00
|
|
|
QTest::qWait(2000);
|
|
|
|
|
2014-12-03 11:09:50 +00:00
|
|
|
window.reset();
|
2011-09-22 12:37:58 +00:00
|
|
|
window.setWindowState(Qt::WindowNoState);
|
2012-04-27 13:45:24 +00:00
|
|
|
QCoreApplication::processEvents();
|
2011-09-22 12:37:58 +00:00
|
|
|
|
2015-10-15 13:24:54 +00:00
|
|
|
QTRY_VERIFY(window.received(QEvent::Resize) > 0);
|
2014-12-18 14:44:38 +00:00
|
|
|
QTest::qWait(2000);
|
|
|
|
|
2012-10-22 15:06:23 +00:00
|
|
|
QTRY_COMPARE(originalPos, window.position());
|
2012-11-27 13:57:19 +00:00
|
|
|
QTRY_COMPARE(originalFramePos, window.framePosition());
|
2011-09-22 12:37:58 +00:00
|
|
|
QTRY_COMPARE(originalMargins, window.frameMargins());
|
|
|
|
|
|
|
|
// 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)) {
|
2015-06-18 15:01:01 +00:00
|
|
|
const QScreen *screen = window.screen();
|
|
|
|
const QRect availableGeometry = screen->availableGeometry();
|
|
|
|
const QPoint framePos = availableGeometry.center();
|
2011-09-22 12:37:58 +00:00
|
|
|
|
2011-09-29 16:02:54 +00:00
|
|
|
window.reset();
|
2014-12-17 12:47:19 +00:00
|
|
|
const QPoint oldFramePos = window.framePosition();
|
2012-11-27 13:57:19 +00:00
|
|
|
window.setFramePosition(framePos);
|
2011-09-22 12:37:58 +00:00
|
|
|
|
2011-09-29 16:02:54 +00:00
|
|
|
QTRY_VERIFY(window.received(QEvent::Move));
|
2015-06-18 15:01:01 +00:00
|
|
|
const int fuzz = int(QHighDpiScaling::factor(&window));
|
|
|
|
if (!qFuzzyCompareWindowPosition(window.framePosition(), framePos, fuzz)) {
|
2014-12-17 12:47:19 +00:00
|
|
|
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;
|
|
|
|
}
|
2015-06-18 15:01:01 +00:00
|
|
|
QTRY_VERIFY2(qFuzzyCompareWindowPosition(window.framePosition(), framePos, fuzz),
|
|
|
|
qPrintable(msgPointMismatch(window.framePosition(), framePos)));
|
2011-09-22 12:37:58 +00:00
|
|
|
QTRY_COMPARE(originalMargins, window.frameMargins());
|
2012-11-27 13:57:19 +00:00
|
|
|
QCOMPARE(window.position(), window.framePosition() + QPoint(originalMargins.left(), originalMargins.top()));
|
2011-09-22 12:37:58 +00:00
|
|
|
|
|
|
|
// and back to regular positioning
|
|
|
|
|
2011-09-29 16:02:54 +00:00
|
|
|
window.reset();
|
2012-10-22 15:06:23 +00:00
|
|
|
window.setPosition(originalPos);
|
2011-09-29 16:02:54 +00:00
|
|
|
QTRY_VERIFY(window.received(QEvent::Move));
|
2012-10-22 15:06:23 +00:00
|
|
|
QTRY_COMPARE(originalPos, window.position());
|
2011-09-22 12:37:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-19 11:45:06 +00:00
|
|
|
void tst_QWindow::positioningDuringMinimized()
|
|
|
|
{
|
|
|
|
// QTBUG-39544, setting a geometry in minimized state should work as well.
|
2015-07-07 11:40:42 +00:00
|
|
|
if (QGuiApplication::platformName().compare("windows", Qt::CaseInsensitive) != 0
|
|
|
|
&& QGuiApplication::platformName().compare("cocoa", Qt::CaseInsensitive) != 0)
|
2014-06-19 11:45:06 +00:00
|
|
|
QSKIP("Not supported on this platform");
|
|
|
|
Window window;
|
|
|
|
window.setTitle(QStringLiteral("positioningDuringMinimized"));
|
2014-07-31 11:48:15 +00:00
|
|
|
const QRect initialGeometry(m_availableTopLeft + QPoint(100, 100), m_testWindowSize);
|
2014-06-19 11:45:06 +00:00
|
|
|
window.setGeometry(initialGeometry);
|
|
|
|
window.showNormal();
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&window));
|
|
|
|
QCOMPARE(window.geometry(), initialGeometry);
|
|
|
|
window.setWindowState(Qt::WindowMinimized);
|
|
|
|
QCOMPARE(window.geometry(), initialGeometry);
|
|
|
|
const QRect newGeometry(initialGeometry.topLeft() + QPoint(50, 50), initialGeometry.size() + QSize(50, 50));
|
|
|
|
window.setGeometry(newGeometry);
|
|
|
|
QTRY_COMPARE(window.geometry(), newGeometry);
|
|
|
|
window.setWindowState(Qt::WindowNoState);
|
|
|
|
QTRY_COMPARE(window.geometry(), newGeometry);
|
|
|
|
}
|
|
|
|
|
2015-10-16 15:36:20 +00:00
|
|
|
void tst_QWindow::childWindowPositioning_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<bool>("showInsteadOfCreate");
|
|
|
|
|
|
|
|
QTest::newRow("create") << false;
|
|
|
|
QTest::newRow("show") << true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QWindow::childWindowPositioning()
|
|
|
|
{
|
|
|
|
const QPoint topLeftOrigin(0, 0);
|
|
|
|
|
|
|
|
ColoredWindow topLevelWindowFirst(Qt::green);
|
|
|
|
topLevelWindowFirst.setObjectName("topLevelWindowFirst");
|
|
|
|
ColoredWindow childWindowAfter(Qt::yellow, &topLevelWindowFirst);
|
|
|
|
childWindowAfter.setObjectName("childWindowAfter");
|
|
|
|
|
|
|
|
topLevelWindowFirst.setFramePosition(m_availableTopLeft);
|
|
|
|
childWindowAfter.setFramePosition(topLeftOrigin);
|
|
|
|
|
|
|
|
ColoredWindow topLevelWindowAfter(Qt::green);
|
|
|
|
topLevelWindowAfter.setObjectName("topLevelWindowAfter");
|
|
|
|
ColoredWindow childWindowFirst(Qt::yellow, &topLevelWindowAfter);
|
|
|
|
childWindowFirst.setObjectName("childWindowFirst");
|
|
|
|
|
|
|
|
topLevelWindowAfter.setFramePosition(m_availableTopLeft);
|
|
|
|
childWindowFirst.setFramePosition(topLeftOrigin);
|
|
|
|
|
|
|
|
QFETCH(bool, showInsteadOfCreate);
|
|
|
|
|
|
|
|
QWindow* windows[] = { &topLevelWindowFirst, &childWindowAfter, &childWindowFirst, &topLevelWindowAfter, 0 };
|
|
|
|
for (int i = 0; windows[i]; ++i) {
|
|
|
|
QWindow *window = windows[i];
|
|
|
|
if (showInsteadOfCreate) {
|
|
|
|
window->showNormal();
|
|
|
|
} else {
|
|
|
|
window->create();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (showInsteadOfCreate) {
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&topLevelWindowFirst));
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&topLevelWindowAfter));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Creation order shouldn't affect the geometry
|
2015-11-11 14:24:37 +00:00
|
|
|
// Use try compare since on X11 the window manager may still re-position the window after expose
|
|
|
|
QTRY_COMPARE(topLevelWindowFirst.geometry(), topLevelWindowAfter.geometry());
|
|
|
|
QTRY_COMPARE(childWindowAfter.geometry(), childWindowFirst.geometry());
|
2015-10-16 15:36:20 +00:00
|
|
|
|
|
|
|
// Creation order shouldn't affect the child ending up at 0,0
|
|
|
|
QCOMPARE(childWindowFirst.framePosition(), topLeftOrigin);
|
|
|
|
QCOMPARE(childWindowAfter.framePosition(), topLeftOrigin);
|
|
|
|
}
|
|
|
|
|
2015-12-09 17:06:20 +00:00
|
|
|
// 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)));
|
|
|
|
}
|
|
|
|
|
2014-11-15 11:40:51 +00:00
|
|
|
class PlatformWindowFilter : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
PlatformWindowFilter(QObject *parent = 0)
|
|
|
|
: QObject(parent)
|
|
|
|
, m_window(Q_NULLPTR)
|
|
|
|
, m_alwaysExisted(true)
|
|
|
|
{}
|
|
|
|
|
|
|
|
void setWindow(Window *window) { m_window = window; }
|
|
|
|
|
|
|
|
bool eventFilter(QObject *o, QEvent *e)
|
|
|
|
{
|
|
|
|
// Check that the platform surface events are delivered synchronously.
|
|
|
|
// If they are, the native platform surface should always exist when we
|
|
|
|
// receive a QPlatformSurfaceEvent
|
|
|
|
if (e->type() == QEvent::PlatformSurface && o == m_window) {
|
|
|
|
m_alwaysExisted &= (m_window->handle() != Q_NULLPTR);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool surfaceExisted() const { return m_alwaysExisted; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
Window *m_window;
|
|
|
|
bool m_alwaysExisted;
|
|
|
|
};
|
|
|
|
|
|
|
|
void tst_QWindow::platformSurface()
|
|
|
|
{
|
|
|
|
QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize);
|
|
|
|
|
|
|
|
Window window;
|
|
|
|
PlatformWindowFilter filter;
|
|
|
|
filter.setWindow(&window);
|
|
|
|
window.installEventFilter(&filter);
|
|
|
|
|
|
|
|
window.setGeometry(geometry);
|
|
|
|
QCOMPARE(window.geometry(), geometry);
|
|
|
|
window.create();
|
|
|
|
|
2015-07-30 13:15:12 +00:00
|
|
|
QTRY_COMPARE(window.received(QEvent::PlatformSurface), 1);
|
|
|
|
QTRY_COMPARE(window.surfaceEventType(), QPlatformSurfaceEvent::SurfaceCreated);
|
2014-11-15 11:40:51 +00:00
|
|
|
QTRY_VERIFY(window.handle() != Q_NULLPTR);
|
|
|
|
|
|
|
|
window.destroy();
|
2015-07-30 13:15:12 +00:00
|
|
|
QTRY_COMPARE(window.received(QEvent::PlatformSurface), 2);
|
|
|
|
QTRY_COMPARE(window.surfaceEventType(), QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed);
|
|
|
|
QTRY_VERIFY(!window.handle());
|
2014-11-15 11:40:51 +00:00
|
|
|
|
|
|
|
// Check for synchronous delivery of platform surface events and that the platform
|
|
|
|
// surface always existed upon event delivery
|
|
|
|
QTRY_VERIFY(filter.surfaceExisted());
|
|
|
|
}
|
|
|
|
|
2012-03-14 16:55:43 +00:00
|
|
|
void tst_QWindow::isExposed()
|
|
|
|
{
|
2014-07-31 11:48:15 +00:00
|
|
|
QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize);
|
2012-03-14 16:55:43 +00:00
|
|
|
|
|
|
|
Window window;
|
|
|
|
window.setGeometry(geometry);
|
|
|
|
QCOMPARE(window.geometry(), geometry);
|
|
|
|
window.show();
|
2012-04-27 13:45:24 +00:00
|
|
|
QCoreApplication::processEvents();
|
2012-03-14 16:55:43 +00:00
|
|
|
|
|
|
|
QTRY_VERIFY(window.received(QEvent::Expose) > 0);
|
|
|
|
QTRY_VERIFY(window.isExposed());
|
|
|
|
|
2014-08-20 15:32:24 +00:00
|
|
|
#ifndef Q_OS_WIN
|
2014-07-28 13:55:56 +00:00
|
|
|
// This is a top-level window so assuming it is completely exposed, the
|
|
|
|
// expose region must be (0, 0), (width, height). If this is not the case,
|
|
|
|
// the platform plugin is sending expose events with a region in an
|
|
|
|
// incorrect coordinate system.
|
|
|
|
QRect r = window.exposeRegion().boundingRect();
|
|
|
|
r = QRect(window.mapToGlobal(r.topLeft()), r.size());
|
|
|
|
QCOMPARE(r, window.geometry());
|
2014-08-20 15:32:24 +00:00
|
|
|
#endif
|
2014-07-28 13:55:56 +00:00
|
|
|
|
2012-03-14 16:55:43 +00:00
|
|
|
window.hide();
|
|
|
|
|
2015-09-24 07:25:25 +00:00
|
|
|
if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
|
2014-08-21 11:23:25 +00:00
|
|
|
QSKIP("Wayland: This is flaky. Figure out why.");
|
|
|
|
|
2012-04-27 13:45:24 +00:00
|
|
|
QCoreApplication::processEvents();
|
2012-03-14 16:55:43 +00:00
|
|
|
QTRY_VERIFY(window.received(QEvent::Expose) > 1);
|
|
|
|
QTRY_VERIFY(!window.isExposed());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-09-29 16:02:54 +00:00
|
|
|
void tst_QWindow::isActive()
|
|
|
|
{
|
2015-09-24 07:25:25 +00:00
|
|
|
if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
|
2014-08-21 11:23:25 +00:00
|
|
|
QSKIP("Wayland: This fails. Figure out why.");
|
|
|
|
|
2011-09-29 16:02:54 +00:00
|
|
|
Window window;
|
2012-04-27 13:45:24 +00:00
|
|
|
// Some platforms enforce minimum widths for windows, which can cause extra resize
|
|
|
|
// events, so set the width to suitably large value to avoid those.
|
2014-07-31 11:48:15 +00:00
|
|
|
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
2011-09-29 16:02:54 +00:00
|
|
|
window.show();
|
2012-04-27 13:45:24 +00:00
|
|
|
QCoreApplication::processEvents();
|
2011-09-29 16:02:54 +00:00
|
|
|
|
2012-03-14 16:55:43 +00:00
|
|
|
QTRY_VERIFY(window.isExposed());
|
2014-03-18 16:18:04 +00:00
|
|
|
#if defined(Q_OS_QNX) // We either need to create a eglSurface or a create a backing store
|
|
|
|
// and then post the window in order for screen to show the window
|
|
|
|
QOpenGLContext context;
|
|
|
|
context.create();
|
|
|
|
context.makeCurrent(&window);
|
|
|
|
context.swapBuffers(&window);
|
|
|
|
#endif
|
2011-09-29 16:02:54 +00:00
|
|
|
QTRY_COMPARE(window.received(QEvent::Resize), 1);
|
2015-07-30 13:15:12 +00:00
|
|
|
QTRY_COMPARE(QGuiApplication::focusWindow(), &window);
|
2011-09-29 16:02:54 +00:00
|
|
|
QVERIFY(window.isActive());
|
|
|
|
|
|
|
|
Window child;
|
|
|
|
child.setParent(&window);
|
|
|
|
child.setGeometry(10, 10, 20, 20);
|
|
|
|
child.show();
|
|
|
|
|
2012-03-14 16:55:43 +00:00
|
|
|
QTRY_VERIFY(child.isExposed());
|
2011-09-29 16:02:54 +00:00
|
|
|
|
Rename all QWindow properties that have "window" in them
windowTitle, windowModality, windowIcon and so on are named that way
to be similar to the ones in QWidget. However QQuickWindow inherits
all of the declared properties, and we would like to have shorter
property names in QML. If you are working with a Window then it's
obvious the title property is the window title. Unfortunately,
there must be patches in many other modules which depend on this one.
In order to avoid the need to merge them all at the same time,
there is also patch https://codereview.qt-project.org/#change,39001
which temporarily adds backwards-compatible accessors, which can be
removed after the other modules are able to build without them.
We should not rename windowState to state, because in QML, state
usually drives the state machine for animation transitions etc.
(although QWindow is not an Item, a user might get confused about it).
Related patches are
https://codereview.qt-project.org/#change,39001
https://codereview.qt-project.org/#change,37764
https://codereview.qt-project.org/#change,37765
https://codereview.qt-project.org/#change,37766
https://codereview.qt-project.org/#change,37762
Change-Id: Ie4424ec15fbdef6b29b137f90a2ae33f173edd21
Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
2012-10-22 10:47:34 +00:00
|
|
|
child.requestActivate();
|
2011-09-29 16:02:54 +00:00
|
|
|
|
2015-07-30 13:15:12 +00:00
|
|
|
QTRY_COMPARE(QGuiApplication::focusWindow(), &child);
|
2011-09-29 16:02:54 +00:00
|
|
|
QVERIFY(child.isActive());
|
|
|
|
|
2012-03-14 16:55:43 +00:00
|
|
|
// parent shouldn't receive new resize events from child being shown
|
2012-04-27 13:45:24 +00:00
|
|
|
QCoreApplication::processEvents();
|
2011-09-29 16:02:54 +00:00
|
|
|
QTRY_COMPARE(window.received(QEvent::Resize), 1);
|
|
|
|
QTRY_COMPARE(window.received(QEvent::FocusIn), 1);
|
|
|
|
QTRY_COMPARE(window.received(QEvent::FocusOut), 1);
|
|
|
|
QTRY_COMPARE(child.received(QEvent::FocusIn), 1);
|
|
|
|
|
|
|
|
// child has focus
|
|
|
|
QVERIFY(window.isActive());
|
|
|
|
|
|
|
|
Window dialog;
|
|
|
|
dialog.setTransientParent(&window);
|
2014-07-31 11:48:15 +00:00
|
|
|
dialog.setGeometry(QRect(m_availableTopLeft + QPoint(110, 100), m_testWindowSize));
|
2011-09-29 16:02:54 +00:00
|
|
|
dialog.show();
|
|
|
|
|
Rename all QWindow properties that have "window" in them
windowTitle, windowModality, windowIcon and so on are named that way
to be similar to the ones in QWidget. However QQuickWindow inherits
all of the declared properties, and we would like to have shorter
property names in QML. If you are working with a Window then it's
obvious the title property is the window title. Unfortunately,
there must be patches in many other modules which depend on this one.
In order to avoid the need to merge them all at the same time,
there is also patch https://codereview.qt-project.org/#change,39001
which temporarily adds backwards-compatible accessors, which can be
removed after the other modules are able to build without them.
We should not rename windowState to state, because in QML, state
usually drives the state machine for animation transitions etc.
(although QWindow is not an Item, a user might get confused about it).
Related patches are
https://codereview.qt-project.org/#change,39001
https://codereview.qt-project.org/#change,37764
https://codereview.qt-project.org/#change,37765
https://codereview.qt-project.org/#change,37766
https://codereview.qt-project.org/#change,37762
Change-Id: Ie4424ec15fbdef6b29b137f90a2ae33f173edd21
Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
2012-10-22 10:47:34 +00:00
|
|
|
dialog.requestActivate();
|
2011-09-29 16:02:54 +00:00
|
|
|
|
2012-03-14 16:55:43 +00:00
|
|
|
QTRY_VERIFY(dialog.isExposed());
|
2012-04-27 13:45:24 +00:00
|
|
|
QCoreApplication::processEvents();
|
2011-09-29 16:02:54 +00:00
|
|
|
QTRY_COMPARE(dialog.received(QEvent::Resize), 1);
|
2015-07-30 13:15:12 +00:00
|
|
|
QTRY_COMPARE(QGuiApplication::focusWindow(), &dialog);
|
2011-09-29 16:02:54 +00:00
|
|
|
QVERIFY(dialog.isActive());
|
|
|
|
|
|
|
|
// transient child has focus
|
|
|
|
QVERIFY(window.isActive());
|
|
|
|
|
|
|
|
// parent is active
|
|
|
|
QVERIFY(child.isActive());
|
|
|
|
|
Rename all QWindow properties that have "window" in them
windowTitle, windowModality, windowIcon and so on are named that way
to be similar to the ones in QWidget. However QQuickWindow inherits
all of the declared properties, and we would like to have shorter
property names in QML. If you are working with a Window then it's
obvious the title property is the window title. Unfortunately,
there must be patches in many other modules which depend on this one.
In order to avoid the need to merge them all at the same time,
there is also patch https://codereview.qt-project.org/#change,39001
which temporarily adds backwards-compatible accessors, which can be
removed after the other modules are able to build without them.
We should not rename windowState to state, because in QML, state
usually drives the state machine for animation transitions etc.
(although QWindow is not an Item, a user might get confused about it).
Related patches are
https://codereview.qt-project.org/#change,39001
https://codereview.qt-project.org/#change,37764
https://codereview.qt-project.org/#change,37765
https://codereview.qt-project.org/#change,37766
https://codereview.qt-project.org/#change,37762
Change-Id: Ie4424ec15fbdef6b29b137f90a2ae33f173edd21
Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
2012-10-22 10:47:34 +00:00
|
|
|
window.requestActivate();
|
2011-09-29 16:02:54 +00:00
|
|
|
|
2015-07-30 13:15:12 +00:00
|
|
|
QTRY_COMPARE(QGuiApplication::focusWindow(), &window);
|
2012-04-27 13:45:24 +00:00
|
|
|
QCoreApplication::processEvents();
|
2011-09-29 16:02:54 +00:00
|
|
|
QTRY_COMPARE(dialog.received(QEvent::FocusOut), 1);
|
|
|
|
QTRY_COMPARE(window.received(QEvent::FocusIn), 2);
|
|
|
|
|
|
|
|
QVERIFY(window.isActive());
|
|
|
|
|
|
|
|
// transient parent has focus
|
|
|
|
QVERIFY(dialog.isActive());
|
|
|
|
|
|
|
|
// parent has focus
|
|
|
|
QVERIFY(child.isActive());
|
|
|
|
}
|
|
|
|
|
2011-12-12 15:24:33 +00:00
|
|
|
class InputTestWindow : public QWindow
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
void keyPressEvent(QKeyEvent *event) {
|
|
|
|
keyPressCode = event->key();
|
|
|
|
}
|
|
|
|
void keyReleaseEvent(QKeyEvent *event) {
|
|
|
|
keyReleaseCode = event->key();
|
|
|
|
}
|
|
|
|
void mousePressEvent(QMouseEvent *event) {
|
2012-01-23 08:28:58 +00:00
|
|
|
if (ignoreMouse) {
|
2012-01-12 07:53:13 +00:00
|
|
|
event->ignore();
|
2012-01-23 08:28:58 +00:00
|
|
|
} else {
|
2012-03-24 08:48:12 +00:00
|
|
|
++mousePressedCount;
|
|
|
|
mouseSequenceSignature += 'p';
|
2012-01-12 07:53:13 +00:00
|
|
|
mousePressButton = event->button();
|
2012-01-23 08:28:58 +00:00
|
|
|
mousePressScreenPos = event->screenPos();
|
2012-05-23 12:38:22 +00:00
|
|
|
mousePressLocalPos = event->localPos();
|
2012-04-23 13:18:01 +00:00
|
|
|
if (spinLoopWhenPressed)
|
|
|
|
QCoreApplication::processEvents();
|
2012-01-23 08:28:58 +00:00
|
|
|
}
|
2011-12-12 15:24:33 +00:00
|
|
|
}
|
|
|
|
void mouseReleaseEvent(QMouseEvent *event) {
|
2012-03-24 08:48:12 +00:00
|
|
|
if (ignoreMouse) {
|
2012-01-12 07:53:13 +00:00
|
|
|
event->ignore();
|
2012-03-24 08:48:12 +00:00
|
|
|
} else {
|
|
|
|
++mouseReleasedCount;
|
|
|
|
mouseSequenceSignature += 'r';
|
2012-01-12 07:53:13 +00:00
|
|
|
mouseReleaseButton = event->button();
|
2012-03-24 08:48:12 +00:00
|
|
|
}
|
2011-12-12 15:24:33 +00:00
|
|
|
}
|
2012-01-23 08:28:58 +00:00
|
|
|
void mouseMoveEvent(QMouseEvent *event) {
|
|
|
|
if (ignoreMouse) {
|
|
|
|
event->ignore();
|
|
|
|
} else {
|
2012-04-23 13:18:01 +00:00
|
|
|
++mouseMovedCount;
|
2012-01-23 08:28:58 +00:00
|
|
|
mouseMoveButton = event->button();
|
|
|
|
mouseMoveScreenPos = event->screenPos();
|
|
|
|
}
|
|
|
|
}
|
2012-03-24 08:48:12 +00:00
|
|
|
void mouseDoubleClickEvent(QMouseEvent *event) {
|
|
|
|
if (ignoreMouse) {
|
|
|
|
event->ignore();
|
|
|
|
} else {
|
|
|
|
++mouseDoubleClickedCount;
|
|
|
|
mouseSequenceSignature += 'd';
|
|
|
|
}
|
|
|
|
}
|
2011-12-12 15:24:33 +00:00
|
|
|
void touchEvent(QTouchEvent *event) {
|
2012-01-12 07:53:13 +00:00
|
|
|
if (ignoreTouch) {
|
|
|
|
event->ignore();
|
|
|
|
return;
|
|
|
|
}
|
2012-02-09 12:39:40 +00:00
|
|
|
touchEventType = event->type();
|
2011-12-12 15:24:33 +00:00
|
|
|
QList<QTouchEvent::TouchPoint> points = event->touchPoints();
|
|
|
|
for (int i = 0; i < points.count(); ++i) {
|
|
|
|
switch (points.at(i).state()) {
|
|
|
|
case Qt::TouchPointPressed:
|
|
|
|
++touchPressedCount;
|
2012-04-23 13:18:01 +00:00
|
|
|
if (spinLoopWhenPressed)
|
|
|
|
QCoreApplication::processEvents();
|
2011-12-12 15:24:33 +00:00
|
|
|
break;
|
|
|
|
case Qt::TouchPointReleased:
|
|
|
|
++touchReleasedCount;
|
|
|
|
break;
|
2012-02-09 12:39:40 +00:00
|
|
|
case Qt::TouchPointMoved:
|
|
|
|
++touchMovedCount;
|
|
|
|
break;
|
2012-01-12 07:53:13 +00:00
|
|
|
default:
|
|
|
|
break;
|
2011-12-12 15:24:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-01-19 21:32:52 +00:00
|
|
|
bool event(QEvent *e) {
|
|
|
|
switch (e->type()) {
|
|
|
|
case QEvent::Enter:
|
|
|
|
++enterEventCount;
|
|
|
|
break;
|
|
|
|
case QEvent::Leave:
|
|
|
|
++leaveEventCount;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return QWindow::event(e);
|
|
|
|
}
|
2012-03-24 08:48:12 +00:00
|
|
|
void resetCounters() {
|
2012-04-23 13:18:01 +00:00
|
|
|
mousePressedCount = mouseReleasedCount = mouseMovedCount = mouseDoubleClickedCount = 0;
|
2012-03-24 08:48:12 +00:00
|
|
|
mouseSequenceSignature = QString();
|
|
|
|
touchPressedCount = touchReleasedCount = touchMovedCount = 0;
|
2016-01-19 21:32:52 +00:00
|
|
|
enterEventCount = leaveEventCount = 0;
|
2012-03-24 08:48:12 +00:00
|
|
|
}
|
2011-12-12 15:24:33 +00:00
|
|
|
|
|
|
|
InputTestWindow() {
|
|
|
|
keyPressCode = keyReleaseCode = 0;
|
2012-03-24 08:48:12 +00:00
|
|
|
mousePressButton = mouseReleaseButton = mouseMoveButton = 0;
|
2012-02-09 12:39:40 +00:00
|
|
|
ignoreMouse = ignoreTouch = false;
|
2012-04-23 13:18:01 +00:00
|
|
|
spinLoopWhenPressed = false;
|
2012-03-24 08:48:12 +00:00
|
|
|
resetCounters();
|
2011-12-12 15:24:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int keyPressCode, keyReleaseCode;
|
2012-01-23 08:28:58 +00:00
|
|
|
int mousePressButton, mouseReleaseButton, mouseMoveButton;
|
2012-04-23 13:18:01 +00:00
|
|
|
int mousePressedCount, mouseReleasedCount, mouseMovedCount, mouseDoubleClickedCount;
|
2012-03-24 08:48:12 +00:00
|
|
|
QString mouseSequenceSignature;
|
2012-05-23 12:38:22 +00:00
|
|
|
QPointF mousePressScreenPos, mouseMoveScreenPos, mousePressLocalPos;
|
2012-02-09 12:39:40 +00:00
|
|
|
int touchPressedCount, touchReleasedCount, touchMovedCount;
|
|
|
|
QEvent::Type touchEventType;
|
2016-01-19 21:32:52 +00:00
|
|
|
int enterEventCount, leaveEventCount;
|
2012-01-12 07:53:13 +00:00
|
|
|
|
|
|
|
bool ignoreMouse, ignoreTouch;
|
2012-04-23 13:18:01 +00:00
|
|
|
|
|
|
|
bool spinLoopWhenPressed;
|
2011-12-12 15:24:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
void tst_QWindow::testInputEvents()
|
|
|
|
{
|
|
|
|
InputTestWindow window;
|
2014-07-31 11:48:15 +00:00
|
|
|
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
2013-05-31 18:27:50 +00:00
|
|
|
window.showNormal();
|
2012-07-20 10:49:12 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&window));
|
2011-12-12 15:24:33 +00:00
|
|
|
|
2015-06-18 15:01:01 +00:00
|
|
|
QTest::keyClick(&window, Qt::Key_A, Qt::NoModifier);
|
2011-12-12 15:24:33 +00:00
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QCOMPARE(window.keyPressCode, int(Qt::Key_A));
|
|
|
|
QCOMPARE(window.keyReleaseCode, int(Qt::Key_A));
|
|
|
|
|
|
|
|
QPointF local(12, 34);
|
2015-06-18 15:01:01 +00:00
|
|
|
QTest::mouseClick(&window, Qt::LeftButton, Qt::NoModifier, local.toPoint());
|
2011-12-12 15:24:33 +00:00
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QCOMPARE(window.mousePressButton, int(Qt::LeftButton));
|
|
|
|
QCOMPARE(window.mouseReleaseButton, int(Qt::LeftButton));
|
2012-05-23 12:38:22 +00:00
|
|
|
QCOMPARE(window.mousePressLocalPos, local);
|
2011-12-12 15:24:33 +00:00
|
|
|
|
2012-01-12 07:53:13 +00:00
|
|
|
QList<QWindowSystemInterface::TouchPoint> points;
|
|
|
|
QWindowSystemInterface::TouchPoint tp1, tp2;
|
|
|
|
tp1.id = 1;
|
|
|
|
tp1.state = Qt::TouchPointPressed;
|
|
|
|
tp1.area = QRect(10, 10, 4, 4);
|
|
|
|
tp2.id = 2;
|
|
|
|
tp2.state = Qt::TouchPointPressed;
|
|
|
|
tp2.area = QRect(20, 20, 4, 4);
|
|
|
|
points << tp1 << tp2;
|
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
|
|
|
points[0].state = Qt::TouchPointReleased;
|
|
|
|
points[1].state = Qt::TouchPointReleased;
|
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QTRY_COMPARE(window.touchPressedCount, 2);
|
|
|
|
QTRY_COMPARE(window.touchReleasedCount, 2);
|
2012-05-23 12:38:22 +00:00
|
|
|
|
|
|
|
// 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;
|
2015-06-18 15:01:01 +00:00
|
|
|
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);
|
2012-05-23 12:38:22 +00:00
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QCOMPARE(window.mousePressButton, 0);
|
|
|
|
QCOMPARE(window.mouseReleaseButton, 0);
|
2015-06-18 15:01:01 +00:00
|
|
|
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);
|
2012-05-23 12:38:22 +00:00
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QCOMPARE(window.mousePressButton, int(Qt::LeftButton));
|
|
|
|
QCOMPARE(window.mouseReleaseButton, int(Qt::LeftButton));
|
|
|
|
QCOMPARE(window.mousePressScreenPos, windowGlobal);
|
|
|
|
QCOMPARE(window.mousePressLocalPos, local); // the local we passed was bogus, verify that qGuiApp calculated the proper one
|
2012-01-12 07:53:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QWindow::touchToMouseTranslation()
|
|
|
|
{
|
|
|
|
InputTestWindow window;
|
|
|
|
window.ignoreTouch = true;
|
2014-07-31 11:48:15 +00:00
|
|
|
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
2012-01-12 07:53:13 +00:00
|
|
|
window.show();
|
2012-07-20 10:49:12 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&window));
|
2012-01-12 07:53:13 +00:00
|
|
|
|
2011-12-12 15:24:33 +00:00
|
|
|
QList<QWindowSystemInterface::TouchPoint> points;
|
|
|
|
QWindowSystemInterface::TouchPoint tp1, tp2;
|
2012-01-23 08:28:58 +00:00
|
|
|
const QRectF pressArea(101, 102, 4, 4);
|
|
|
|
const QRectF moveArea(105, 108, 4, 4);
|
2011-12-12 15:24:33 +00:00
|
|
|
tp1.id = 1;
|
|
|
|
tp1.state = Qt::TouchPointPressed;
|
2015-06-18 15:01:01 +00:00
|
|
|
tp1.area = QHighDpi::toNativePixels(pressArea, &window);
|
2011-12-12 15:24:33 +00:00
|
|
|
tp2.id = 2;
|
|
|
|
tp2.state = Qt::TouchPointPressed;
|
|
|
|
points << tp1 << tp2;
|
2012-01-12 07:53:13 +00:00
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
2012-01-23 08:28:58 +00:00
|
|
|
// Now an update but with changed list order. The mouse event should still
|
|
|
|
// be generated from the point with id 1.
|
|
|
|
tp1.id = 2;
|
|
|
|
tp1.state = Qt::TouchPointStationary;
|
|
|
|
tp2.id = 1;
|
|
|
|
tp2.state = Qt::TouchPointMoved;
|
2015-06-18 15:01:01 +00:00
|
|
|
tp2.area = QHighDpi::toNativePixels(moveArea, &window);
|
2012-01-23 08:28:58 +00:00
|
|
|
points.clear();
|
|
|
|
points << tp1 << tp2;
|
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
2012-01-12 07:53:13 +00:00
|
|
|
points[0].state = Qt::TouchPointReleased;
|
|
|
|
points[1].state = Qt::TouchPointReleased;
|
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
|
|
|
|
QTRY_COMPARE(window.mousePressButton, int(Qt::LeftButton));
|
|
|
|
QTRY_COMPARE(window.mouseReleaseButton, int(Qt::LeftButton));
|
2012-01-23 08:28:58 +00:00
|
|
|
QTRY_COMPARE(window.mousePressScreenPos, pressArea.center());
|
|
|
|
QTRY_COMPARE(window.mouseMoveScreenPos, moveArea.center());
|
2012-01-12 07:53:13 +00:00
|
|
|
|
|
|
|
window.mousePressButton = 0;
|
|
|
|
window.mouseReleaseButton = 0;
|
|
|
|
|
|
|
|
window.ignoreTouch = false;
|
|
|
|
|
|
|
|
points[0].state = Qt::TouchPointPressed;
|
|
|
|
points[1].state = Qt::TouchPointPressed;
|
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
|
|
|
points[0].state = Qt::TouchPointReleased;
|
|
|
|
points[1].state = Qt::TouchPointReleased;
|
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
|
|
|
|
// no new mouse events should be generated since the input window handles the touch events
|
|
|
|
QTRY_COMPARE(window.mousePressButton, 0);
|
|
|
|
QTRY_COMPARE(window.mouseReleaseButton, 0);
|
|
|
|
|
|
|
|
qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, false);
|
|
|
|
|
|
|
|
window.ignoreTouch = true;
|
|
|
|
points[0].state = Qt::TouchPointPressed;
|
|
|
|
points[1].state = Qt::TouchPointPressed;
|
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
2011-12-12 15:24:33 +00:00
|
|
|
points[0].state = Qt::TouchPointReleased;
|
|
|
|
points[1].state = Qt::TouchPointReleased;
|
2012-01-12 07:53:13 +00:00
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
2011-12-12 15:24:33 +00:00
|
|
|
QCoreApplication::processEvents();
|
2012-01-12 07:53:13 +00:00
|
|
|
|
|
|
|
qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true);
|
|
|
|
|
|
|
|
// mouse event synthesizing disabled
|
|
|
|
QTRY_COMPARE(window.mousePressButton, 0);
|
|
|
|
QTRY_COMPARE(window.mouseReleaseButton, 0);
|
|
|
|
}
|
|
|
|
|
2014-12-09 15:52:24 +00:00
|
|
|
void tst_QWindow::touchToMouseTranslationForDevices()
|
|
|
|
{
|
|
|
|
InputTestWindow window;
|
|
|
|
window.ignoreTouch = true;
|
|
|
|
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
|
|
|
window.show();
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&window));
|
|
|
|
|
|
|
|
QPoint touchPoint(10, 10);
|
|
|
|
|
|
|
|
QTest::touchEvent(&window, touchDevice).press(0, touchPoint, &window);
|
|
|
|
QTest::touchEvent(&window, touchDevice).release(0, touchPoint, &window);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
|
|
|
|
QCOMPARE(window.mousePressedCount, 1);
|
|
|
|
QCOMPARE(window.mouseReleasedCount, 1);
|
|
|
|
|
|
|
|
window.resetCounters();
|
|
|
|
|
|
|
|
touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation);
|
|
|
|
QTest::touchEvent(&window, touchDevice).press(0, touchPoint, &window);
|
|
|
|
QTest::touchEvent(&window, touchDevice).release(0, touchPoint, &window);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
touchDevice->setCapabilities(touchDevice->capabilities() & ~QTouchDevice::MouseEmulation);
|
|
|
|
|
|
|
|
QCOMPARE(window.mousePressedCount, 0);
|
|
|
|
QCOMPARE(window.mouseReleasedCount, 0);
|
|
|
|
}
|
|
|
|
|
2012-01-12 07:53:13 +00:00
|
|
|
void tst_QWindow::mouseToTouchTranslation()
|
|
|
|
{
|
|
|
|
qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true);
|
|
|
|
|
|
|
|
InputTestWindow window;
|
|
|
|
window.ignoreMouse = true;
|
2014-07-31 11:48:15 +00:00
|
|
|
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
2012-01-12 07:53:13 +00:00
|
|
|
window.show();
|
2012-07-20 10:49:12 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&window));
|
2012-01-12 07:53:13 +00:00
|
|
|
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::NoButton);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
|
|
|
|
qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false);
|
|
|
|
|
|
|
|
QTRY_COMPARE(window.touchPressedCount, 1);
|
|
|
|
QTRY_COMPARE(window.touchReleasedCount, 1);
|
|
|
|
|
|
|
|
qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true);
|
|
|
|
|
|
|
|
window.ignoreMouse = false;
|
|
|
|
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::NoButton);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
|
|
|
|
qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false);
|
|
|
|
|
|
|
|
// no new touch events should be generated since the input window handles the mouse events
|
|
|
|
QTRY_COMPARE(window.touchPressedCount, 1);
|
|
|
|
QTRY_COMPARE(window.touchReleasedCount, 1);
|
|
|
|
|
|
|
|
window.ignoreMouse = true;
|
|
|
|
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::NoButton);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
|
|
|
|
// touch event synthesis disabled
|
|
|
|
QTRY_COMPARE(window.touchPressedCount, 1);
|
|
|
|
QTRY_COMPARE(window.touchReleasedCount, 1);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QWindow::mouseToTouchLoop()
|
|
|
|
{
|
|
|
|
// make sure there's no infinite loop when synthesizing both ways
|
|
|
|
qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true);
|
|
|
|
qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true);
|
|
|
|
|
|
|
|
InputTestWindow window;
|
|
|
|
window.ignoreMouse = true;
|
|
|
|
window.ignoreTouch = true;
|
2014-07-31 11:48:15 +00:00
|
|
|
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
2012-01-12 07:53:13 +00:00
|
|
|
window.show();
|
2012-07-20 10:49:12 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&window));
|
2012-01-12 07:53:13 +00:00
|
|
|
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, QPoint(10, 10), window.mapToGlobal(QPoint(10, 10)), Qt::NoButton);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
|
|
|
|
qApp->setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false);
|
2012-02-09 12:39:40 +00:00
|
|
|
qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QWindow::touchCancel()
|
|
|
|
{
|
|
|
|
InputTestWindow window;
|
2014-07-31 11:48:15 +00:00
|
|
|
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
2012-02-09 12:39:40 +00:00
|
|
|
window.show();
|
2012-07-20 10:49:12 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&window));
|
2012-02-09 12:39:40 +00:00
|
|
|
|
|
|
|
QList<QWindowSystemInterface::TouchPoint> points;
|
|
|
|
QWindowSystemInterface::TouchPoint tp1;
|
|
|
|
tp1.id = 1;
|
|
|
|
|
|
|
|
// Start a touch.
|
|
|
|
tp1.state = Qt::TouchPointPressed;
|
|
|
|
tp1.area = QRect(10, 10, 4, 4);
|
|
|
|
points << tp1;
|
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QTRY_COMPARE(window.touchEventType, QEvent::TouchBegin);
|
|
|
|
QTRY_COMPARE(window.touchPressedCount, 1);
|
|
|
|
|
|
|
|
// Cancel the active touch sequence.
|
|
|
|
QWindowSystemInterface::handleTouchCancelEvent(&window, touchDevice);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QTRY_COMPARE(window.touchEventType, QEvent::TouchCancel);
|
|
|
|
|
|
|
|
// Send a move -> will not be delivered due to the cancellation.
|
|
|
|
QTRY_COMPARE(window.touchMovedCount, 0);
|
|
|
|
points[0].state = Qt::TouchPointMoved;
|
|
|
|
tp1.area.adjust(2, 2, 2, 2);
|
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QTRY_COMPARE(window.touchMovedCount, 0);
|
|
|
|
|
|
|
|
// Likewise. The only allowed transition is TouchCancel -> TouchBegin.
|
|
|
|
QTRY_COMPARE(window.touchReleasedCount, 0);
|
|
|
|
points[0].state = Qt::TouchPointReleased;
|
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QTRY_COMPARE(window.touchReleasedCount, 0);
|
|
|
|
|
|
|
|
// Start a new sequence -> from this point on everything should go through normally.
|
|
|
|
points[0].state = Qt::TouchPointPressed;
|
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QTRY_COMPARE(window.touchEventType, QEvent::TouchBegin);
|
|
|
|
QTRY_COMPARE(window.touchPressedCount, 2);
|
|
|
|
|
|
|
|
points[0].state = Qt::TouchPointMoved;
|
|
|
|
tp1.area.adjust(2, 2, 2, 2);
|
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QTRY_COMPARE(window.touchMovedCount, 1);
|
|
|
|
|
|
|
|
points[0].state = Qt::TouchPointReleased;
|
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QTRY_COMPARE(window.touchReleasedCount, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QWindow::touchCancelWithTouchToMouse()
|
|
|
|
{
|
|
|
|
InputTestWindow window;
|
|
|
|
window.ignoreTouch = true;
|
2014-07-31 11:48:15 +00:00
|
|
|
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
2012-02-09 12:39:40 +00:00
|
|
|
window.show();
|
2012-07-20 10:49:12 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&window));
|
2012-02-09 12:39:40 +00:00
|
|
|
|
|
|
|
QList<QWindowSystemInterface::TouchPoint> points;
|
|
|
|
QWindowSystemInterface::TouchPoint tp1;
|
|
|
|
tp1.id = 1;
|
|
|
|
|
|
|
|
tp1.state = Qt::TouchPointPressed;
|
2015-06-18 15:01:01 +00:00
|
|
|
const QRect area(100, 100, 4, 4);
|
|
|
|
tp1.area = QHighDpi::toNativePixels(area, &window);
|
2012-02-09 12:39:40 +00:00
|
|
|
points << tp1;
|
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QTRY_COMPARE(window.mousePressButton, int(Qt::LeftButton));
|
2015-06-18 15:01:01 +00:00
|
|
|
const int fuzz = 2 * int(QHighDpiScaling::factor(&window));
|
|
|
|
QTRY_VERIFY2(qFuzzyCompareWindowPosition(window.mousePressScreenPos.toPoint(), area.center(), fuzz),
|
|
|
|
qPrintable(msgPointMismatch(window.mousePressScreenPos.toPoint(), area.center())));
|
2012-02-09 12:39:40 +00:00
|
|
|
|
|
|
|
// Cancel the touch. Should result in a mouse release for windows that have
|
|
|
|
// have an active touch-to-mouse sequence.
|
|
|
|
QWindowSystemInterface::handleTouchCancelEvent(0, touchDevice);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
|
|
|
|
QTRY_COMPARE(window.mouseReleaseButton, int(Qt::LeftButton));
|
|
|
|
|
|
|
|
// Now change the window to accept touches.
|
|
|
|
window.mousePressButton = window.mouseReleaseButton = 0;
|
|
|
|
window.ignoreTouch = false;
|
|
|
|
|
|
|
|
// Send a touch, there will be no mouse event generated.
|
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QTRY_COMPARE(window.mousePressButton, 0);
|
|
|
|
|
|
|
|
// Cancel the touch. It should not result in a mouse release with this window.
|
|
|
|
QWindowSystemInterface::handleTouchCancelEvent(0, touchDevice);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QTRY_COMPARE(window.mouseReleaseButton, 0);
|
2011-12-12 15:24:33 +00:00
|
|
|
}
|
|
|
|
|
2014-03-11 21:10:05 +00:00
|
|
|
void tst_QWindow::touchInterruptedByPopup()
|
|
|
|
{
|
|
|
|
InputTestWindow window;
|
2014-07-31 11:48:15 +00:00
|
|
|
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
2014-03-11 21:10:05 +00:00
|
|
|
window.show();
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&window));
|
|
|
|
|
|
|
|
QList<QWindowSystemInterface::TouchPoint> points;
|
|
|
|
QWindowSystemInterface::TouchPoint tp1;
|
|
|
|
tp1.id = 1;
|
|
|
|
|
|
|
|
// Start a touch.
|
|
|
|
tp1.state = Qt::TouchPointPressed;
|
|
|
|
tp1.area = QRect(10, 10, 4, 4);
|
|
|
|
points << tp1;
|
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QTRY_COMPARE(window.touchEventType, QEvent::TouchBegin);
|
|
|
|
QTRY_COMPARE(window.touchPressedCount, 1);
|
|
|
|
|
|
|
|
// Launch a popup window
|
|
|
|
InputTestWindow popup;
|
|
|
|
popup.setFlags(Qt::Popup);
|
|
|
|
popup.setModality(Qt::WindowModal);
|
2014-07-31 11:48:15 +00:00
|
|
|
popup.resize(m_testWindowSize / 2);
|
2014-03-11 21:10:05 +00:00
|
|
|
popup.setTransientParent(&window);
|
|
|
|
popup.show();
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&popup));
|
|
|
|
|
|
|
|
// Send a move -> will not be delivered to the original window
|
|
|
|
// (TODO verify where it is forwarded, after we've defined that)
|
|
|
|
QTRY_COMPARE(window.touchMovedCount, 0);
|
|
|
|
points[0].state = Qt::TouchPointMoved;
|
|
|
|
tp1.area.adjust(2, 2, 2, 2);
|
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QTRY_COMPARE(window.touchMovedCount, 0);
|
|
|
|
|
|
|
|
// Send a touch end -> will not be delivered to the original window
|
|
|
|
QTRY_COMPARE(window.touchReleasedCount, 0);
|
|
|
|
points[0].state = Qt::TouchPointReleased;
|
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QTRY_COMPARE(window.touchReleasedCount, 0);
|
|
|
|
|
|
|
|
// Due to temporary fix for QTBUG-37371: the original window should receive a TouchCancel
|
|
|
|
QTRY_COMPARE(window.touchEventType, QEvent::TouchCancel);
|
|
|
|
}
|
|
|
|
|
2012-01-13 09:31:11 +00:00
|
|
|
void tst_QWindow::orientation()
|
|
|
|
{
|
2012-02-21 02:00:14 +00:00
|
|
|
qRegisterMetaType<Qt::ScreenOrientation>("Qt::ScreenOrientation");
|
|
|
|
|
2012-01-13 09:31:11 +00:00
|
|
|
QWindow window;
|
2014-07-31 11:48:15 +00:00
|
|
|
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
2012-01-13 09:31:11 +00:00
|
|
|
window.create();
|
|
|
|
|
|
|
|
window.reportContentOrientationChange(Qt::PortraitOrientation);
|
|
|
|
QCOMPARE(window.contentOrientation(), Qt::PortraitOrientation);
|
|
|
|
|
|
|
|
window.reportContentOrientationChange(Qt::PrimaryOrientation);
|
2012-01-25 12:41:43 +00:00
|
|
|
QCOMPARE(window.contentOrientation(), Qt::PrimaryOrientation);
|
2012-01-13 09:31:11 +00:00
|
|
|
|
2012-01-25 12:41:43 +00:00
|
|
|
QSignalSpy spy(&window, SIGNAL(contentOrientationChanged(Qt::ScreenOrientation)));
|
|
|
|
window.reportContentOrientationChange(Qt::LandscapeOrientation);
|
|
|
|
QCOMPARE(spy.count(), 1);
|
2012-01-13 09:31:11 +00:00
|
|
|
}
|
|
|
|
|
2012-11-01 16:03:45 +00:00
|
|
|
void tst_QWindow::sizes()
|
|
|
|
{
|
|
|
|
QWindow window;
|
|
|
|
|
|
|
|
QSignalSpy minimumWidthSpy(&window, SIGNAL(minimumWidthChanged(int)));
|
|
|
|
QSignalSpy minimumHeightSpy(&window, SIGNAL(minimumHeightChanged(int)));
|
|
|
|
QSignalSpy maximumWidthSpy(&window, SIGNAL(maximumWidthChanged(int)));
|
|
|
|
QSignalSpy maximumHeightSpy(&window, SIGNAL(maximumHeightChanged(int)));
|
|
|
|
|
|
|
|
QSize oldMaximum = window.maximumSize();
|
|
|
|
|
|
|
|
window.setMinimumWidth(10);
|
|
|
|
QCOMPARE(window.minimumWidth(), 10);
|
|
|
|
QCOMPARE(window.minimumHeight(), 0);
|
|
|
|
QCOMPARE(window.minimumSize(), QSize(10, 0));
|
|
|
|
QCOMPARE(window.maximumSize(), oldMaximum);
|
|
|
|
QCOMPARE(minimumWidthSpy.count(), 1);
|
|
|
|
QCOMPARE(minimumHeightSpy.count(), 0);
|
|
|
|
QCOMPARE(maximumWidthSpy.count(), 0);
|
|
|
|
QCOMPARE(maximumHeightSpy.count(), 0);
|
|
|
|
|
|
|
|
window.setMinimumHeight(10);
|
|
|
|
QCOMPARE(window.minimumWidth(), 10);
|
|
|
|
QCOMPARE(window.minimumHeight(), 10);
|
|
|
|
QCOMPARE(window.minimumSize(), QSize(10, 10));
|
|
|
|
QCOMPARE(window.maximumSize(), oldMaximum);
|
|
|
|
QCOMPARE(minimumWidthSpy.count(), 1);
|
|
|
|
QCOMPARE(minimumHeightSpy.count(), 1);
|
|
|
|
QCOMPARE(maximumWidthSpy.count(), 0);
|
|
|
|
QCOMPARE(maximumHeightSpy.count(), 0);
|
|
|
|
|
|
|
|
window.setMaximumWidth(100);
|
|
|
|
QCOMPARE(window.maximumWidth(), 100);
|
|
|
|
QCOMPARE(window.maximumHeight(), oldMaximum.height());
|
|
|
|
QCOMPARE(window.minimumSize(), QSize(10, 10));
|
|
|
|
QCOMPARE(window.maximumSize(), QSize(100, oldMaximum.height()));
|
|
|
|
QCOMPARE(minimumWidthSpy.count(), 1);
|
|
|
|
QCOMPARE(minimumHeightSpy.count(), 1);
|
|
|
|
QCOMPARE(maximumWidthSpy.count(), 1);
|
|
|
|
QCOMPARE(maximumHeightSpy.count(), 0);
|
|
|
|
|
|
|
|
window.setMaximumHeight(100);
|
|
|
|
QCOMPARE(window.maximumWidth(), 100);
|
|
|
|
QCOMPARE(window.maximumHeight(), 100);
|
|
|
|
QCOMPARE(window.minimumSize(), QSize(10, 10));
|
|
|
|
QCOMPARE(window.maximumSize(), QSize(100, 100));
|
|
|
|
QCOMPARE(minimumWidthSpy.count(), 1);
|
|
|
|
QCOMPARE(minimumHeightSpy.count(), 1);
|
|
|
|
QCOMPARE(maximumWidthSpy.count(), 1);
|
|
|
|
QCOMPARE(maximumHeightSpy.count(), 1);
|
|
|
|
}
|
|
|
|
|
2012-01-20 12:08:42 +00:00
|
|
|
void tst_QWindow::close()
|
|
|
|
{
|
|
|
|
QWindow a;
|
|
|
|
QWindow b;
|
|
|
|
QWindow c(&a);
|
|
|
|
|
|
|
|
a.show();
|
|
|
|
b.show();
|
|
|
|
|
|
|
|
// we can not close a non top level window
|
|
|
|
QVERIFY(!c.close());
|
|
|
|
QVERIFY(a.close());
|
|
|
|
QVERIFY(b.close());
|
|
|
|
}
|
|
|
|
|
2012-02-24 17:05:06 +00:00
|
|
|
void tst_QWindow::activateAndClose()
|
|
|
|
{
|
2015-09-24 07:25:25 +00:00
|
|
|
if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
|
2014-08-21 11:23:25 +00:00
|
|
|
QSKIP("Wayland: This fails. Figure out why.");
|
|
|
|
|
2012-02-24 17:05:06 +00:00
|
|
|
for (int i = 0; i < 10; ++i) {
|
|
|
|
QWindow window;
|
2014-03-18 16:18:04 +00:00
|
|
|
#if defined(Q_OS_QNX)
|
|
|
|
window.setSurfaceType(QSurface::OpenGLSurface);
|
|
|
|
#endif
|
2013-11-15 18:25:54 +00:00
|
|
|
// qWaitForWindowActive will block for the duration of
|
|
|
|
// of the timeout if the window is at 0,0
|
|
|
|
window.setGeometry(QGuiApplication::primaryScreen()->availableGeometry().adjusted(1, 1, -1, -1));
|
|
|
|
window.showNormal();
|
2014-03-18 16:18:04 +00:00
|
|
|
#if defined(Q_OS_QNX) // We either need to create a eglSurface or a create a backing store
|
|
|
|
// and then post the window in order for screen to show the window
|
|
|
|
QTest::qWaitForWindowExposed(&window);
|
|
|
|
QOpenGLContext context;
|
|
|
|
context.create();
|
|
|
|
context.makeCurrent(&window);
|
|
|
|
context.swapBuffers(&window);
|
|
|
|
#endif
|
Rename all QWindow properties that have "window" in them
windowTitle, windowModality, windowIcon and so on are named that way
to be similar to the ones in QWidget. However QQuickWindow inherits
all of the declared properties, and we would like to have shorter
property names in QML. If you are working with a Window then it's
obvious the title property is the window title. Unfortunately,
there must be patches in many other modules which depend on this one.
In order to avoid the need to merge them all at the same time,
there is also patch https://codereview.qt-project.org/#change,39001
which temporarily adds backwards-compatible accessors, which can be
removed after the other modules are able to build without them.
We should not rename windowState to state, because in QML, state
usually drives the state machine for animation transitions etc.
(although QWindow is not an Item, a user might get confused about it).
Related patches are
https://codereview.qt-project.org/#change,39001
https://codereview.qt-project.org/#change,37764
https://codereview.qt-project.org/#change,37765
https://codereview.qt-project.org/#change,37766
https://codereview.qt-project.org/#change,37762
Change-Id: Ie4424ec15fbdef6b29b137f90a2ae33f173edd21
Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
2012-10-22 10:47:34 +00:00
|
|
|
window.requestActivate();
|
2012-07-20 10:49:12 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&window));
|
|
|
|
QCOMPARE(qGuiApp->focusWindow(), &window);
|
2012-02-24 17:05:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-24 08:48:12 +00:00
|
|
|
void tst_QWindow::mouseEventSequence()
|
|
|
|
{
|
|
|
|
int doubleClickInterval = qGuiApp->styleHints()->mouseDoubleClickInterval();
|
|
|
|
|
|
|
|
InputTestWindow window;
|
2014-07-31 11:48:15 +00:00
|
|
|
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
2012-03-24 08:48:12 +00:00
|
|
|
window.show();
|
2012-07-20 10:49:12 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&window));
|
2012-03-24 08:48:12 +00:00
|
|
|
|
|
|
|
ulong timestamp = 0;
|
|
|
|
QPointF local(12, 34);
|
2015-06-18 15:01:01 +00:00
|
|
|
const QPointF deviceLocal = QHighDpi::toNativePixels(local, &window);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, deviceLocal, deviceLocal, Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, deviceLocal, deviceLocal, Qt::NoButton);
|
2012-03-24 08:48:12 +00:00
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QCOMPARE(window.mousePressedCount, 1);
|
|
|
|
QCOMPARE(window.mouseReleasedCount, 1);
|
|
|
|
QCOMPARE(window.mouseDoubleClickedCount, 0);
|
|
|
|
QCOMPARE(window.mouseSequenceSignature, QLatin1String("pr"));
|
|
|
|
|
|
|
|
window.resetCounters();
|
|
|
|
timestamp += doubleClickInterval;
|
|
|
|
|
|
|
|
// A double click must result in press, release, press, doubleclick, release.
|
|
|
|
// Check that no unexpected event suppression occurs and that the order is correct.
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QCOMPARE(window.mousePressedCount, 2);
|
|
|
|
QCOMPARE(window.mouseReleasedCount, 2);
|
|
|
|
QCOMPARE(window.mouseDoubleClickedCount, 1);
|
|
|
|
QCOMPARE(window.mouseSequenceSignature, QLatin1String("prpdr"));
|
|
|
|
|
|
|
|
timestamp += doubleClickInterval;
|
|
|
|
window.resetCounters();
|
|
|
|
|
|
|
|
// Triple click = double + single click
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QCOMPARE(window.mousePressedCount, 3);
|
|
|
|
QCOMPARE(window.mouseReleasedCount, 3);
|
|
|
|
QCOMPARE(window.mouseDoubleClickedCount, 1);
|
|
|
|
QCOMPARE(window.mouseSequenceSignature, QLatin1String("prpdrpr"));
|
|
|
|
|
|
|
|
timestamp += doubleClickInterval;
|
|
|
|
window.resetCounters();
|
|
|
|
|
|
|
|
// Two double clicks.
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QCOMPARE(window.mousePressedCount, 4);
|
|
|
|
QCOMPARE(window.mouseReleasedCount, 4);
|
|
|
|
QCOMPARE(window.mouseDoubleClickedCount, 2);
|
|
|
|
QCOMPARE(window.mouseSequenceSignature, QLatin1String("prpdrprpdr"));
|
|
|
|
|
|
|
|
timestamp += doubleClickInterval;
|
|
|
|
window.resetCounters();
|
|
|
|
|
|
|
|
// Four clicks, none of which qualifies as a double click.
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton);
|
|
|
|
timestamp += doubleClickInterval;
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton);
|
|
|
|
timestamp += doubleClickInterval;
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton);
|
|
|
|
timestamp += doubleClickInterval;
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton);
|
|
|
|
timestamp += doubleClickInterval;
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QCOMPARE(window.mousePressedCount, 4);
|
|
|
|
QCOMPARE(window.mouseReleasedCount, 4);
|
|
|
|
QCOMPARE(window.mouseDoubleClickedCount, 0);
|
|
|
|
QCOMPARE(window.mouseSequenceSignature, QLatin1String("prprprpr"));
|
|
|
|
}
|
|
|
|
|
2012-04-04 10:11:40 +00:00
|
|
|
void tst_QWindow::windowModality()
|
|
|
|
{
|
|
|
|
qRegisterMetaType<Qt::WindowModality>("Qt::WindowModality");
|
|
|
|
|
|
|
|
QWindow window;
|
Rename all QWindow properties that have "window" in them
windowTitle, windowModality, windowIcon and so on are named that way
to be similar to the ones in QWidget. However QQuickWindow inherits
all of the declared properties, and we would like to have shorter
property names in QML. If you are working with a Window then it's
obvious the title property is the window title. Unfortunately,
there must be patches in many other modules which depend on this one.
In order to avoid the need to merge them all at the same time,
there is also patch https://codereview.qt-project.org/#change,39001
which temporarily adds backwards-compatible accessors, which can be
removed after the other modules are able to build without them.
We should not rename windowState to state, because in QML, state
usually drives the state machine for animation transitions etc.
(although QWindow is not an Item, a user might get confused about it).
Related patches are
https://codereview.qt-project.org/#change,39001
https://codereview.qt-project.org/#change,37764
https://codereview.qt-project.org/#change,37765
https://codereview.qt-project.org/#change,37766
https://codereview.qt-project.org/#change,37762
Change-Id: Ie4424ec15fbdef6b29b137f90a2ae33f173edd21
Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
2012-10-22 10:47:34 +00:00
|
|
|
QSignalSpy spy(&window, SIGNAL(modalityChanged(Qt::WindowModality)));
|
2012-04-04 10:11:40 +00:00
|
|
|
|
Rename all QWindow properties that have "window" in them
windowTitle, windowModality, windowIcon and so on are named that way
to be similar to the ones in QWidget. However QQuickWindow inherits
all of the declared properties, and we would like to have shorter
property names in QML. If you are working with a Window then it's
obvious the title property is the window title. Unfortunately,
there must be patches in many other modules which depend on this one.
In order to avoid the need to merge them all at the same time,
there is also patch https://codereview.qt-project.org/#change,39001
which temporarily adds backwards-compatible accessors, which can be
removed after the other modules are able to build without them.
We should not rename windowState to state, because in QML, state
usually drives the state machine for animation transitions etc.
(although QWindow is not an Item, a user might get confused about it).
Related patches are
https://codereview.qt-project.org/#change,39001
https://codereview.qt-project.org/#change,37764
https://codereview.qt-project.org/#change,37765
https://codereview.qt-project.org/#change,37766
https://codereview.qt-project.org/#change,37762
Change-Id: Ie4424ec15fbdef6b29b137f90a2ae33f173edd21
Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
2012-10-22 10:47:34 +00:00
|
|
|
QCOMPARE(window.modality(), Qt::NonModal);
|
|
|
|
window.setModality(Qt::NonModal);
|
|
|
|
QCOMPARE(window.modality(), Qt::NonModal);
|
2012-04-04 10:11:40 +00:00
|
|
|
QCOMPARE(spy.count(), 0);
|
|
|
|
|
Rename all QWindow properties that have "window" in them
windowTitle, windowModality, windowIcon and so on are named that way
to be similar to the ones in QWidget. However QQuickWindow inherits
all of the declared properties, and we would like to have shorter
property names in QML. If you are working with a Window then it's
obvious the title property is the window title. Unfortunately,
there must be patches in many other modules which depend on this one.
In order to avoid the need to merge them all at the same time,
there is also patch https://codereview.qt-project.org/#change,39001
which temporarily adds backwards-compatible accessors, which can be
removed after the other modules are able to build without them.
We should not rename windowState to state, because in QML, state
usually drives the state machine for animation transitions etc.
(although QWindow is not an Item, a user might get confused about it).
Related patches are
https://codereview.qt-project.org/#change,39001
https://codereview.qt-project.org/#change,37764
https://codereview.qt-project.org/#change,37765
https://codereview.qt-project.org/#change,37766
https://codereview.qt-project.org/#change,37762
Change-Id: Ie4424ec15fbdef6b29b137f90a2ae33f173edd21
Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
2012-10-22 10:47:34 +00:00
|
|
|
window.setModality(Qt::WindowModal);
|
|
|
|
QCOMPARE(window.modality(), Qt::WindowModal);
|
2012-04-04 10:11:40 +00:00
|
|
|
QCOMPARE(spy.count(), 1);
|
Rename all QWindow properties that have "window" in them
windowTitle, windowModality, windowIcon and so on are named that way
to be similar to the ones in QWidget. However QQuickWindow inherits
all of the declared properties, and we would like to have shorter
property names in QML. If you are working with a Window then it's
obvious the title property is the window title. Unfortunately,
there must be patches in many other modules which depend on this one.
In order to avoid the need to merge them all at the same time,
there is also patch https://codereview.qt-project.org/#change,39001
which temporarily adds backwards-compatible accessors, which can be
removed after the other modules are able to build without them.
We should not rename windowState to state, because in QML, state
usually drives the state machine for animation transitions etc.
(although QWindow is not an Item, a user might get confused about it).
Related patches are
https://codereview.qt-project.org/#change,39001
https://codereview.qt-project.org/#change,37764
https://codereview.qt-project.org/#change,37765
https://codereview.qt-project.org/#change,37766
https://codereview.qt-project.org/#change,37762
Change-Id: Ie4424ec15fbdef6b29b137f90a2ae33f173edd21
Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
2012-10-22 10:47:34 +00:00
|
|
|
window.setModality(Qt::WindowModal);
|
|
|
|
QCOMPARE(window.modality(), Qt::WindowModal);
|
2012-04-04 10:11:40 +00:00
|
|
|
QCOMPARE(spy.count(), 1);
|
|
|
|
|
Rename all QWindow properties that have "window" in them
windowTitle, windowModality, windowIcon and so on are named that way
to be similar to the ones in QWidget. However QQuickWindow inherits
all of the declared properties, and we would like to have shorter
property names in QML. If you are working with a Window then it's
obvious the title property is the window title. Unfortunately,
there must be patches in many other modules which depend on this one.
In order to avoid the need to merge them all at the same time,
there is also patch https://codereview.qt-project.org/#change,39001
which temporarily adds backwards-compatible accessors, which can be
removed after the other modules are able to build without them.
We should not rename windowState to state, because in QML, state
usually drives the state machine for animation transitions etc.
(although QWindow is not an Item, a user might get confused about it).
Related patches are
https://codereview.qt-project.org/#change,39001
https://codereview.qt-project.org/#change,37764
https://codereview.qt-project.org/#change,37765
https://codereview.qt-project.org/#change,37766
https://codereview.qt-project.org/#change,37762
Change-Id: Ie4424ec15fbdef6b29b137f90a2ae33f173edd21
Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
2012-10-22 10:47:34 +00:00
|
|
|
window.setModality(Qt::ApplicationModal);
|
|
|
|
QCOMPARE(window.modality(), Qt::ApplicationModal);
|
2012-04-04 10:11:40 +00:00
|
|
|
QCOMPARE(spy.count(), 2);
|
Rename all QWindow properties that have "window" in them
windowTitle, windowModality, windowIcon and so on are named that way
to be similar to the ones in QWidget. However QQuickWindow inherits
all of the declared properties, and we would like to have shorter
property names in QML. If you are working with a Window then it's
obvious the title property is the window title. Unfortunately,
there must be patches in many other modules which depend on this one.
In order to avoid the need to merge them all at the same time,
there is also patch https://codereview.qt-project.org/#change,39001
which temporarily adds backwards-compatible accessors, which can be
removed after the other modules are able to build without them.
We should not rename windowState to state, because in QML, state
usually drives the state machine for animation transitions etc.
(although QWindow is not an Item, a user might get confused about it).
Related patches are
https://codereview.qt-project.org/#change,39001
https://codereview.qt-project.org/#change,37764
https://codereview.qt-project.org/#change,37765
https://codereview.qt-project.org/#change,37766
https://codereview.qt-project.org/#change,37762
Change-Id: Ie4424ec15fbdef6b29b137f90a2ae33f173edd21
Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
2012-10-22 10:47:34 +00:00
|
|
|
window.setModality(Qt::ApplicationModal);
|
|
|
|
QCOMPARE(window.modality(), Qt::ApplicationModal);
|
2012-04-04 10:11:40 +00:00
|
|
|
QCOMPARE(spy.count(), 2);
|
|
|
|
|
Rename all QWindow properties that have "window" in them
windowTitle, windowModality, windowIcon and so on are named that way
to be similar to the ones in QWidget. However QQuickWindow inherits
all of the declared properties, and we would like to have shorter
property names in QML. If you are working with a Window then it's
obvious the title property is the window title. Unfortunately,
there must be patches in many other modules which depend on this one.
In order to avoid the need to merge them all at the same time,
there is also patch https://codereview.qt-project.org/#change,39001
which temporarily adds backwards-compatible accessors, which can be
removed after the other modules are able to build without them.
We should not rename windowState to state, because in QML, state
usually drives the state machine for animation transitions etc.
(although QWindow is not an Item, a user might get confused about it).
Related patches are
https://codereview.qt-project.org/#change,39001
https://codereview.qt-project.org/#change,37764
https://codereview.qt-project.org/#change,37765
https://codereview.qt-project.org/#change,37766
https://codereview.qt-project.org/#change,37762
Change-Id: Ie4424ec15fbdef6b29b137f90a2ae33f173edd21
Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
2012-10-22 10:47:34 +00:00
|
|
|
window.setModality(Qt::NonModal);
|
|
|
|
QCOMPARE(window.modality(), Qt::NonModal);
|
2012-04-04 10:11:40 +00:00
|
|
|
QCOMPARE(spy.count(), 3);
|
|
|
|
}
|
|
|
|
|
2012-04-23 13:18:01 +00:00
|
|
|
void tst_QWindow::inputReentrancy()
|
|
|
|
{
|
|
|
|
InputTestWindow window;
|
|
|
|
window.spinLoopWhenPressed = true;
|
|
|
|
|
2014-07-31 11:48:15 +00:00
|
|
|
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
|
2012-04-23 13:18:01 +00:00
|
|
|
window.show();
|
2012-07-20 10:49:12 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&window));
|
2012-04-23 13:18:01 +00:00
|
|
|
|
|
|
|
// Queue three events.
|
|
|
|
QPointF local(12, 34);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, local, local, Qt::LeftButton);
|
|
|
|
local += QPointF(2, 2);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, local, local, Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&window, local, local, Qt::NoButton);
|
|
|
|
// Process them. However, the event handler for the press will also call
|
|
|
|
// processEvents() so the move and release will be delivered before returning
|
|
|
|
// from mousePressEvent(). The point is that no events should get lost.
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QCOMPARE(window.mousePressButton, int(Qt::LeftButton));
|
|
|
|
QCOMPARE(window.mouseReleaseButton, int(Qt::LeftButton));
|
|
|
|
QCOMPARE(window.mousePressedCount, 1);
|
|
|
|
QCOMPARE(window.mouseMovedCount, 1);
|
|
|
|
QCOMPARE(window.mouseReleasedCount, 1);
|
|
|
|
|
|
|
|
// Now the same for touch.
|
|
|
|
QList<QWindowSystemInterface::TouchPoint> points;
|
|
|
|
QWindowSystemInterface::TouchPoint tp1;
|
|
|
|
tp1.id = 1;
|
|
|
|
tp1.state = Qt::TouchPointPressed;
|
|
|
|
tp1.area = QRectF(10, 10, 4, 4);
|
|
|
|
points << tp1;
|
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
|
|
|
points[0].state = Qt::TouchPointMoved;
|
|
|
|
points[0].area = QRectF(20, 20, 8, 8);
|
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
|
|
|
points[0].state = Qt::TouchPointReleased;
|
|
|
|
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QCOMPARE(window.touchPressedCount, 1);
|
|
|
|
QCOMPARE(window.touchMovedCount, 1);
|
|
|
|
QCOMPARE(window.touchReleasedCount, 1);
|
|
|
|
}
|
|
|
|
|
2012-05-23 12:07:39 +00:00
|
|
|
#ifndef QT_NO_TABLETEVENT
|
|
|
|
class TabletTestWindow : public QWindow
|
|
|
|
{
|
|
|
|
public:
|
2015-07-30 13:15:12 +00:00
|
|
|
TabletTestWindow() : eventType(QEvent::None) { }
|
2012-05-23 12:07:39 +00:00
|
|
|
void tabletEvent(QTabletEvent *ev) {
|
|
|
|
eventType = ev->type();
|
|
|
|
eventGlobal = ev->globalPosF();
|
|
|
|
eventLocal = ev->posF();
|
|
|
|
eventDevice = ev->device();
|
|
|
|
}
|
2015-07-30 13:15:12 +00:00
|
|
|
QEvent::Type eventType;
|
2012-05-23 12:07:39 +00:00
|
|
|
QPointF eventGlobal, eventLocal;
|
|
|
|
int eventDevice;
|
|
|
|
bool eventFilter(QObject *obj, QEvent *ev) {
|
|
|
|
if (ev->type() == QEvent::TabletEnterProximity
|
|
|
|
|| ev->type() == QEvent::TabletLeaveProximity) {
|
|
|
|
eventType = ev->type();
|
|
|
|
QTabletEvent *te = static_cast<QTabletEvent *>(ev);
|
|
|
|
eventDevice = te->device();
|
|
|
|
}
|
|
|
|
return QWindow::eventFilter(obj, ev);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void tst_QWindow::tabletEvents()
|
|
|
|
{
|
|
|
|
#ifndef QT_NO_TABLETEVENT
|
|
|
|
TabletTestWindow window;
|
2014-07-31 11:48:15 +00:00
|
|
|
window.setGeometry(QRect(m_availableTopLeft + QPoint(10, 10), m_testWindowSize));
|
2012-05-23 12:07:39 +00:00
|
|
|
qGuiApp->installEventFilter(&window);
|
|
|
|
|
2015-06-18 15:01:01 +00:00
|
|
|
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);
|
2012-05-23 12:07:39 +00:00
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QTRY_VERIFY(window.eventType == QEvent::TabletPress);
|
|
|
|
QTRY_COMPARE(window.eventGlobal.toPoint(), global);
|
|
|
|
QTRY_COMPARE(window.eventLocal.toPoint(), local);
|
2015-06-18 15:01:01 +00:00
|
|
|
QWindowSystemInterface::handleTabletEvent(&window, false, deviceLocal, deviceGlobal, 1, 2, 0.5, 1, 2, 0.1, 0, 0, 0);
|
2012-05-23 12:07:39 +00:00
|
|
|
QCoreApplication::processEvents();
|
2015-07-30 13:15:12 +00:00
|
|
|
QTRY_COMPARE(window.eventType, QEvent::TabletRelease);
|
2012-05-23 12:07:39 +00:00
|
|
|
|
|
|
|
QWindowSystemInterface::handleTabletEnterProximityEvent(1, 2, 3);
|
|
|
|
QCoreApplication::processEvents();
|
2015-07-30 13:15:12 +00:00
|
|
|
QTRY_COMPARE(window.eventType, QEvent::TabletEnterProximity);
|
2012-05-23 12:07:39 +00:00
|
|
|
QTRY_COMPARE(window.eventDevice, 1);
|
|
|
|
|
|
|
|
QWindowSystemInterface::handleTabletLeaveProximityEvent(1, 2, 3);
|
|
|
|
QCoreApplication::processEvents();
|
2015-07-30 13:15:12 +00:00
|
|
|
QTRY_COMPARE(window.eventType, QEvent::TabletLeaveProximity);
|
2012-05-23 12:07:39 +00:00
|
|
|
QTRY_COMPARE(window.eventDevice, 1);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2012-09-21 10:12:01 +00:00
|
|
|
void tst_QWindow::windowModality_QTBUG27039()
|
|
|
|
{
|
2015-09-24 07:25:25 +00:00
|
|
|
if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
|
2014-08-21 11:23:25 +00:00
|
|
|
QSKIP("Wayland: This fails. Figure out why.");
|
|
|
|
|
2012-09-21 10:12:01 +00:00
|
|
|
QWindow parent;
|
2014-07-31 11:48:15 +00:00
|
|
|
parent.setGeometry(QRect(m_availableTopLeft + QPoint(10, 10), m_testWindowSize));
|
2012-09-21 10:12:01 +00:00
|
|
|
parent.show();
|
|
|
|
|
|
|
|
InputTestWindow modalA;
|
|
|
|
modalA.setTransientParent(&parent);
|
2014-07-31 11:48:15 +00:00
|
|
|
modalA.setGeometry(QRect(m_availableTopLeft + QPoint(20, 10), m_testWindowSize));
|
Rename all QWindow properties that have "window" in them
windowTitle, windowModality, windowIcon and so on are named that way
to be similar to the ones in QWidget. However QQuickWindow inherits
all of the declared properties, and we would like to have shorter
property names in QML. If you are working with a Window then it's
obvious the title property is the window title. Unfortunately,
there must be patches in many other modules which depend on this one.
In order to avoid the need to merge them all at the same time,
there is also patch https://codereview.qt-project.org/#change,39001
which temporarily adds backwards-compatible accessors, which can be
removed after the other modules are able to build without them.
We should not rename windowState to state, because in QML, state
usually drives the state machine for animation transitions etc.
(although QWindow is not an Item, a user might get confused about it).
Related patches are
https://codereview.qt-project.org/#change,39001
https://codereview.qt-project.org/#change,37764
https://codereview.qt-project.org/#change,37765
https://codereview.qt-project.org/#change,37766
https://codereview.qt-project.org/#change,37762
Change-Id: Ie4424ec15fbdef6b29b137f90a2ae33f173edd21
Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
2012-10-22 10:47:34 +00:00
|
|
|
modalA.setModality(Qt::ApplicationModal);
|
2012-09-21 10:12:01 +00:00
|
|
|
modalA.show();
|
|
|
|
|
|
|
|
InputTestWindow modalB;
|
|
|
|
modalB.setTransientParent(&parent);
|
2014-07-31 11:48:15 +00:00
|
|
|
modalA.setGeometry(QRect(m_availableTopLeft + QPoint(30, 10), m_testWindowSize));
|
Rename all QWindow properties that have "window" in them
windowTitle, windowModality, windowIcon and so on are named that way
to be similar to the ones in QWidget. However QQuickWindow inherits
all of the declared properties, and we would like to have shorter
property names in QML. If you are working with a Window then it's
obvious the title property is the window title. Unfortunately,
there must be patches in many other modules which depend on this one.
In order to avoid the need to merge them all at the same time,
there is also patch https://codereview.qt-project.org/#change,39001
which temporarily adds backwards-compatible accessors, which can be
removed after the other modules are able to build without them.
We should not rename windowState to state, because in QML, state
usually drives the state machine for animation transitions etc.
(although QWindow is not an Item, a user might get confused about it).
Related patches are
https://codereview.qt-project.org/#change,39001
https://codereview.qt-project.org/#change,37764
https://codereview.qt-project.org/#change,37765
https://codereview.qt-project.org/#change,37766
https://codereview.qt-project.org/#change,37762
Change-Id: Ie4424ec15fbdef6b29b137f90a2ae33f173edd21
Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
2012-10-22 10:47:34 +00:00
|
|
|
modalB.setModality(Qt::ApplicationModal);
|
2012-09-21 10:12:01 +00:00
|
|
|
modalB.show();
|
|
|
|
|
|
|
|
QPointF local(5, 5);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&modalA, local, local, Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&modalA, local, local, Qt::NoButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&modalB, local, local, Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&modalB, local, local, Qt::NoButton);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
|
|
|
|
// modal A should be blocked since it was shown first, but modal B should not be blocked
|
|
|
|
QCOMPARE(modalB.mousePressedCount, 1);
|
|
|
|
QCOMPARE(modalA.mousePressedCount, 0);
|
|
|
|
|
|
|
|
modalB.hide();
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&modalA, local, local, Qt::LeftButton);
|
|
|
|
QWindowSystemInterface::handleMouseEvent(&modalA, local, local, Qt::NoButton);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
|
|
|
|
// modal B has been hidden, modal A should be unblocked again
|
|
|
|
QCOMPARE(modalA.mousePressedCount, 1);
|
|
|
|
}
|
|
|
|
|
2013-02-08 09:49:52 +00:00
|
|
|
void tst_QWindow::visibility()
|
|
|
|
{
|
|
|
|
qRegisterMetaType<Qt::WindowModality>("QWindow::Visibility");
|
|
|
|
|
|
|
|
QWindow window;
|
|
|
|
QSignalSpy spy(&window, SIGNAL(visibilityChanged(QWindow::Visibility)));
|
|
|
|
|
|
|
|
window.setVisibility(QWindow::AutomaticVisibility);
|
|
|
|
QVERIFY(window.isVisible());
|
|
|
|
QVERIFY(window.visibility() != QWindow::Hidden);
|
|
|
|
QVERIFY(window.visibility() != QWindow::AutomaticVisibility);
|
|
|
|
QCOMPARE(spy.count(), 1);
|
|
|
|
spy.clear();
|
|
|
|
|
|
|
|
window.setVisibility(QWindow::Hidden);
|
|
|
|
QVERIFY(!window.isVisible());
|
|
|
|
QCOMPARE(window.visibility(), QWindow::Hidden);
|
|
|
|
QCOMPARE(spy.count(), 1);
|
|
|
|
spy.clear();
|
|
|
|
|
|
|
|
window.setVisibility(QWindow::FullScreen);
|
|
|
|
QVERIFY(window.isVisible());
|
|
|
|
QCOMPARE(window.windowState(), Qt::WindowFullScreen);
|
|
|
|
QCOMPARE(window.visibility(), QWindow::FullScreen);
|
|
|
|
QCOMPARE(spy.count(), 1);
|
|
|
|
spy.clear();
|
|
|
|
|
|
|
|
window.setWindowState(Qt::WindowNoState);
|
|
|
|
QCOMPARE(window.visibility(), QWindow::Windowed);
|
|
|
|
QCOMPARE(spy.count(), 1);
|
|
|
|
spy.clear();
|
|
|
|
|
|
|
|
window.setVisible(false);
|
|
|
|
QCOMPARE(window.visibility(), QWindow::Hidden);
|
|
|
|
QCOMPARE(spy.count(), 1);
|
|
|
|
spy.clear();
|
|
|
|
}
|
|
|
|
|
2013-02-25 07:54:30 +00:00
|
|
|
void tst_QWindow::mask()
|
|
|
|
{
|
|
|
|
QRegion mask = QRect(10, 10, 800 - 20, 600 - 20);
|
|
|
|
|
|
|
|
QWindow window;
|
|
|
|
window.resize(800, 600);
|
|
|
|
window.setMask(mask);
|
|
|
|
|
|
|
|
QCOMPARE(window.mask(), QRegion());
|
|
|
|
|
|
|
|
window.create();
|
|
|
|
window.setMask(mask);
|
|
|
|
|
|
|
|
QCOMPARE(window.mask(), mask);
|
|
|
|
}
|
|
|
|
|
2014-01-09 11:45:14 +00:00
|
|
|
void tst_QWindow::initialSize()
|
|
|
|
{
|
2015-09-24 07:25:25 +00:00
|
|
|
if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
|
2014-08-21 11:23:25 +00:00
|
|
|
QSKIP("Wayland: This fails. Figure out why.");
|
|
|
|
|
2014-01-09 11:45:14 +00:00
|
|
|
QSize defaultSize(0,0);
|
|
|
|
{
|
|
|
|
Window w;
|
2015-03-10 13:41:30 +00:00
|
|
|
w.showNormal();
|
2014-01-09 11:45:14 +00:00
|
|
|
QTRY_VERIFY(w.width() > 0);
|
|
|
|
QTRY_VERIFY(w.height() > 0);
|
|
|
|
defaultSize = QSize(w.width(), w.height());
|
|
|
|
}
|
|
|
|
{
|
|
|
|
Window w;
|
2014-07-31 11:48:15 +00:00
|
|
|
w.setWidth(m_testWindowSize.width());
|
2015-03-10 13:41:30 +00:00
|
|
|
w.showNormal();
|
2014-07-31 11:48:15 +00:00
|
|
|
QTRY_COMPARE(w.width(), m_testWindowSize.width());
|
2014-01-09 11:45:14 +00:00
|
|
|
QTRY_VERIFY(w.height() > 0);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
Window w;
|
2014-07-31 11:48:15 +00:00
|
|
|
const QSize testSize(m_testWindowSize.width(), 42);
|
|
|
|
w.resize(testSize);
|
2015-03-10 13:41:30 +00:00
|
|
|
w.showNormal();
|
2014-07-31 11:48:15 +00:00
|
|
|
|
|
|
|
const QSize expectedSize = testSize;
|
|
|
|
QTRY_COMPARE(w.size(), expectedSize);
|
2014-01-09 11:45:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-03 11:11:59 +00:00
|
|
|
void tst_QWindow::modalDialog()
|
|
|
|
{
|
2015-09-24 07:25:25 +00:00
|
|
|
if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
|
2014-08-21 11:23:25 +00:00
|
|
|
QSKIP("Wayland: This fails. Figure out why.");
|
|
|
|
|
2014-04-03 11:11:59 +00:00
|
|
|
QWindow normalWindow;
|
2014-07-31 11:48:15 +00:00
|
|
|
normalWindow.setFramePosition(m_availableTopLeft + QPoint(80, 80));
|
|
|
|
normalWindow.resize(m_testWindowSize);
|
2014-04-03 11:11:59 +00:00
|
|
|
normalWindow.show();
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&normalWindow));
|
|
|
|
|
|
|
|
QWindow dialog;
|
2014-07-31 11:48:15 +00:00
|
|
|
dialog.setFramePosition(m_availableTopLeft + QPoint(200, 200));
|
|
|
|
dialog.resize(m_testWindowSize);
|
2014-04-03 11:11:59 +00:00
|
|
|
dialog.setModality(Qt::ApplicationModal);
|
|
|
|
dialog.setFlags(Qt::Dialog);
|
|
|
|
dialog.show();
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&dialog));
|
|
|
|
|
|
|
|
normalWindow.requestActivate();
|
|
|
|
|
|
|
|
QGuiApplication::sync();
|
|
|
|
QGuiApplication::processEvents();
|
|
|
|
QTRY_COMPARE(QGuiApplication::focusWindow(), &dialog);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QWindow::modalDialogClosingOneOfTwoModal()
|
|
|
|
{
|
2015-09-24 07:25:25 +00:00
|
|
|
if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
|
2014-08-21 11:23:25 +00:00
|
|
|
QSKIP("Wayland: This fails. Figure out why.");
|
|
|
|
|
2014-04-03 11:11:59 +00:00
|
|
|
QWindow normalWindow;
|
2014-07-31 11:48:15 +00:00
|
|
|
normalWindow.setFramePosition(m_availableTopLeft + QPoint(80, 80));
|
|
|
|
normalWindow.resize(m_testWindowSize);
|
2014-04-03 11:11:59 +00:00
|
|
|
normalWindow.show();
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&normalWindow));
|
|
|
|
|
|
|
|
QWindow first_dialog;
|
2014-07-31 11:48:15 +00:00
|
|
|
first_dialog.setFramePosition(m_availableTopLeft + QPoint(200, 200));
|
|
|
|
first_dialog.resize(m_testWindowSize);
|
2014-04-03 11:11:59 +00:00
|
|
|
first_dialog.setModality(Qt::ApplicationModal);
|
|
|
|
first_dialog.setFlags(Qt::Dialog);
|
|
|
|
first_dialog.show();
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&first_dialog));
|
|
|
|
|
|
|
|
{
|
|
|
|
QWindow second_dialog;
|
2014-07-31 11:48:15 +00:00
|
|
|
second_dialog.setFramePosition(m_availableTopLeft + QPoint(300, 300));
|
|
|
|
second_dialog.resize(m_testWindowSize);
|
2014-04-03 11:11:59 +00:00
|
|
|
second_dialog.setModality(Qt::ApplicationModal);
|
|
|
|
second_dialog.setFlags(Qt::Dialog);
|
|
|
|
second_dialog.show();
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&second_dialog));
|
|
|
|
|
|
|
|
QTRY_COMPARE(QGuiApplication::focusWindow(), &second_dialog);
|
|
|
|
|
|
|
|
second_dialog.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
QGuiApplication::sync();
|
|
|
|
QGuiApplication::processEvents();
|
|
|
|
QTRY_COMPARE(QGuiApplication::focusWindow(), &first_dialog);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QWindow::modalWithChildWindow()
|
|
|
|
{
|
2015-09-24 07:25:25 +00:00
|
|
|
if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
|
2014-08-21 11:23:25 +00:00
|
|
|
QSKIP("Wayland: This fails. Figure out why.");
|
|
|
|
|
2014-04-03 11:11:59 +00:00
|
|
|
QWindow normalWindow;
|
2014-07-31 11:48:15 +00:00
|
|
|
normalWindow.setFramePosition(m_availableTopLeft + QPoint(80, 80));
|
|
|
|
normalWindow.resize(m_testWindowSize);
|
2014-04-03 11:11:59 +00:00
|
|
|
normalWindow.show();
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&normalWindow));
|
|
|
|
|
|
|
|
QWindow tlw_dialog;
|
2014-07-31 11:48:15 +00:00
|
|
|
tlw_dialog.setFramePosition(m_availableTopLeft + QPoint(200, 200));
|
|
|
|
tlw_dialog.resize(m_testWindowSize);
|
2014-04-03 11:11:59 +00:00
|
|
|
tlw_dialog.setModality(Qt::ApplicationModal);
|
|
|
|
tlw_dialog.setFlags(Qt::Dialog);
|
|
|
|
tlw_dialog.create();
|
|
|
|
|
|
|
|
QWindow sub_window(&tlw_dialog);
|
|
|
|
sub_window.resize(200,300);
|
|
|
|
sub_window.show();
|
|
|
|
|
|
|
|
tlw_dialog.show();
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&tlw_dialog));
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&sub_window));
|
|
|
|
|
|
|
|
QTRY_COMPARE(QGuiApplication::focusWindow(), &tlw_dialog);
|
|
|
|
|
|
|
|
sub_window.requestActivate();
|
|
|
|
QGuiApplication::sync();
|
|
|
|
QGuiApplication::processEvents();
|
|
|
|
QTRY_COMPARE(QGuiApplication::focusWindow(), &sub_window);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QWindow::modalWindowModallity()
|
|
|
|
{
|
2015-09-24 07:25:25 +00:00
|
|
|
if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
|
2014-08-21 11:23:25 +00:00
|
|
|
QSKIP("Wayland: This fails. Figure out why.");
|
|
|
|
|
2014-04-03 11:11:59 +00:00
|
|
|
QWindow normal_window;
|
2014-07-31 11:48:15 +00:00
|
|
|
normal_window.setFramePosition(m_availableTopLeft + QPoint(80, 80));
|
|
|
|
normal_window.resize(m_testWindowSize);
|
2014-04-03 11:11:59 +00:00
|
|
|
normal_window.show();
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&normal_window));
|
|
|
|
|
|
|
|
QWindow parent_to_modal;
|
2014-07-31 11:48:15 +00:00
|
|
|
parent_to_modal.setFramePosition(normal_window.geometry().topRight() + QPoint(100, 0));
|
|
|
|
parent_to_modal.resize(m_testWindowSize);
|
2014-04-03 11:11:59 +00:00
|
|
|
parent_to_modal.show();
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&parent_to_modal));
|
|
|
|
QTRY_COMPARE(QGuiApplication::focusWindow(), &parent_to_modal);
|
|
|
|
|
|
|
|
QWindow modal_dialog;
|
2014-07-31 11:48:15 +00:00
|
|
|
modal_dialog.resize(m_testWindowSize);
|
|
|
|
modal_dialog.setFramePosition(normal_window.geometry().bottomLeft() + QPoint(0, 100));
|
2014-04-03 11:11:59 +00:00
|
|
|
modal_dialog.setModality(Qt::WindowModal);
|
|
|
|
modal_dialog.setFlags(Qt::Dialog);
|
|
|
|
modal_dialog.setTransientParent(&parent_to_modal);
|
|
|
|
modal_dialog.show();
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&modal_dialog));
|
|
|
|
QTRY_COMPARE(QGuiApplication::focusWindow(), &modal_dialog);
|
|
|
|
|
|
|
|
normal_window.requestActivate();
|
|
|
|
QTRY_COMPARE(QGuiApplication::focusWindow(), &normal_window);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-05-19 17:58:35 +00:00
|
|
|
void tst_QWindow::modalWindowPosition()
|
|
|
|
{
|
|
|
|
QWindow window;
|
2014-07-31 11:48:15 +00:00
|
|
|
window.setGeometry(QRect(m_availableTopLeft + QPoint(100, 100), m_testWindowSize));
|
2014-05-19 17:58:35 +00:00
|
|
|
// Allow for any potential resizing due to constraints
|
|
|
|
QRect origGeo = window.geometry();
|
|
|
|
window.setModality(Qt::WindowModal);
|
|
|
|
window.show();
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&window));
|
|
|
|
QCOMPARE(window.geometry(), origGeo);
|
|
|
|
}
|
|
|
|
|
2016-01-19 21:32:52 +00:00
|
|
|
#ifndef QT_NO_CURSOR
|
|
|
|
void tst_QWindow::modalWindowEnterEventOnHide_QTBUG35109()
|
|
|
|
{
|
|
|
|
if (QGuiApplication::platformName() == QLatin1String("cocoa"))
|
|
|
|
QSKIP("This test fails on OS X on CI");
|
|
|
|
|
|
|
|
const QPoint center = QGuiApplication::primaryScreen()->availableGeometry().center();
|
|
|
|
|
|
|
|
const int childOffset = 16;
|
|
|
|
const QPoint rootPos = center - QPoint(m_testWindowSize.width(),
|
|
|
|
m_testWindowSize.height())/2;
|
|
|
|
const QPoint modalPos = rootPos + QPoint(childOffset * 5,
|
|
|
|
childOffset * 5);
|
|
|
|
const QPoint cursorPos = rootPos - QPoint(80, 80);
|
|
|
|
|
|
|
|
// Test whether tlw can receive the enter event
|
|
|
|
{
|
|
|
|
QCursor::setPos(cursorPos);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
|
|
|
|
InputTestWindow root;
|
|
|
|
root.setTitle(__FUNCTION__);
|
|
|
|
root.setGeometry(QRect(rootPos, m_testWindowSize));
|
|
|
|
root.show();
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&root));
|
|
|
|
root.requestActivate();
|
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&root));
|
|
|
|
|
|
|
|
// Move the mouse over the root window, but not over the modal window.
|
|
|
|
QCursor::setPos(rootPos + QPoint(childOffset * 5 / 2,
|
|
|
|
childOffset * 5 / 2));
|
|
|
|
|
|
|
|
// Wait for the enter event. It must be delivered here, otherwise second
|
|
|
|
// compare can PASS because of this event even after "resetCounters()".
|
|
|
|
QTRY_COMPARE(root.enterEventCount, 1);
|
|
|
|
QTRY_COMPARE(root.leaveEventCount, 0);
|
|
|
|
|
|
|
|
QWindow modal;
|
|
|
|
modal.setTitle(QLatin1String("Modal - ") + __FUNCTION__);
|
|
|
|
modal.setTransientParent(&root);
|
|
|
|
modal.resize(m_testWindowSize/2);
|
|
|
|
modal.setFramePosition(modalPos);
|
|
|
|
modal.setModality(Qt::ApplicationModal);
|
|
|
|
modal.show();
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&modal));
|
|
|
|
modal.requestActivate();
|
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&modal));
|
|
|
|
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QTRY_COMPARE(root.leaveEventCount, 1);
|
|
|
|
|
|
|
|
root.resetCounters();
|
|
|
|
modal.close();
|
|
|
|
|
|
|
|
// Check for the enter event
|
|
|
|
QTRY_COMPARE(root.enterEventCount, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test whether child window can receive the enter event
|
|
|
|
{
|
|
|
|
QCursor::setPos(cursorPos);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
|
|
|
|
QWindow root;
|
|
|
|
root.setTitle(__FUNCTION__);
|
|
|
|
root.setGeometry(QRect(rootPos, m_testWindowSize));
|
|
|
|
|
|
|
|
QWindow childLvl1;
|
|
|
|
childLvl1.setParent(&root);
|
|
|
|
childLvl1.setGeometry(childOffset,
|
|
|
|
childOffset,
|
|
|
|
m_testWindowSize.width() - childOffset,
|
|
|
|
m_testWindowSize.height() - childOffset);
|
|
|
|
|
|
|
|
InputTestWindow childLvl2;
|
|
|
|
childLvl2.setParent(&childLvl1);
|
|
|
|
childLvl2.setGeometry(childOffset,
|
|
|
|
childOffset,
|
|
|
|
childLvl1.width() - childOffset,
|
|
|
|
childLvl1.height() - childOffset);
|
|
|
|
|
|
|
|
root.show();
|
|
|
|
childLvl1.show();
|
|
|
|
childLvl2.show();
|
|
|
|
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&root));
|
|
|
|
root.requestActivate();
|
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&root));
|
|
|
|
QVERIFY(childLvl1.isVisible());
|
|
|
|
QVERIFY(childLvl2.isVisible());
|
|
|
|
|
|
|
|
// Move the mouse over the child window, but not over the modal window.
|
|
|
|
// Be sure that the value is almost left-top of second child window for
|
|
|
|
// checking proper position mapping.
|
|
|
|
QCursor::setPos(rootPos + QPoint(childOffset * 5 / 2,
|
|
|
|
childOffset * 5 / 2));
|
|
|
|
|
|
|
|
// Wait for the enter event. It must be delivered here, otherwise second
|
|
|
|
// compare can PASS because of this event even after "resetCounters()".
|
|
|
|
QTRY_COMPARE(childLvl2.enterEventCount, 1);
|
|
|
|
QTRY_COMPARE(childLvl2.leaveEventCount, 0);
|
|
|
|
|
|
|
|
QWindow modal;
|
|
|
|
modal.setTitle(QLatin1String("Modal - ") + __FUNCTION__);
|
|
|
|
modal.setTransientParent(&root);
|
|
|
|
modal.resize(m_testWindowSize/2);
|
|
|
|
modal.setFramePosition(modalPos);
|
|
|
|
modal.setModality(Qt::ApplicationModal);
|
|
|
|
modal.show();
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&modal));
|
|
|
|
modal.requestActivate();
|
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&modal));
|
|
|
|
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QTRY_COMPARE(childLvl2.leaveEventCount, 1);
|
|
|
|
|
|
|
|
childLvl2.resetCounters();
|
|
|
|
modal.close();
|
|
|
|
|
|
|
|
// Check for the enter event
|
|
|
|
QTRY_COMPARE(childLvl2.enterEventCount, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test whether tlw can receive the enter event if mouse is over the invisible child windnow
|
|
|
|
{
|
|
|
|
QCursor::setPos(cursorPos);
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
|
|
|
|
InputTestWindow root;
|
|
|
|
root.setTitle(__FUNCTION__);
|
|
|
|
root.setGeometry(QRect(rootPos, m_testWindowSize));
|
|
|
|
|
|
|
|
QWindow child;
|
|
|
|
child.setParent(&root);
|
|
|
|
child.setGeometry(QRect(QPoint(), m_testWindowSize));
|
|
|
|
|
|
|
|
root.show();
|
|
|
|
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&root));
|
|
|
|
root.requestActivate();
|
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&root));
|
|
|
|
QVERIFY(!child.isVisible());
|
|
|
|
|
|
|
|
// Move the mouse over the child window, but not over the modal window.
|
|
|
|
QCursor::setPos(rootPos + QPoint(childOffset * 5 / 2,
|
|
|
|
childOffset * 5 / 2));
|
|
|
|
|
|
|
|
// Wait for the enter event. It must be delivered here, otherwise second
|
|
|
|
// compare can PASS because of this event even after "resetCounters()".
|
|
|
|
QTRY_COMPARE(root.enterEventCount, 1);
|
|
|
|
QTRY_COMPARE(root.leaveEventCount, 0);
|
|
|
|
|
|
|
|
QWindow modal;
|
|
|
|
modal.setTitle(QLatin1String("Modal - ") + __FUNCTION__);
|
|
|
|
modal.setTransientParent(&root);
|
|
|
|
modal.resize(m_testWindowSize/2);
|
|
|
|
modal.setFramePosition(modalPos);
|
|
|
|
modal.setModality(Qt::ApplicationModal);
|
|
|
|
modal.show();
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&modal));
|
|
|
|
modal.requestActivate();
|
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&modal));
|
|
|
|
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QTRY_COMPARE(root.leaveEventCount, 1);
|
|
|
|
|
|
|
|
root.resetCounters();
|
|
|
|
modal.close();
|
|
|
|
|
|
|
|
// Check for the enter event
|
|
|
|
QTRY_COMPARE(root.enterEventCount, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-08-28 10:59:14 +00:00
|
|
|
static bool isNativeWindowVisible(const QWindow *window)
|
|
|
|
{
|
|
|
|
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
|
|
|
|
return IsWindowVisible(reinterpret_cast<HWND>(window->winId()));
|
|
|
|
#else
|
|
|
|
Q_UNIMPLEMENTED();
|
|
|
|
return window->isVisible();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QWindow::windowsTransientChildren()
|
|
|
|
{
|
|
|
|
if (QGuiApplication::platformName().compare(QStringLiteral("windows"), Qt::CaseInsensitive))
|
|
|
|
QSKIP("Windows only test");
|
|
|
|
|
|
|
|
ColoredWindow mainWindow(Qt::yellow);
|
|
|
|
mainWindow.setGeometry(QRect(m_availableTopLeft + QPoint(100, 100), m_testWindowSize));
|
|
|
|
mainWindow.setTitle(QStringLiteral("Main"));
|
|
|
|
ColoredWindow child(Qt::blue, &mainWindow);
|
|
|
|
child.setGeometry(QRect(QPoint(0, 0), m_testWindowSize / 2));
|
|
|
|
|
|
|
|
ColoredWindow dialog(Qt::red);
|
|
|
|
dialog.setGeometry(QRect(m_availableTopLeft + QPoint(200, 200), m_testWindowSize));
|
|
|
|
dialog.setTitle(QStringLiteral("Dialog"));
|
|
|
|
dialog.setTransientParent(&mainWindow);
|
|
|
|
|
|
|
|
mainWindow.show();
|
|
|
|
child.show();
|
|
|
|
dialog.show();
|
|
|
|
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&dialog));
|
|
|
|
mainWindow.setWindowState(Qt::WindowMinimized);
|
|
|
|
QVERIFY(!isNativeWindowVisible(&dialog));
|
|
|
|
dialog.hide();
|
|
|
|
mainWindow.setWindowState(Qt::WindowNoState);
|
|
|
|
// QTBUG-40696, transient children hidden by Qt should not be re-shown by Windows.
|
|
|
|
QVERIFY(!isNativeWindowVisible(&dialog));
|
|
|
|
QVERIFY(isNativeWindowVisible(&child)); // Real children should be visible.
|
|
|
|
}
|
|
|
|
|
2015-02-12 14:28:12 +00:00
|
|
|
void tst_QWindow::requestUpdate()
|
|
|
|
{
|
|
|
|
QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize);
|
|
|
|
|
|
|
|
Window window;
|
|
|
|
window.setGeometry(geometry);
|
|
|
|
window.show();
|
|
|
|
QCoreApplication::processEvents();
|
|
|
|
QTRY_VERIFY(window.isExposed());
|
|
|
|
|
2015-07-30 13:15:12 +00:00
|
|
|
QCOMPARE(window.received(QEvent::UpdateRequest), 0);
|
2015-02-12 14:28:12 +00:00
|
|
|
|
|
|
|
window.requestUpdate();
|
2015-07-30 13:15:12 +00:00
|
|
|
QTRY_COMPARE(window.received(QEvent::UpdateRequest), 1);
|
2015-02-12 14:28:12 +00:00
|
|
|
|
|
|
|
window.requestUpdate();
|
2015-07-30 13:15:12 +00:00
|
|
|
QTRY_COMPARE(window.received(QEvent::UpdateRequest), 2);
|
2015-02-12 14:28:12 +00:00
|
|
|
}
|
|
|
|
|
2011-08-29 06:26:37 +00:00
|
|
|
#include <tst_qwindow.moc>
|
2012-03-24 08:48:12 +00:00
|
|
|
QTEST_MAIN(tst_QWindow)
|
2012-09-21 10:12:01 +00:00
|
|
|
|