wayland: Make fullscreen mode updates async
Currently, the fullscreen state is update synchronously, but it needs to be done in asynchronous fashion. This change removes some tests as they don't add any value, testFullscreen() covers them all.
This commit is contained in:
parent
62500acd1a
commit
a0fc0277a7
6 changed files with 26 additions and 137 deletions
|
@ -68,9 +68,7 @@ private Q_SLOTS:
|
|||
void testFullscreen_data();
|
||||
void testFullscreen();
|
||||
|
||||
void testFullscreenRestore();
|
||||
void testUserCanSetFullscreen();
|
||||
void testUserSetFullscreen();
|
||||
|
||||
void testMaximizeHorizontal();
|
||||
void testMaximizeVertical();
|
||||
|
@ -432,13 +430,8 @@ void TestXdgShellClient::testFullscreen()
|
|||
shellSurface->ackConfigure(configureRequestedSpy.last().at(2).value<quint32>());
|
||||
Test::render(surface.data(), configureRequestedSpy.last().at(0).value<QSize>(), Qt::red);
|
||||
|
||||
#if 0 // TODO: Uncomment when full screen state updates are truly asynchronous.
|
||||
QVERIFY(fullScreenChangedSpy.wait());
|
||||
QCOMPARE(fullScreenChangedSpy.count(), 1);
|
||||
#else
|
||||
QVERIFY(frameGeometryChangedSpy.wait());
|
||||
QCOMPARE(fullScreenChangedSpy.count(), 1);
|
||||
#endif
|
||||
QVERIFY(client->isFullScreen());
|
||||
QVERIFY(!client->isDecorated());
|
||||
QCOMPARE(client->layer(), ActiveLayer);
|
||||
|
@ -455,13 +448,8 @@ void TestXdgShellClient::testFullscreen()
|
|||
shellSurface->ackConfigure(configureRequestedSpy.last().at(2).value<quint32>());
|
||||
Test::render(surface.data(), configureRequestedSpy.last().at(0).value<QSize>(), Qt::blue);
|
||||
|
||||
#if 0 // TODO: Uncomment when full screen state updates are truly asynchronous.
|
||||
QVERIFY(fullScreenChangedSpy.wait());
|
||||
QCOMPARE(fullScreenChangedSpy.count(), 2);
|
||||
#else
|
||||
QVERIFY(frameGeometryChangedSpy.wait());
|
||||
QCOMPARE(fullScreenChangedSpy.count(), 2);
|
||||
#endif
|
||||
QCOMPARE(client->clientSize(), QSize(100, 50));
|
||||
QVERIFY(!client->isFullScreen());
|
||||
QCOMPARE(client->isDecorated(), decoMode == ServerSideDecoration::Mode::Server);
|
||||
|
@ -472,58 +460,6 @@ void TestXdgShellClient::testFullscreen()
|
|||
QVERIFY(Test::waitForWindowDestroyed(client));
|
||||
}
|
||||
|
||||
void TestXdgShellClient::testFullscreenRestore()
|
||||
{
|
||||
// this test verifies that windows created fullscreen can be later properly restored
|
||||
QScopedPointer<Surface> surface(Test::createSurface());
|
||||
XdgShellSurface *xdgShellSurface = Test::createXdgShellStableSurface(surface.data(), surface.data(), Test::CreationSetup::CreateOnly);
|
||||
QSignalSpy configureRequestedSpy(xdgShellSurface, &XdgShellSurface::configureRequested);
|
||||
|
||||
// fullscreen the window
|
||||
xdgShellSurface->setFullscreen(true);
|
||||
surface->commit(Surface::CommitFlag::None);
|
||||
|
||||
configureRequestedSpy.wait();
|
||||
QCOMPARE(configureRequestedSpy.count(), 1);
|
||||
|
||||
const auto size = configureRequestedSpy.first()[0].value<QSize>();
|
||||
const auto state = configureRequestedSpy.first()[1].value<KWayland::Client::XdgShellSurface::States>();
|
||||
|
||||
QCOMPARE(size, screens()->size(0));
|
||||
QVERIFY(state & KWayland::Client::XdgShellSurface::State::Fullscreen);
|
||||
xdgShellSurface->ackConfigure(configureRequestedSpy.first()[2].toUInt());
|
||||
|
||||
auto c = Test::renderAndWaitForShown(surface.data(), size, Qt::blue);
|
||||
QVERIFY(c);
|
||||
QVERIFY(c->isFullScreen());
|
||||
|
||||
configureRequestedSpy.wait(100);
|
||||
|
||||
QSignalSpy fullscreenChangedSpy(c, &AbstractClient::fullScreenChanged);
|
||||
QVERIFY(fullscreenChangedSpy.isValid());
|
||||
QSignalSpy frameGeometryChangedSpy(c, &AbstractClient::frameGeometryChanged);
|
||||
QVERIFY(frameGeometryChangedSpy.isValid());
|
||||
|
||||
// swap back to normal
|
||||
configureRequestedSpy.clear();
|
||||
xdgShellSurface->setFullscreen(false);
|
||||
|
||||
QVERIFY(fullscreenChangedSpy.wait());
|
||||
QVERIFY(configureRequestedSpy.wait());
|
||||
QCOMPARE(configureRequestedSpy.last().first().toSize(), QSize(0, 0));
|
||||
QVERIFY(!c->isFullScreen());
|
||||
|
||||
for (const auto &it: configureRequestedSpy) {
|
||||
xdgShellSurface->ackConfigure(it[2].toUInt());
|
||||
}
|
||||
|
||||
Test::render(surface.data(), QSize(100, 50), Qt::red);
|
||||
QVERIFY(frameGeometryChangedSpy.wait());
|
||||
QCOMPARE(frameGeometryChangedSpy.count(), 1);
|
||||
QVERIFY(!c->isFullScreen());
|
||||
QCOMPARE(c->frameGeometry().size(), QSize(100, 50));
|
||||
}
|
||||
|
||||
void TestXdgShellClient::testUserCanSetFullscreen()
|
||||
{
|
||||
QScopedPointer<Surface> surface(Test::createSurface());
|
||||
|
@ -535,59 +471,6 @@ void TestXdgShellClient::testUserCanSetFullscreen()
|
|||
QVERIFY(c->userCanSetFullScreen());
|
||||
}
|
||||
|
||||
void TestXdgShellClient::testUserSetFullscreen()
|
||||
{
|
||||
QScopedPointer<Surface> surface(Test::createSurface());
|
||||
QScopedPointer<XdgShellSurface> shellSurface(Test::createXdgShellStableSurface(
|
||||
surface.data(), surface.data(), Test::CreationSetup::CreateOnly));
|
||||
QVERIFY(!shellSurface.isNull());
|
||||
|
||||
// wait for the initial configure event
|
||||
QSignalSpy configureRequestedSpy(shellSurface.data(), &XdgShellSurface::configureRequested);
|
||||
QVERIFY(configureRequestedSpy.isValid());
|
||||
surface->commit(Surface::CommitFlag::None);
|
||||
QVERIFY(configureRequestedSpy.wait());
|
||||
QCOMPARE(configureRequestedSpy.count(), 1);
|
||||
|
||||
shellSurface->ackConfigure(configureRequestedSpy.last().at(2).value<quint32>());
|
||||
auto c = Test::renderAndWaitForShown(surface.data(), QSize(100, 50), Qt::blue);
|
||||
QVERIFY(c);
|
||||
QVERIFY(c->isActive());
|
||||
QVERIFY(!c->isFullScreen());
|
||||
|
||||
// The client gets activated, which gets another configure event. Though that's not relevant to the test
|
||||
configureRequestedSpy.wait(10);
|
||||
|
||||
QSignalSpy fullscreenChangedSpy(c, &AbstractClient::fullScreenChanged);
|
||||
QVERIFY(fullscreenChangedSpy.isValid());
|
||||
c->setFullScreen(true);
|
||||
QCOMPARE(c->isFullScreen(), true);
|
||||
configureRequestedSpy.clear();
|
||||
QVERIFY(configureRequestedSpy.wait());
|
||||
QCOMPARE(configureRequestedSpy.count(), 1);
|
||||
QCOMPARE(configureRequestedSpy.first().at(0).toSize(), screens()->size(0));
|
||||
const auto states = configureRequestedSpy.first().at(1).value<KWayland::Client::XdgShellSurface::States>();
|
||||
QVERIFY(states.testFlag(KWayland::Client::XdgShellSurface::State::Fullscreen));
|
||||
QVERIFY(states.testFlag(KWayland::Client::XdgShellSurface::State::Activated));
|
||||
QVERIFY(!states.testFlag(KWayland::Client::XdgShellSurface::State::Maximized));
|
||||
QVERIFY(!states.testFlag(KWayland::Client::XdgShellSurface::State::Resizing));
|
||||
QCOMPARE(fullscreenChangedSpy.count(), 1);
|
||||
QVERIFY(c->isFullScreen());
|
||||
|
||||
shellSurface->ackConfigure(configureRequestedSpy.first().at(2).value<quint32>());
|
||||
|
||||
// unset fullscreen again
|
||||
c->setFullScreen(false);
|
||||
QCOMPARE(c->isFullScreen(), false);
|
||||
configureRequestedSpy.clear();
|
||||
QVERIFY(configureRequestedSpy.wait());
|
||||
QCOMPARE(configureRequestedSpy.count(), 1);
|
||||
QCOMPARE(configureRequestedSpy.first().at(0).toSize(), QSize(100, 50));
|
||||
QVERIFY(!configureRequestedSpy.first().at(1).value<KWayland::Client::XdgShellSurface::States>().testFlag(KWayland::Client::XdgShellSurface::State::Fullscreen));
|
||||
QCOMPARE(fullscreenChangedSpy.count(), 2);
|
||||
QVERIFY(!c->isFullScreen());
|
||||
}
|
||||
|
||||
void TestXdgShellClient::testMaximizedToFullscreen_data()
|
||||
{
|
||||
QTest::addColumn<ServerSideDecoration::Mode>("decoMode");
|
||||
|
@ -660,12 +543,8 @@ void TestXdgShellClient::testMaximizedToFullscreen()
|
|||
shellSurface->ackConfigure(configureRequestedSpy.last().at(2).value<quint32>());
|
||||
Test::render(surface.data(), configureRequestedSpy.last().at(0).value<QSize>(), Qt::red);
|
||||
|
||||
#if 0 // TODO: Uncomment when full screen changes are truly asynchronous.
|
||||
QVERIFY(fullScreenChangedSpy.wait());
|
||||
QCOMPARE(fullScreenChangedSpy.count(), 1);
|
||||
#else
|
||||
QTRY_COMPARE(fullscreenChangedSpy.count(), 1);
|
||||
#endif
|
||||
QVERIFY(fullscreenChangedSpy.wait());
|
||||
QCOMPARE(fullscreenChangedSpy.count(), 1);
|
||||
QCOMPARE(client->maximizeMode(), MaximizeFull);
|
||||
QVERIFY(client->isFullScreen());
|
||||
QVERIFY(!client->isDecorated());
|
||||
|
|
|
@ -3615,6 +3615,11 @@ bool AbstractClient::isFullScreen() const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool AbstractClient::isRequestedFullScreen() const
|
||||
{
|
||||
return isFullScreen();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether requests initiated by the user to enter or leave full screen mode are honored.
|
||||
*
|
||||
|
|
|
@ -419,6 +419,7 @@ public:
|
|||
virtual void hideClient(bool hide) = 0;
|
||||
virtual bool isFullScreenable() const;
|
||||
virtual bool isFullScreen() const;
|
||||
virtual bool isRequestedFullScreen() const;
|
||||
// TODO: remove boolean trap
|
||||
virtual AbstractClient *findModal(bool allow_itself = false) = 0;
|
||||
virtual bool isTransient() const;
|
||||
|
|
|
@ -718,7 +718,7 @@ void Workspace::addShellClient(AbstractClient *client)
|
|||
if (client->isPlaceable()) {
|
||||
const QRect area = clientArea(PlacementArea, Screens::self()->current(), client->desktop());
|
||||
bool placementDone = false;
|
||||
if (client->isFullScreen()) {
|
||||
if (client->isRequestedFullScreen()) {
|
||||
placementDone = true;
|
||||
}
|
||||
if (client->maximizeMode() == MaximizeMode::MaximizeFull) {
|
||||
|
|
|
@ -457,9 +457,14 @@ bool XdgToplevelClient::isFullScreen() const
|
|||
return m_isFullScreen;
|
||||
}
|
||||
|
||||
bool XdgToplevelClient::isRequestedFullScreen() const
|
||||
{
|
||||
return m_isRequestedFullScreen;
|
||||
}
|
||||
|
||||
bool XdgToplevelClient::isMovable() const
|
||||
{
|
||||
if (isFullScreen()) {
|
||||
if (isRequestedFullScreen()) {
|
||||
return false;
|
||||
}
|
||||
if (isSpecialWindow() && !isSplash() && !isToolbar()) {
|
||||
|
@ -484,7 +489,7 @@ bool XdgToplevelClient::isMovableAcrossScreens() const
|
|||
|
||||
bool XdgToplevelClient::isResizable() const
|
||||
{
|
||||
if (isFullScreen()) {
|
||||
if (isRequestedFullScreen()) {
|
||||
return false;
|
||||
}
|
||||
if (isSpecialWindow() || isSplash() || isToolbar()) {
|
||||
|
@ -577,7 +582,7 @@ bool XdgToplevelClient::noBorder() const
|
|||
if (m_serverDecoration) {
|
||||
switch (m_serverDecoration->mode()) {
|
||||
case ServerSideDecorationManagerInterface::Mode::Server:
|
||||
return m_userNoBorder || isFullScreen();
|
||||
return m_userNoBorder || isRequestedFullScreen();
|
||||
case ServerSideDecorationManagerInterface::Mode::Client:
|
||||
case ServerSideDecorationManagerInterface::Mode::None:
|
||||
return true;
|
||||
|
@ -587,7 +592,7 @@ bool XdgToplevelClient::noBorder() const
|
|||
switch (m_xdgDecoration->preferredMode()) {
|
||||
case XdgToplevelDecorationV1Interface::Mode::Server:
|
||||
case XdgToplevelDecorationV1Interface::Mode::Undefined:
|
||||
return !Decoration::DecorationBridge::hasPlugin() || m_userNoBorder || isFullScreen();
|
||||
return !Decoration::DecorationBridge::hasPlugin() || m_userNoBorder || isRequestedFullScreen();
|
||||
case XdgToplevelDecorationV1Interface::Mode::Client:
|
||||
return true;
|
||||
}
|
||||
|
@ -791,7 +796,7 @@ void XdgToplevelClient::doSetActive()
|
|||
|
||||
void XdgToplevelClient::doSetFullScreen()
|
||||
{
|
||||
if (isFullScreen()) {
|
||||
if (isRequestedFullScreen()) {
|
||||
m_requestedStates |= XdgToplevelInterface::State::FullScreen;
|
||||
} else {
|
||||
m_requestedStates &= ~XdgToplevelInterface::State::FullScreen;
|
||||
|
@ -1223,7 +1228,7 @@ void XdgToplevelClient::initialize()
|
|||
RuleBook::self()->discardUsed(this, false); // Remove Apply Now rules.
|
||||
updateWindowRules(Rules::All);
|
||||
}
|
||||
if (isFullScreen()) {
|
||||
if (isRequestedFullScreen()) {
|
||||
needsPlacement = false;
|
||||
}
|
||||
if (needsPlacement) {
|
||||
|
@ -1253,7 +1258,9 @@ void XdgToplevelClient::updateFullScreenMode(bool set)
|
|||
if (m_isFullScreen == set) {
|
||||
return;
|
||||
}
|
||||
StackingUpdatesBlocker blocker1(workspace());
|
||||
m_isFullScreen = set;
|
||||
updateLayer();
|
||||
updateWindowRules(Rules::Fullscreen);
|
||||
emit fullScreenChanged();
|
||||
}
|
||||
|
@ -1527,7 +1534,7 @@ void XdgToplevelClient::setFullScreen(bool set, bool user)
|
|||
{
|
||||
set = rules()->checkFullScreen(set);
|
||||
|
||||
const bool wasFullscreen = isFullScreen();
|
||||
const bool wasFullscreen = isRequestedFullScreen();
|
||||
if (wasFullscreen == set) {
|
||||
return;
|
||||
}
|
||||
|
@ -1543,18 +1550,16 @@ void XdgToplevelClient::setFullScreen(bool set, bool user)
|
|||
} else {
|
||||
setFullscreenGeometryRestore(frameGeometry());
|
||||
}
|
||||
m_isFullScreen = set;
|
||||
m_isRequestedFullScreen = set;
|
||||
|
||||
if (set) {
|
||||
workspace()->raiseClient(this);
|
||||
}
|
||||
StackingUpdatesBlocker blocker1(workspace());
|
||||
GeometryUpdatesBlocker blocker2(this);
|
||||
if (set) {
|
||||
dontMoveResize();
|
||||
}
|
||||
|
||||
workspace()->updateClientLayer(this); // active fullscreens get different layer
|
||||
updateDecoration(false, false);
|
||||
|
||||
if (set) {
|
||||
|
@ -1576,9 +1581,6 @@ void XdgToplevelClient::setFullScreen(bool set, bool user)
|
|||
}
|
||||
|
||||
doSetFullScreen();
|
||||
|
||||
updateWindowRules(Rules::Fullscreen|Rules::Position|Rules::Size);
|
||||
emit fullScreenChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -126,6 +126,7 @@ public:
|
|||
QSize minSize() const override;
|
||||
QSize maxSize() const override;
|
||||
bool isFullScreen() const override;
|
||||
bool isRequestedFullScreen() const override;
|
||||
bool isMovableAcrossScreens() const override;
|
||||
bool isMovable() const override;
|
||||
bool isResizable() const override;
|
||||
|
@ -215,6 +216,7 @@ private:
|
|||
MaximizeMode m_maximizeMode = MaximizeRestore;
|
||||
MaximizeMode m_requestedMaximizeMode = MaximizeRestore;
|
||||
bool m_isFullScreen = false;
|
||||
bool m_isRequestedFullScreen = false;
|
||||
bool m_isInitialized = false;
|
||||
bool m_userNoBorder = false;
|
||||
bool m_isTransient = false;
|
||||
|
|
Loading…
Reference in a new issue