summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorJohan Klokkhammer Helsing <johan.helsing@qt.io>2018-03-06 13:06:11 +0100
committerJohan Helsing <johan.helsing@qt.io>2018-05-07 11:34:41 +0000
commitc5ab40d2573fde27a14d7c05d8693966c65a400c (patch)
treed93c4647c90b0d72059b9148a6b4ca1d3f7cc272 /tests
parent9db98c7e0a2656988d5c549f0618b2ba882f1fc9 (diff)
Client: Add acked configure support and implement it for xdg-shell v6
The problem: The code in QWaylandWindow::setWindowStateInternal made many assumptions about how the shell surface responded to new window states, and when and if they were applied. Particularly: - The shell integrations support different subsets of Qt::WindowStates, so it doesn't make sense to map from states to setFullscreen, setNormal, etc. in QWaylandWindow because it really depends on the shell integration how it should be handled. - Some states are not supported/unknown on some shells and should immediately be rejected. - On some shells, particularly those where the current state is unknown, flags need to be resent even though they didn't change. - Should handleWindowStatesChanged be called immediately (client decides) or should it wait for a configure event (compositor decides)? I.e. the mState variable only makes sense for some shells. Furthermore, when state changes come from the compositors, some shell integrations require that a configure event is acked by the client and that the next committed buffer's size and content matches that configure event. Previously, we would just ack immediately and still send a buffer with the old size before a correct frame was drawn. i.e. sending incorrect acks, which would lead to protocol errors on some compositors. Additionally, QWaylandWindow::createDecoration() also assumed that windows should have decorations unless they are fullscreen. This is not always the case, particularly on ivi-application and probably on future shell integrations for embedded or tiling window managers etc. The Solution: The responsibility of mapping requested window states to Wayland requests have been moved to the QWaylandShellSurface implementation. QWaylandWindow now calls a new virtual, QWaylandShellSurface::requestWindowStates(Qt::WindowStates), instead of trying to be smart about it. The virtual getters and setters for window states have now been removed from the QWaylandShellSurface interface. It's now also the shell surface implementation's responsibility to call QWaylandWindow::handleWindowStatesChanged if and when it knows a new state is effective. QWaylandWindow::configure has been replaced with QWaylandWindow::applyConfigureWhenPossible(), which causes another new virtual, QWaylandShellSurface::applyConfigure(), to be called whenever we're free to resize and change the states of the next buffer (this is when states should be acked). This means that shells that use acked states need to store the pending states themselves, call applyConfigureWhenPossible(), wait for applyConfigure() to be called, call resizeFromApplyConfigure() and handleWindowStatesChanged(), and finally ack the applied state. Acked state for xdg-shell v5 and v6 has now been implemented, which also means we've now: [ChangeLog][QPA plugin] Implemented support for maximizing, minimizing, and setting fullscreen with xdg-shell unstable v6. [ChangeLog][QPA plugin] QWindow::isActive now follows configure events on xdg-shell unstable v6 (like v5). QWaylandWindow::createDecoration queries QWaylandShellSurface::wantsDecoration before creating window decorations, instead of using the previously unreliable QWaylandWindow::isFullscreen(). [ChangeLog][QPA plugin] Window decorations are now automatically disabled for ivi-application. The refactor also removes a couple of hacks: - QWindowSystemInterface::flushWindowSystemEvents() was called in QWaylandWindow::setWindowStates. Since this hack was introduced, the events now have oldState and newState members, and their values seem to make sense (ensured in the tests). - The hack for unminimizing on xdg-shell v5 in QWaylandWindow::createDecoration was not needed anymore. Finally, tests have been added for xdg-shell v6 to ensure that the right Wayland requests are sent, that we respond to configure events from the compositor, and that the Qt events and signals emitted on the client side make sense. Task-number: QTBUG-53702 Task-number: QTBUG-63417 Task-number: QTBUG-63748 Task-number: QTBUG-66928 Change-Id: Ib4c36b69105750f9dbdcc78adcf71e2e994cc70d Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/client/client/tst_client.cpp20
-rw-r--r--tests/auto/client/shared/mockcompositor.cpp5
-rw-r--r--tests/auto/client/shared/mockcompositor.h14
-rw-r--r--tests/auto/client/shared/mockxdgshellv6.cpp35
-rw-r--r--tests/auto/client/shared/mockxdgshellv6.h5
-rw-r--r--tests/auto/client/xdgshellv6/tst_xdgshellv6.cpp189
6 files changed, 261 insertions, 7 deletions
diff --git a/tests/auto/client/client/tst_client.cpp b/tests/auto/client/client/tst_client.cpp
index 05b8bac1a..7a7c7fa85 100644
--- a/tests/auto/client/client/tst_client.cpp
+++ b/tests/auto/client/client/tst_client.cpp
@@ -172,6 +172,7 @@ private slots:
void windowScreens();
void removePrimaryScreen();
void createDestroyWindow();
+ void activeWindowFollowsKeyboardFocus();
void events();
void backingStore();
void touchDrag();
@@ -313,7 +314,7 @@ void tst_WaylandClient::createDestroyWindow()
QTRY_VERIFY(!compositor->surface());
}
-void tst_WaylandClient::events()
+void tst_WaylandClient::activeWindowFollowsKeyboardFocus()
{
TestWindow window;
window.show();
@@ -324,6 +325,9 @@ void tst_WaylandClient::events()
QTRY_VERIFY(window.isExposed());
+ if (compositor->xdgToplevelV6())
+ QSKIP("On xdg-shell v6 focus is handled by configure events");
+
QCOMPARE(window.focusInEventCount, 0);
compositor->setKeyboardFocus(surface);
QTRY_COMPARE(window.focusInEventCount, 1);
@@ -333,9 +337,21 @@ void tst_WaylandClient::events()
compositor->setKeyboardFocus(QSharedPointer<MockSurface>(nullptr));
QTRY_COMPARE(window.focusOutEventCount, 1);
QTRY_COMPARE(QGuiApplication::focusWindow(), static_cast<QWindow *>(nullptr));
+}
+
+void tst_WaylandClient::events()
+{
+ TestWindow window;
+ window.show();
+
+ QSharedPointer<MockSurface> surface;
+ QTRY_VERIFY(surface = compositor->surface());
+ compositor->sendShellSurfaceConfigure(surface);
+
+ QTRY_VERIFY(window.isExposed());
compositor->setKeyboardFocus(surface);
- QTRY_COMPARE(window.focusInEventCount, 2);
+ QTRY_COMPARE(window.focusInEventCount, 1);
QTRY_COMPARE(QGuiApplication::focusWindow(), &window);
uint keyCode = 80; // arbitrarily chosen
diff --git a/tests/auto/client/shared/mockcompositor.cpp b/tests/auto/client/shared/mockcompositor.cpp
index 9ef08ad95..11b40d9fc 100644
--- a/tests/auto/client/shared/mockcompositor.cpp
+++ b/tests/auto/client/shared/mockcompositor.cpp
@@ -236,11 +236,14 @@ void MockCompositor::sendIviSurfaceConfigure(const QSharedPointer<MockIviSurface
processCommand(command);
}
-void MockCompositor::sendXdgToplevelV6Configure(const QSharedPointer<MockXdgToplevelV6> toplevel, const QSize &size)
+void MockCompositor::sendXdgToplevelV6Configure(const QSharedPointer<MockXdgToplevelV6> toplevel, const QSize &size, const QVector<uint> &states)
{
Command command = makeCommand(Impl::Compositor::sendXdgToplevelV6Configure, m_compositor);
command.parameters << QVariant::fromValue(toplevel);
command.parameters << QVariant::fromValue(size);
+ auto statesBytes = QByteArray::fromRawData(reinterpret_cast<const char *>(states.data()),
+ states.size() * static_cast<int>(sizeof(uint)));
+ command.parameters << statesBytes;
processCommand(command);
}
diff --git a/tests/auto/client/shared/mockcompositor.h b/tests/auto/client/shared/mockcompositor.h
index 34c20943a..d3568c165 100644
--- a/tests/auto/client/shared/mockcompositor.h
+++ b/tests/auto/client/shared/mockcompositor.h
@@ -175,12 +175,21 @@ private:
Q_DECLARE_METATYPE(QSharedPointer<MockIviSurface>)
-class MockXdgToplevelV6
+class MockXdgToplevelV6 : public QObject
{
+ Q_OBJECT
public:
Impl::XdgToplevelV6 *handle() const { return m_toplevel; }
void sendConfigure(const QSharedPointer<MockXdgToplevelV6> toplevel);
+
+signals:
+ uint setMinimizedRequested();
+ uint setMaximizedRequested();
+ uint unsetMaximizedRequested();
+ uint setFullscreenRequested();
+ uint unsetFullscreenRequested();
+
private:
MockXdgToplevelV6(Impl::XdgToplevelV6 *toplevel) : m_toplevel(toplevel) {}
friend class Impl::Compositor;
@@ -234,7 +243,8 @@ public:
void sendSurfaceLeave(const QSharedPointer<MockSurface> &surface, QSharedPointer<MockOutput> &output);
void sendShellSurfaceConfigure(const QSharedPointer<MockSurface> surface, const QSize &size = QSize(0, 0));
void sendIviSurfaceConfigure(const QSharedPointer<MockIviSurface> iviSurface, const QSize &size);
- void sendXdgToplevelV6Configure(const QSharedPointer<MockXdgToplevelV6> toplevel, const QSize &size = QSize(0, 0));
+ void sendXdgToplevelV6Configure(const QSharedPointer<MockXdgToplevelV6> toplevel, const QSize &size = QSize(0, 0),
+ const QVector<uint> &states = { ZXDG_TOPLEVEL_V6_STATE_ACTIVATED });
void waitForStartDrag();
QSharedPointer<MockSurface> surface();
diff --git a/tests/auto/client/shared/mockxdgshellv6.cpp b/tests/auto/client/shared/mockxdgshellv6.cpp
index 39e03296d..6f6f0b905 100644
--- a/tests/auto/client/shared/mockxdgshellv6.cpp
+++ b/tests/auto/client/shared/mockxdgshellv6.cpp
@@ -39,8 +39,8 @@ void Compositor::sendXdgToplevelV6Configure(void *data, const QList<QVariant> &p
Q_ASSERT(toplevel && toplevel->resource());
QSize size = parameters.at(1).toSize();
Q_ASSERT(size.isValid());
- QByteArray states;
- toplevel->send_configure(size.width(), size.height(), states);
+ auto statesBytes = parameters.at(2).toByteArray();
+ toplevel->send_configure(size.width(), size.height(), statesBytes);
toplevel->xdgSurface()->send_configure(compositor->nextSerial());
}
@@ -87,6 +87,37 @@ void XdgToplevelV6::zxdg_toplevel_v6_destroy(QtWaylandServer::zxdg_toplevel_v6::
wl_resource_destroy(resource->handle);
}
+void XdgToplevelV6::zxdg_toplevel_v6_set_minimized(QtWaylandServer::zxdg_toplevel_v6::Resource *resource)
+{
+ Q_UNUSED(resource);
+ emit m_mockToplevel->setMinimizedRequested();
+}
+
+void XdgToplevelV6::zxdg_toplevel_v6_set_maximized(QtWaylandServer::zxdg_toplevel_v6::Resource *resource)
+{
+ Q_UNUSED(resource);
+ emit m_mockToplevel->setMaximizedRequested();
+}
+
+void XdgToplevelV6::zxdg_toplevel_v6_unset_maximized(QtWaylandServer::zxdg_toplevel_v6::Resource *resource)
+{
+ Q_UNUSED(resource);
+ emit m_mockToplevel->unsetMaximizedRequested();
+}
+
+void XdgToplevelV6::zxdg_toplevel_v6_set_fullscreen(QtWaylandServer::zxdg_toplevel_v6::Resource *resource, wl_resource *output)
+{
+ Q_UNUSED(resource);
+ Q_UNUSED(output);
+ emit m_mockToplevel->setFullscreenRequested();
+}
+
+void XdgToplevelV6::zxdg_toplevel_v6_unset_fullscreen(QtWaylandServer::zxdg_toplevel_v6::Resource *resource)
+{
+ Q_UNUSED(resource);
+ emit m_mockToplevel->unsetFullscreenRequested();
+}
+
void Impl::XdgShellV6::zxdg_shell_v6_get_xdg_surface(QtWaylandServer::zxdg_shell_v6::Resource *resource, uint32_t id, wl_resource *surface)
{
new XdgSurfaceV6(this, Surface::fromResource(surface), resource->client(), id);
diff --git a/tests/auto/client/shared/mockxdgshellv6.h b/tests/auto/client/shared/mockxdgshellv6.h
index 92b808ba8..faadb785a 100644
--- a/tests/auto/client/shared/mockxdgshellv6.h
+++ b/tests/auto/client/shared/mockxdgshellv6.h
@@ -74,6 +74,11 @@ public:
protected:
void zxdg_toplevel_v6_destroy_resource(Resource *) override { delete this; }
void zxdg_toplevel_v6_destroy(Resource *resource) override;
+ void zxdg_toplevel_v6_set_minimized(Resource *resource) override;
+ void zxdg_toplevel_v6_set_maximized(Resource *resource) override;
+ void zxdg_toplevel_v6_unset_maximized(Resource *resource) override;
+ void zxdg_toplevel_v6_set_fullscreen(Resource *resource, struct ::wl_resource *output) override;
+ void zxdg_toplevel_v6_unset_fullscreen(Resource *resource) override;
private:
XdgSurfaceV6 *m_xdgSurface = nullptr;
diff --git a/tests/auto/client/xdgshellv6/tst_xdgshellv6.cpp b/tests/auto/client/xdgshellv6/tst_xdgshellv6.cpp
index 364cd1099..0f72f58a9 100644
--- a/tests/auto/client/xdgshellv6/tst_xdgshellv6.cpp
+++ b/tests/auto/client/xdgshellv6/tst_xdgshellv6.cpp
@@ -42,6 +42,7 @@ static const QSize screenSize(1600, 1200);
class TestWindow : public QWindow
{
+ Q_OBJECT
public:
TestWindow()
{
@@ -49,6 +50,16 @@ public:
setGeometry(0, 0, 32, 32);
create();
}
+
+ bool event(QEvent *event) override
+ {
+ if (event->type() == QEvent::WindowStateChange)
+ emit windowStateChangeEventReceived(static_cast<QWindowStateChangeEvent *>(event)->oldState());
+ return QWindow::event(event);
+ }
+
+signals:
+ void windowStateChangeEventReceived(uint oldState);
};
class tst_WaylandClientXdgShellV6 : public QObject
@@ -58,6 +69,7 @@ public:
tst_WaylandClientXdgShellV6(MockCompositor *c)
: m_compositor(c)
{
+ qRegisterMetaType<Qt::WindowState>();
QSocketNotifier *notifier = new QSocketNotifier(m_compositor->waylandFileDescriptor(), QSocketNotifier::Read, this);
connect(notifier, &QSocketNotifier::activated, this, &tst_WaylandClientXdgShellV6::processWaylandEvents);
// connect to the event dispatcher to make sure to flush out the outgoing message queue
@@ -82,6 +94,11 @@ public slots:
private slots:
void createDestroyWindow();
void configure();
+ void showMinimized();
+ void setMinimized();
+ void unsetMaximized();
+ void focusWindowFollowsConfigure();
+ void windowStateChangedEvents();
private:
MockCompositor *m_compositor = nullptr;
@@ -118,10 +135,182 @@ void tst_WaylandClientXdgShellV6::configure()
QSharedPointer<MockXdgToplevelV6> toplevel;
QTRY_VERIFY(toplevel = m_compositor->xdgToplevelV6());
+
const QSize newSize(123, 456);
m_compositor->sendXdgToplevelV6Configure(toplevel, newSize);
QTRY_VERIFY(window.isExposed());
+ QTRY_COMPARE(window.visibility(), QWindow::Windowed);
+ QTRY_COMPARE(window.windowStates(), Qt::WindowNoState);
QTRY_COMPARE(window.frameGeometry(), QRect(QPoint(), newSize));
+
+ m_compositor->sendXdgToplevelV6Configure(toplevel, screenSize, { ZXDG_TOPLEVEL_V6_STATE_ACTIVATED, ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED });
+ QTRY_COMPARE(window.visibility(), QWindow::Maximized);
+ QTRY_COMPARE(window.windowStates(), Qt::WindowMaximized);
+ QTRY_COMPARE(window.frameGeometry(), QRect(QPoint(), screenSize));
+
+ m_compositor->sendXdgToplevelV6Configure(toplevel, screenSize, { ZXDG_TOPLEVEL_V6_STATE_ACTIVATED, ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN });
+ QTRY_COMPARE(window.visibility(), QWindow::FullScreen);
+ QTRY_COMPARE(window.windowStates(), Qt::WindowFullScreen);
+ QTRY_COMPARE(window.frameGeometry(), QRect(QPoint(), screenSize));
+
+ //The window should remember it's original size
+ m_compositor->sendXdgToplevelV6Configure(toplevel, QSize(0, 0), { ZXDG_TOPLEVEL_V6_STATE_ACTIVATED });
+ QTRY_COMPARE(window.visibility(), QWindow::Windowed);
+ QTRY_COMPARE(window.windowStates(), Qt::WindowNoState);
+ QTRY_COMPARE(window.frameGeometry(), QRect(QPoint(), newSize));
+}
+
+void tst_WaylandClientXdgShellV6::showMinimized()
+{
+ // On xdg-shell v6 there's really no way for the compositor to tell the window if it's minimized
+ // There are wl_surface.enter events and so on, but there's really no way to differentiate
+ // between a window preview and an unminimized window.
+ TestWindow window;
+ window.showMinimized();
+ QCOMPARE(window.windowStates(), Qt::WindowMinimized); // should return minimized until
+ QTRY_COMPARE(window.windowStates(), Qt::WindowNoState); // rejected by handleWindowStateChanged
+}
+
+void tst_WaylandClientXdgShellV6::setMinimized()
+{
+ TestWindow window;
+ window.show();
+
+ QSharedPointer<MockXdgToplevelV6> toplevel;
+ QTRY_VERIFY(toplevel = m_compositor->xdgToplevelV6());
+
+ m_compositor->sendXdgToplevelV6Configure(toplevel);
+ QTRY_COMPARE(window.visibility(), QWindow::Windowed);
+ QTRY_COMPARE(window.windowStates(), Qt::WindowNoState);
+
+ QSignalSpy setMinimizedSpy(toplevel.data(), SIGNAL(setMinimizedRequested()));
+ QSignalSpy windowStateChangeSpy(&window, SIGNAL(windowStateChangeEventReceived(uint)));
+
+ window.setVisibility(QWindow::Minimized);
+ QCOMPARE(window.visibility(), QWindow::Minimized);
+ QCOMPARE(window.windowStates(), Qt::WindowMinimized);
+ QTRY_COMPARE(setMinimizedSpy.count(), 1);
+ {
+ QTRY_VERIFY(windowStateChangeSpy.count() > 0);
+ Qt::WindowStates oldStates(windowStateChangeSpy.takeFirst().at(0).toUInt());
+ QCOMPARE(oldStates, Qt::WindowNoState);
+ }
+
+ // In the meantime the compositor may minimize, do nothing or reshow the window without
+ // telling us.
+
+ QTRY_COMPARE(window.visibility(), QWindow::Windowed); // verify that we don't know anything
+ QTRY_COMPARE(window.windowStates(), Qt::WindowNoState);
+ {
+ QTRY_COMPARE(windowStateChangeSpy.count(), 1);
+ Qt::WindowStates oldStates(windowStateChangeSpy.takeFirst().at(0).toUInt());
+ QCOMPARE(oldStates, Qt::WindowNoState); // because the window never was minimized
+ }
+
+ // Setting visibility again should send another set_minimized request
+ window.setVisibility(QWindow::Minimized);
+ QTRY_COMPARE(setMinimizedSpy.count(), 2);
+}
+
+void tst_WaylandClientXdgShellV6::unsetMaximized()
+{
+ TestWindow window;
+ window.show();
+
+ QSharedPointer<MockXdgToplevelV6> toplevel;
+ QTRY_VERIFY(toplevel = m_compositor->xdgToplevelV6());
+
+ QSignalSpy unsetMaximizedSpy(toplevel.data(), SIGNAL(unsetMaximizedRequested()));
+
+ QSignalSpy windowStateChangedSpy(&window, SIGNAL(windowStateChanged(Qt::WindowState)));
+
+ m_compositor->sendXdgToplevelV6Configure(toplevel, screenSize, { ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED });
+
+ QTRY_COMPARE(windowStateChangedSpy.count(), 1);
+ QCOMPARE(windowStateChangedSpy.takeFirst().at(0).toUInt(), Qt::WindowMaximized);
+
+ window.setWindowStates(Qt::WindowNoState);
+
+ QTRY_COMPARE(unsetMaximizedSpy.count(), 1);
+ QTRY_COMPARE(windowStateChangedSpy.count(), 1);
+ QCOMPARE(windowStateChangedSpy.takeFirst().at(0).toUInt(), Qt::WindowNoState);
+
+ m_compositor->sendXdgToplevelV6Configure(toplevel, QSize(0, 0), {});
+
+ QTRY_COMPARE(windowStateChangedSpy.count(), 1);
+ QCOMPARE(windowStateChangedSpy.takeFirst().at(0).toUInt(), Qt::WindowNoState);
+}
+
+void tst_WaylandClientXdgShellV6::focusWindowFollowsConfigure()
+{
+ TestWindow window;
+ window.show();
+
+ QSharedPointer<MockXdgToplevelV6> toplevel;
+ QTRY_VERIFY(toplevel = m_compositor->xdgToplevelV6());
+ QTRY_VERIFY(!window.isActive());
+
+ QSignalSpy windowStateChangeSpy(&window, SIGNAL(windowStateChangeEventReceived(uint)));
+
+ m_compositor->sendXdgToplevelV6Configure(toplevel, QSize(0, 0), { ZXDG_TOPLEVEL_V6_STATE_ACTIVATED });
+ QTRY_VERIFY(window.isActive());
+
+ m_compositor->sendXdgToplevelV6Configure(toplevel, QSize(0, 0), {});
+ QTRY_VERIFY(!window.isActive());
+}
+
+void tst_WaylandClientXdgShellV6::windowStateChangedEvents()
+{
+ TestWindow window;
+ window.show();
+
+ QSharedPointer<MockXdgToplevelV6> toplevel;
+ QTRY_VERIFY(toplevel = m_compositor->xdgToplevelV6());
+
+ QSignalSpy eventSpy(&window, SIGNAL(windowStateChangeEventReceived(uint)));
+ QSignalSpy signalSpy(&window, SIGNAL(windowStateChanged(Qt::WindowState)));
+
+ m_compositor->sendXdgToplevelV6Configure(toplevel, screenSize, { ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED });
+
+ QTRY_COMPARE(window.windowStates(), Qt::WindowMaximized);
+ QTRY_COMPARE(window.windowState(), Qt::WindowMaximized);
+ {
+ QTRY_COMPARE(eventSpy.count(), 1);
+ Qt::WindowStates oldStates(eventSpy.takeFirst().at(0).toUInt());
+ QCOMPARE(oldStates, Qt::WindowNoState);
+
+ QTRY_COMPARE(signalSpy.count(), 1);
+ uint newState = signalSpy.takeFirst().at(0).toUInt();
+ QCOMPARE(newState, Qt::WindowMaximized);
+ }
+
+ m_compositor->sendXdgToplevelV6Configure(toplevel, screenSize, { ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN });
+
+ QTRY_COMPARE(window.windowStates(), Qt::WindowFullScreen);
+ QTRY_COMPARE(window.windowState(), Qt::WindowFullScreen);
+ {
+ QTRY_COMPARE(eventSpy.count(), 1);
+ Qt::WindowStates oldStates(eventSpy.takeFirst().at(0).toUInt());
+ QCOMPARE(oldStates, Qt::WindowMaximized);
+
+ QTRY_COMPARE(signalSpy.count(), 1);
+ uint newState = signalSpy.takeFirst().at(0).toUInt();
+ QCOMPARE(newState, Qt::WindowFullScreen);
+ }
+
+ m_compositor->sendXdgToplevelV6Configure(toplevel, QSize(0, 0), {});
+
+ QTRY_COMPARE(window.windowStates(), Qt::WindowNoState);
+ QTRY_COMPARE(window.windowState(), Qt::WindowNoState);
+ {
+ QTRY_COMPARE(eventSpy.count(), 1);
+ Qt::WindowStates oldStates(eventSpy.takeFirst().at(0).toUInt());
+ QCOMPARE(oldStates, Qt::WindowFullScreen);
+
+ QTRY_COMPARE(signalSpy.count(), 1);
+ uint newState = signalSpy.takeFirst().at(0).toUInt();
+ QCOMPARE(newState, Qt::WindowNoState);
+ }
}
int main(int argc, char **argv)