[wayland] Fix window sizing when restoring a window that was initially fullscreen
Summary: When creating a surface and setting it as fullscreen before attaching its buffer KWin does not know the original dimensions of the surface and tries to use an invalid value when unsetting the fullscreen flag. This patch fixes this by sending a configure with the size of 0,0 - which according to xdg-shell spec means that the client is requested to set its size by itself. Test Plan: 1. Create a fullscreen Wayland window. 2. Toggle fullscreen off. 3. KWin should send a configure event with size 0,0 instead of 1,1. Reviewers: #kwin, davidedmundson Reviewed By: #kwin, davidedmundson Subscribers: zzag, graesslin, davidedmundson, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D16710
This commit is contained in:
parent
cbbe94d769
commit
7bf2c1d73e
2 changed files with 57 additions and 3 deletions
|
@ -72,6 +72,8 @@ private Q_SLOTS:
|
|||
void testMinimizeActiveWindow();
|
||||
void testFullscreen_data();
|
||||
void testFullscreen();
|
||||
void testFullscreenRestore_data();
|
||||
void testFullscreenRestore();
|
||||
void testUserCanSetFullscreen_data();
|
||||
void testUserCanSetFullscreen();
|
||||
void testUserSetFullscreenWlShell();
|
||||
|
@ -524,6 +526,57 @@ void TestShellClient::testFullscreen()
|
|||
QCOMPARE(c->isDecorated(), decoMode == ServerSideDecoration::Mode::Server);
|
||||
}
|
||||
|
||||
void TestShellClient::testFullscreenRestore_data()
|
||||
{
|
||||
QTest::addColumn<Test::ShellSurfaceType>("type");
|
||||
|
||||
QTest::newRow("xdgShellV5") << Test::ShellSurfaceType::XdgShellV5;
|
||||
QTest::newRow("xdgShellV6") << Test::ShellSurfaceType::XdgShellV6;
|
||||
QTest::newRow("xdgShellWmBase") << Test::ShellSurfaceType::XdgShellStable;
|
||||
}
|
||||
|
||||
void TestShellClient::testFullscreenRestore()
|
||||
{
|
||||
// this test verifies that windows created fullscreen can be later properly restored
|
||||
QScopedPointer<Surface> surface(Test::createSurface());
|
||||
QFETCH(Test::ShellSurfaceType, type);
|
||||
QScopedPointer<QObject> shellSurface(Test::createShellSurface(type, surface.data()));
|
||||
|
||||
XdgShellSurface *xdgShellSurface = nullptr;
|
||||
// fullscreen the window
|
||||
xdgShellSurface = qobject_cast<XdgShellSurface*>(shellSurface.data());
|
||||
xdgShellSurface->setFullscreen(true);
|
||||
|
||||
auto c = Test::renderAndWaitForShown(surface.data(), QSize(screens()->size(0)), Qt::blue);
|
||||
QVERIFY(c);
|
||||
QVERIFY(c->isFullScreen());
|
||||
|
||||
QSignalSpy fullscreenChangedSpy(c, &ShellClient::fullScreenChanged);
|
||||
QVERIFY(fullscreenChangedSpy.isValid());
|
||||
QSignalSpy geometryChangedSpy(c, &ShellClient::geometryChanged);
|
||||
QVERIFY(geometryChangedSpy.isValid());
|
||||
QSignalSpy configureRequestedSpy(shellSurface.data(), SIGNAL(configureRequested(QSize, KWayland::Client::XdgShellSurface::States, quint32)));
|
||||
QVERIFY(configureRequestedSpy.isValid());
|
||||
|
||||
// swap back to normal
|
||||
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].toInt());
|
||||
}
|
||||
|
||||
Test::render(surface.data(), QSize(100, 50), Qt::red);
|
||||
QVERIFY(geometryChangedSpy.wait());
|
||||
QCOMPARE(geometryChangedSpy.count(), 1);
|
||||
QVERIFY(!c->isFullScreen());
|
||||
QCOMPARE(c->geometry().size(), QSize(100, 50));
|
||||
}
|
||||
|
||||
void TestShellClient::testUserCanSetFullscreen_data()
|
||||
{
|
||||
QTest::addColumn<Test::ShellSurfaceType>("type");
|
||||
|
|
|
@ -920,14 +920,15 @@ void ShellClient::setFullScreen(bool set, bool user)
|
|||
if (isFullScreen()) {
|
||||
setGeometry(workspace()->clientArea(FullScreenArea, this));
|
||||
} else {
|
||||
if (!m_geomFsRestore.isNull()) {
|
||||
if (m_geomFsRestore.isValid()) {
|
||||
int currentScreen = screen();
|
||||
setGeometry(QRect(m_geomFsRestore.topLeft(), adjustedSize(m_geomFsRestore.size())));
|
||||
if( currentScreen != screen())
|
||||
workspace()->sendClientToScreen( this, currentScreen );
|
||||
} else {
|
||||
// does this ever happen?
|
||||
setGeometry(workspace()->clientArea(MaximizeArea, this));
|
||||
// this can happen when the window was first shown already fullscreen,
|
||||
// so let the client set the size by itself
|
||||
setGeometry(QRect(workspace()->clientArea(PlacementArea, this).topLeft(), QSize(0, 0)));
|
||||
}
|
||||
}
|
||||
updateWindowRules(Rules::Fullscreen|Rules::Position|Rules::Size);
|
||||
|
|
Loading…
Reference in a new issue