Commit 31ea780d authored by Vlad Zahorodnii's avatar Vlad Zahorodnii
Browse files

[wayland] Rework xdg-shell implementation

Summary:
This change splits the XdgShellClient class to better match existing
abstractions in the xdg-shell protocol and fix a few issues related to
sending configure events.

In the new client classes, configure events are handled differently.
Instead of blocking configure events, we try to send them as late as
possible. Delaying configure events will let us merge changeMaximize()
for X11 clients and Wayland clients and it also fixes the bug where
we don't send the final configure event when user has finished resizing
a window.

Given that configure events are not sent immediately, XdgSurfaceClient
keeps the last requested frame geometry and the last requested client
geometry.

This patch doesn't intend to fix all issues in kwin's implementation of
the xdg-shell protocol. For example, we still handle surface unmapping
very poorly.

Test Plan: Tests pass.

Reviewers: #kwin

Subscribers: kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D27861
parent 076b8bc1
......@@ -502,10 +502,10 @@ set(kwin_SRCS
sm.cpp
subsurfacemonitor.cpp
syncalarmx11filter.cpp
tablet_input.cpp
thumbnailitem.cpp
toplevel.cpp
touch_hide_cursor_spy.cpp
tablet_input.cpp
touch_input.cpp
udev.cpp
unmanaged.cpp
......@@ -518,6 +518,7 @@ set(kwin_SRCS
was_user_interaction_x11_filter.cpp
wayland_cursor_theme.cpp
wayland_server.cpp
waylandclient.cpp
window_property_notify_x11_filter.cpp
workspace.cpp
x11client.cpp
......
......@@ -942,6 +942,8 @@ void AbstractClient::finishMoveResize(bool cancel)
const bool wasResize = isResize(); // store across leaveMoveResize
leaveMoveResize();
doFinishMoveResize();
if (cancel)
setFrameGeometry(initialMoveResizeGeometry());
else {
......@@ -2067,6 +2069,10 @@ bool AbstractClient::doStartMoveResize()
return true;
}
void AbstractClient::doFinishMoveResize()
{
}
void AbstractClient::positionGeometryTip()
{
}
......
......@@ -1129,6 +1129,7 @@ protected:
* Base implementation returns @c true.
*/
virtual bool doStartMoveResize();
virtual void doFinishMoveResize();
void finishMoveResize(bool cancel);
/**
* Leaves the move resize mode.
......
......@@ -361,6 +361,8 @@ void TestMaximized::testBorderlessMaximizedWindowNoClientSideDecoration()
// test case verifies that borderless maximized windows doesn't cause
// clients to render client-side decorations instead (BUG 405385)
XdgShellSurface::States states;
// adjust config
auto group = kwinApp()->config()->group("Windows");
group.writeEntry("BorderlessMaximizedWindows", true);
......@@ -376,29 +378,32 @@ void TestMaximized::testBorderlessMaximizedWindowNoClientSideDecoration()
QVERIFY(decorationConfiguredSpy.isValid());
auto client = Test::renderAndWaitForShown(surface.data(), QSize(100, 50), Qt::blue);
QVERIFY(client->isDecorated());
QVERIFY(!client->noBorder());
QSignalSpy frameGeometryChangedSpy(client, &AbstractClient::frameGeometryChanged);
QVERIFY(frameGeometryChangedSpy.isValid());
QSignalSpy sizeChangeRequestedSpy(xdgShellSurface.data(), &XdgShellSurface::sizeChanged);
QVERIFY(sizeChangeRequestedSpy.isValid());
QSignalSpy configureRequestedSpy(xdgShellSurface.data(), &XdgShellSurface::configureRequested);
QVERIFY(configureRequestedSpy.isValid());
QVERIFY(client->isDecorated());
QVERIFY(!client->noBorder());
configureRequestedSpy.wait();
// Wait for the compositor to send a configure event with the Activated state.
QVERIFY(configureRequestedSpy.wait());
QCOMPARE(configureRequestedSpy.count(), 1);
states = configureRequestedSpy.last().at(1).value<XdgShellSurface::States>();
QVERIFY(states & XdgShellSurface::State::Activated);
QCOMPARE(decorationConfiguredSpy.count(), 1);
QCOMPARE(deco->mode(), XdgDecoration::Mode::ServerSide);
// go to maximized
xdgShellSurface->setMaximized(true);
QVERIFY(sizeChangeRequestedSpy.wait());
QCOMPARE(sizeChangeRequestedSpy.count(), 1);
QVERIFY(configureRequestedSpy.wait());
QCOMPARE(configureRequestedSpy.count(), 2);
states = configureRequestedSpy.last().at(1).value<XdgShellSurface::States>();
QVERIFY(states & XdgShellSurface::State::Maximized);
for (const auto &it: configureRequestedSpy) {
xdgShellSurface->ackConfigure(it[2].toInt());
}
Test::render(surface.data(), sizeChangeRequestedSpy.last().first().toSize(), Qt::red);
xdgShellSurface->ackConfigure(configureRequestedSpy.last().at(2).value<quint32>());
Test::render(surface.data(), configureRequestedSpy.last().first().toSize(), Qt::red);
QVERIFY(frameGeometryChangedSpy.wait());
// no deco
......@@ -409,13 +414,13 @@ void TestMaximized::testBorderlessMaximizedWindowNoClientSideDecoration()
// go back to normal
xdgShellSurface->setMaximized(false);
QVERIFY(sizeChangeRequestedSpy.wait());
QCOMPARE(sizeChangeRequestedSpy.count(), 2);
QVERIFY(configureRequestedSpy.wait());
QCOMPARE(configureRequestedSpy.count(), 3);
states = configureRequestedSpy.last().at(1).value<XdgShellSurface::States>();
QVERIFY(!(states & XdgShellSurface::State::Maximized));
for (const auto &it: configureRequestedSpy) {
xdgShellSurface->ackConfigure(it[2].toInt());
}
Test::render(surface.data(), sizeChangeRequestedSpy.last().first().toSize(), Qt::red);
xdgShellSurface->ackConfigure(configureRequestedSpy.last().at(2).value<quint32>());
Test::render(surface.data(), configureRequestedSpy.last().first().toSize(), Qt::red);
QVERIFY(frameGeometryChangedSpy.wait());
QVERIFY(client->isDecorated());
......
......@@ -316,7 +316,6 @@ void MoveResizeWindowTest::testResize()
QCOMPARE(moveResizedChangedSpy.count(), 2);
QCOMPARE(c->isResize(), false);
QCOMPARE(workspace()->moveResizeClient(), nullptr);
QEXPECT_FAIL("", "XdgShellClient currently doesn't send final configure event", Abort);
QVERIFY(configureRequestedSpy.wait());
QCOMPARE(configureRequestedSpy.count(), 6);
states = configureRequestedSpy.last().at(1).value<XdgShellSurface::States>();
......@@ -324,7 +323,7 @@ void MoveResizeWindowTest::testResize()
QVERIFY(!states.testFlag(XdgShellSurface::State::Resizing));
// Destroy the client.
surface.reset();
shellSurface.reset();
QVERIFY(Test::waitForWindowDestroyed(c));
}
......
......@@ -192,7 +192,6 @@ void QuickTilingTest::testQuickTiling()
// but we got requested a new geometry
QVERIFY(configureRequestedSpy.wait());
QEXPECT_FAIL("maximize", "Two configure events are sent for maximized", Continue);
QCOMPARE(configureRequestedSpy.count(), 2);
QCOMPARE(configureRequestedSpy.last().at(0).toSize(), expectedGeometry.size());
......@@ -272,7 +271,6 @@ void QuickTilingTest::testQuickMaximizing()
// but we got requested a new geometry
QVERIFY(configureRequestedSpy.wait());
QEXPECT_FAIL("", "Two configure events are sent for maximized", Continue);
QCOMPARE(configureRequestedSpy.count(), 2);
QCOMPARE(configureRequestedSpy.last().at(0).toSize(), QSize(1280, 1024));
......@@ -305,7 +303,6 @@ void QuickTilingTest::testQuickMaximizing()
QCOMPARE(c->geometryRestore(), QRect(0, 0, 100, 50));
// we got requested a new geometry
QVERIFY(configureRequestedSpy.wait());
QEXPECT_FAIL("", "Two configure events are sent for maximized", Continue);
QCOMPARE(configureRequestedSpy.count(), 3);
QCOMPARE(configureRequestedSpy.last().at(0).toSize(), QSize(100, 50));
......
......@@ -840,9 +840,7 @@ void TestXdgShellClientRules::testSizeApply()
QVERIFY(!client->isMove());
QVERIFY(!client->isResize());
QEXPECT_FAIL("", "Interactive resize is not spec-compliant", Continue);
QVERIFY(configureRequestedSpy->wait(10));
QEXPECT_FAIL("", "Interactive resize is not spec-compliant", Continue);
QCOMPARE(configureRequestedSpy->count(), 5);
// The rule should be applied again if the client appears after it's been closed.
......@@ -978,9 +976,7 @@ void TestXdgShellClientRules::testSizeRemember()
QVERIFY(!client->isMove());
QVERIFY(!client->isResize());
QEXPECT_FAIL("", "Interactive resize is not spec-compliant", Continue);
QVERIFY(configureRequestedSpy->wait(10));
QEXPECT_FAIL("", "Interactive resize is not spec-compliant", Continue);
QCOMPARE(configureRequestedSpy->count(), 5);
// If the client appears again, it should have the last known size.
......@@ -1380,6 +1376,7 @@ void TestXdgShellClientRules::testMaximizeApply()
workspace()->slotWindowMaximize();
QVERIFY(configureRequestedSpy->wait());
QCOMPARE(configureRequestedSpy->count(), 3);
QEXPECT_FAIL("", "Geometry restore is set to the first valid geometry", Continue);
QCOMPARE(configureRequestedSpy->last().at(0).toSize(), QSize(0, 0));
states = configureRequestedSpy->last().at(1).value<XdgShellSurface::States>();
QVERIFY(states.testFlag(XdgShellSurface::State::Activated));
......@@ -1492,6 +1489,7 @@ void TestXdgShellClientRules::testMaximizeRemember()
workspace()->slotWindowMaximize();
QVERIFY(configureRequestedSpy->wait());
QCOMPARE(configureRequestedSpy->count(), 3);
QEXPECT_FAIL("", "Geometry restore is set to the first valid geometry", Continue);
QCOMPARE(configureRequestedSpy->last().at(0).toSize(), QSize(0, 0));
states = configureRequestedSpy->last().at(1).value<XdgShellSurface::States>();
QVERIFY(states.testFlag(XdgShellSurface::State::Activated));
......
......@@ -430,6 +430,9 @@ void TestXdgShellClient::testFullscreen_data()
void TestXdgShellClient::testFullscreen()
{
// this test verifies that a window can be properly fullscreened
XdgShellSurface::States states;
QScopedPointer<Surface> surface(Test::createSurface());
QFETCH(Test::XdgShellSurfaceType, type);
QScopedPointer<XdgShellSurface> shellSurface(Test::createXdgShellSurface(type, surface.data()));
......@@ -445,52 +448,77 @@ void TestXdgShellClient::testFullscreen()
QVERIFY(decoSpy.wait());
QCOMPARE(deco->mode(), decoMode);
auto c = Test::renderAndWaitForShown(surface.data(), QSize(100, 50), Qt::blue);
QVERIFY(c);
QVERIFY(c->isActive());
QCOMPARE(c->layer(), NormalLayer);
QVERIFY(!c->isFullScreen());
QCOMPARE(c->clientSize(), QSize(100, 50));
QCOMPARE(c->isDecorated(), decoMode == ServerSideDecoration::Mode::Server);
QCOMPARE(c->clientSizeToFrameSize(c->clientSize()), c->frameGeometry().size());
QSignalSpy fullscreenChangedSpy(c, &AbstractClient::fullScreenChanged);
QVERIFY(fullscreenChangedSpy.isValid());
QSignalSpy frameGeometryChangedSpy(c, &AbstractClient::frameGeometryChanged);
auto client = Test::renderAndWaitForShown(surface.data(), QSize(100, 50), Qt::blue);
QVERIFY(client);
QVERIFY(client->isActive());
QCOMPARE(client->layer(), NormalLayer);
QVERIFY(!client->isFullScreen());
QCOMPARE(client->clientSize(), QSize(100, 50));
QCOMPARE(client->isDecorated(), decoMode == ServerSideDecoration::Mode::Server);
QCOMPARE(client->clientSizeToFrameSize(client->clientSize()), client->size());
QSignalSpy fullScreenChangedSpy(client, &AbstractClient::fullScreenChanged);
QVERIFY(fullScreenChangedSpy.isValid());
QSignalSpy frameGeometryChangedSpy(client, &AbstractClient::frameGeometryChanged);
QVERIFY(frameGeometryChangedSpy.isValid());
QSignalSpy sizeChangeRequestedSpy(shellSurface.data(), &XdgShellSurface::sizeChanged);
QVERIFY(sizeChangeRequestedSpy.isValid());
QSignalSpy configureRequestedSpy(shellSurface.data(), &XdgShellSurface::configureRequested);
QVERIFY(configureRequestedSpy.isValid());
// Wait for the compositor to send a configure event with the Activated state.
QVERIFY(configureRequestedSpy.wait());
QCOMPARE(configureRequestedSpy.count(), 1);
states = configureRequestedSpy.last().at(1).value<XdgShellSurface::States>();
QVERIFY(states & XdgShellSurface::State::Activated);
// Ask the compositor to show the window in full screen mode.
shellSurface->setFullscreen(true);
QVERIFY(fullscreenChangedSpy.wait());
QVERIFY(sizeChangeRequestedSpy.wait());
QCOMPARE(sizeChangeRequestedSpy.count(), 1);
QCOMPARE(sizeChangeRequestedSpy.first().first().toSize(), QSize(screens()->size(0)));
// TODO: should switch to fullscreen once it's updated
QVERIFY(c->isFullScreen());
QCOMPARE(c->clientSize(), QSize(100, 50));
QVERIFY(frameGeometryChangedSpy.isEmpty());
QVERIFY(configureRequestedSpy.wait());
QCOMPARE(configureRequestedSpy.count(), 2);
states = configureRequestedSpy.last().at(1).value<XdgShellSurface::States>();
QVERIFY(states & XdgShellSurface::State::Fullscreen);
QCOMPARE(configureRequestedSpy.last().at(0).value<QSize>(), screens()->size(0));
shellSurface->ackConfigure(configureRequestedSpy.last().at(2).value<quint32>());
Test::render(surface.data(), sizeChangeRequestedSpy.first().first().toSize(), Qt::red);
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(frameGeometryChangedSpy.count(), 1);
QVERIFY(c->isFullScreen());
QVERIFY(!c->isDecorated());
QCOMPARE(c->frameGeometry(), QRect(QPoint(0, 0), sizeChangeRequestedSpy.first().first().toSize()));
QCOMPARE(c->layer(), ActiveLayer);
QCOMPARE(fullScreenChangedSpy.count(), 1);
#endif
QVERIFY(client->isFullScreen());
QVERIFY(!client->isDecorated());
QCOMPARE(client->layer(), ActiveLayer);
QCOMPARE(client->frameGeometry(), QRect(QPoint(0, 0), screens()->size(0)));
// swap back to normal
// Ask the compositor to show the window in normal mode.
shellSurface->setFullscreen(false);
QVERIFY(fullscreenChangedSpy.wait());
QVERIFY(sizeChangeRequestedSpy.wait());
QCOMPARE(sizeChangeRequestedSpy.count(), 2);
QCOMPARE(sizeChangeRequestedSpy.last().first().toSize(), QSize(100, 50));
// TODO: should switch to fullscreen once it's updated
QVERIFY(!c->isFullScreen());
QCOMPARE(c->layer(), NormalLayer);
QCOMPARE(c->isDecorated(), decoMode == ServerSideDecoration::Mode::Server);
QVERIFY(configureRequestedSpy.wait());
QCOMPARE(configureRequestedSpy.count(), 3);
states = configureRequestedSpy.last().at(1).value<XdgShellSurface::States>();
QVERIFY(!(states & XdgShellSurface::State::Fullscreen));
QCOMPARE(configureRequestedSpy.last().at(0).value<QSize>(), QSize(100, 50));
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);
QCOMPARE(client->layer(), NormalLayer);
// Destroy the client.
shellSurface.reset();
QVERIFY(Test::waitForWindowDestroyed(client));
}
void TestXdgShellClient::testFullscreenRestore_data()
......@@ -646,6 +674,9 @@ void TestXdgShellClient::testMaximizedToFullscreen_data()
void TestXdgShellClient::testMaximizedToFullscreen()
{
// this test verifies that a window can be properly fullscreened after maximizing
XdgShellSurface::States states;
QScopedPointer<Surface> surface(Test::createSurface());
QFETCH(Test::XdgShellSurfaceType, type);
QScopedPointer<XdgShellSurface> shellSurface(Test::createXdgShellSurface(type, surface.data()));
......@@ -661,67 +692,81 @@ void TestXdgShellClient::testMaximizedToFullscreen()
QVERIFY(decoSpy.wait());
QCOMPARE(deco->mode(), decoMode);
auto c = Test::renderAndWaitForShown(surface.data(), QSize(100, 50), Qt::blue);
QVERIFY(c);
QVERIFY(c->isActive());
QVERIFY(!c->isFullScreen());
QCOMPARE(c->clientSize(), QSize(100, 50));
QCOMPARE(c->isDecorated(), decoMode == ServerSideDecoration::Mode::Server);
QSignalSpy fullscreenChangedSpy(c, &AbstractClient::fullScreenChanged);
auto client = Test::renderAndWaitForShown(surface.data(), QSize(100, 50), Qt::blue);
QVERIFY(client);
QVERIFY(client->isActive());
QVERIFY(!client->isFullScreen());
QCOMPARE(client->clientSize(), QSize(100, 50));
QCOMPARE(client->isDecorated(), decoMode == ServerSideDecoration::Mode::Server);
QSignalSpy fullscreenChangedSpy(client, &AbstractClient::fullScreenChanged);
QVERIFY(fullscreenChangedSpy.isValid());
QSignalSpy frameGeometryChangedSpy(c, &AbstractClient::frameGeometryChanged);
QSignalSpy frameGeometryChangedSpy(client, &AbstractClient::frameGeometryChanged);
QVERIFY(frameGeometryChangedSpy.isValid());
QSignalSpy sizeChangeRequestedSpy(shellSurface.data(), &XdgShellSurface::sizeChanged);
QVERIFY(sizeChangeRequestedSpy.isValid());
QSignalSpy configureRequestedSpy(shellSurface.data(), &XdgShellSurface::configureRequested);
QVERIFY(configureRequestedSpy.isValid());
// Wait for the compositor to send a configure event with the Activated state.
QVERIFY(configureRequestedSpy.wait());
QCOMPARE(configureRequestedSpy.count(), 1);
states = configureRequestedSpy.last().at(1).value<XdgShellSurface::States>();
QVERIFY(states & XdgShellSurface::State::Activated);
// Ask the compositor to maximize the window.
shellSurface->setMaximized(true);
QVERIFY(sizeChangeRequestedSpy.wait());
QCOMPARE(sizeChangeRequestedSpy.count(), 1);
QVERIFY(configureRequestedSpy.wait());
QCOMPARE(configureRequestedSpy.count(), 2);
states = configureRequestedSpy.last().at(1).value<XdgShellSurface::States>();
QVERIFY(states & XdgShellSurface::State::Maximized);
shellSurface->ackConfigure(configureRequestedSpy.last().at(2).value<quint32>());
Test::render(surface.data(), sizeChangeRequestedSpy.last().first().toSize(), Qt::red);
Test::render(surface.data(), configureRequestedSpy.last().at(0).value<QSize>(), Qt::red);
QVERIFY(frameGeometryChangedSpy.wait());
QCOMPARE(client->maximizeMode(), MaximizeFull);
QCOMPARE(c->maximizeMode(), MaximizeFull);
QCOMPARE(frameGeometryChangedSpy.isEmpty(), false);
frameGeometryChangedSpy.clear();
// fullscreen the window
// Ask the compositor to show the window in full screen mode.
shellSurface->setFullscreen(true);
QVERIFY(fullscreenChangedSpy.wait());
if (decoMode == ServerSideDecoration::Mode::Server) {
QVERIFY(sizeChangeRequestedSpy.wait());
QCOMPARE(sizeChangeRequestedSpy.count(), 2);
}
QCOMPARE(sizeChangeRequestedSpy.last().first().toSize(), QSize(screens()->size(0)));
// TODO: should switch to fullscreen once it's updated
QVERIFY(c->isFullScreen());
QVERIFY(configureRequestedSpy.wait());
QCOMPARE(configureRequestedSpy.count(), 3);
QCOMPARE(configureRequestedSpy.last().at(0).value<QSize>(), screens()->size(0));
states = configureRequestedSpy.last().at(1).value<XdgShellSurface::States>();
QVERIFY(states & XdgShellSurface::State::Maximized);
QVERIFY(states & XdgShellSurface::State::Fullscreen);
// render at the new size
shellSurface->ackConfigure(configureRequestedSpy.last().at(2).value<quint32>());
Test::render(surface.data(), sizeChangeRequestedSpy.last().first().toSize(), Qt::red);
Test::render(surface.data(), configureRequestedSpy.last().at(0).value<QSize>(), Qt::red);
QVERIFY(c->isFullScreen());
QVERIFY(!c->isDecorated());
QCOMPARE(c->frameGeometry(), QRect(QPoint(0, 0), sizeChangeRequestedSpy.last().first().toSize()));
sizeChangeRequestedSpy.clear();
#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
QCOMPARE(client->maximizeMode(), MaximizeFull);
QVERIFY(client->isFullScreen());
QVERIFY(!client->isDecorated());
// swap back to normal
// Switch back to normal mode.
shellSurface->setFullscreen(false);
shellSurface->setMaximized(false);
QVERIFY(fullscreenChangedSpy.wait());
if (decoMode == ServerSideDecoration::Mode::Server) {
QVERIFY(sizeChangeRequestedSpy.wait());
// XDG will legitimately get two updates. They might be batched
if (shellSurface && sizeChangeRequestedSpy.count() == 1) {
QVERIFY(sizeChangeRequestedSpy.wait());
}
QCOMPARE(sizeChangeRequestedSpy.last().first().toSize(), QSize(100, 50));
}
// TODO: should switch to fullscreen once it's updated
QVERIFY(!c->isFullScreen());
QCOMPARE(c->isDecorated(), decoMode == ServerSideDecoration::Mode::Server);
QVERIFY(configureRequestedSpy.wait());
QCOMPARE(configureRequestedSpy.count(), 4);
QCOMPARE(configureRequestedSpy.last().at(0).value<QSize>(), QSize(100, 50));
states = configureRequestedSpy.last().at(1).value<XdgShellSurface::States>();
QVERIFY(!(states & XdgShellSurface::State::Maximized));
QVERIFY(!(states & XdgShellSurface::State::Fullscreen));
shellSurface->ackConfigure(configureRequestedSpy.last().at(2).value<quint32>());
Test::render(surface.data(), configureRequestedSpy.last().at(0).value<QSize>(), Qt::red);
QVERIFY(frameGeometryChangedSpy.wait());
QVERIFY(!client->isFullScreen());
QCOMPARE(client->isDecorated(), decoMode == ServerSideDecoration::Mode::Server);
QCOMPARE(client->maximizeMode(), MaximizeRestore);
// Destroy the client.
shellSurface.reset();
QVERIFY(Test::waitForWindowDestroyed(client));
}
void TestXdgShellClient::testWindowOpensLargerThanScreen_data()
......@@ -753,10 +798,9 @@ void TestXdgShellClient::testWindowOpensLargerThanScreen()
auto c = Test::renderAndWaitForShown(surface.data(), screens()->size(0), Qt::blue);
QVERIFY(c);
QVERIFY(c->isActive());
QCOMPARE(c->clientSize(), screens()->size(0));
QVERIFY(c->isDecorated());
QEXPECT_FAIL("", "BUG 366632", Continue);
QVERIFY(sizeChangeRequestedSpy.wait(10));
QCOMPARE(c->frameGeometry(), QRect(QPoint(0, 0), screens()->size(0)));
}
void TestXdgShellClient::testHidden_data()
......@@ -1352,17 +1396,17 @@ void TestXdgShellClient::testXdgWindowGeometryAttachBuffer()
QVERIFY(frameGeometryChangedSpy.wait());
QCOMPARE(frameGeometryChangedSpy.count(), 2);
QCOMPARE(client->frameGeometry().topLeft(), oldPosition);
QCOMPARE(client->frameGeometry().size(), QSize(100, 50));
QCOMPARE(client->frameGeometry().size(), QSize(90, 40));
QCOMPARE(client->bufferGeometry().topLeft(), oldPosition - QPoint(10, 10));
QCOMPARE(client->bufferGeometry().size(), QSize(100, 50));
shellSurface->setWindowGeometry(QRect(5, 5, 90, 40));
shellSurface->setWindowGeometry(QRect(0, 0, 100, 50));
surface->commit(Surface::CommitFlag::None);
QVERIFY(frameGeometryChangedSpy.wait());
QCOMPARE(frameGeometryChangedSpy.count(), 3);
QCOMPARE(client->frameGeometry().topLeft(), oldPosition);
QCOMPARE(client->frameGeometry().size(), QSize(90, 40));
QCOMPARE(client->bufferGeometry().topLeft(), oldPosition - QPoint(5, 5));
QCOMPARE(client->frameGeometry().size(), QSize(100, 50));
QCOMPARE(client->bufferGeometry().topLeft(), oldPosition);
QCOMPARE(client->bufferGeometry().size(), QSize(100, 50));
shellSurface.reset();
......@@ -1497,13 +1541,10 @@ void TestXdgShellClient::testXdgWindowGeometryInteractiveResize()
client->keyPressEvent(Qt::Key_Enter);
QCOMPARE(clientFinishUserMovedResizedSpy.count(), 1);
QCOMPARE(workspace()->moveResizeClient(), nullptr);
#if 0
QEXPECT_FAIL("", "XdgShellClient currently doesn't send final configure event", Abort);
QVERIFY(configureRequestedSpy.wait());
QCOMPARE(configureRequestedSpy.count(), 5);
states = configureRequestedSpy.last().at(1).value<XdgShellSurface::States>();
QVERIFY(!states.testFlag(XdgShellSurface::State::Resizing));
#endif
shellSurface.reset();
QVERIFY(Test::waitForWindowDestroyed(client));
......
......@@ -25,7 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "group.h"
#include "netinfo.h"
#include "shadow.h"
#include "xdgshellclient.h"
#include "waylandclient.h"
#include "decorations/decoratedclient.h"
#include "decorations/decorationrenderer.h"
......@@ -149,7 +149,7 @@ void Deleted::copyToDeleted(Toplevel* c)
});
}
m_wasWaylandClient = qobject_cast<XdgShellClient *>(c) != nullptr;
m_wasWaylandClient = qobject_cast<WaylandClient *>(c) != nullptr;
m_wasX11Client = qobject_cast<X11Client *>(c) != nullptr;
m_wasPopupWindow = c->isPopupWindow();
m_wasOutline = c->isOutline();
......
......@@ -55,7 +55,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "composite.h"
#include "xcbutils.h"
#include "platform.h"
#include "xdgshellclient.h"
#include "waylandclient.h"
#include "wayland_server.h"
#include "decorations/decorationbridge.h"
......@@ -1738,7 +1738,7 @@ EffectWindowImpl::EffectWindowImpl(Toplevel *toplevel)
// can still figure out whether it is/was a managed window.
managed = toplevel->isClient();
waylandClient = qobject_cast<KWin::XdgShellClient *>(toplevel) != nullptr;
waylandClient = qobject_cast<KWin::WaylandClient *>(toplevel) != nullptr;
x11Client = qobject_cast<KWin::X11Client *>(toplevel) != nullptr ||
qobject_cast<KWin::Unmanaged *>(toplevel) != nullptr;
}
......
......@@ -210,7 +210,7 @@ void Placement::placeSmart(AbstractClient* c, const QRect& area, Policy /*next*/
* with ideas from xfce.
*/
if (!c->size().isValid()) {
if (!c->frameGeometry().isValid()) {
return;
}
......@@ -385,7 +385,7 @@ void Placement::placeCascaded(AbstractClient *c, const QRect &area, Policy nextP
{
Q_ASSERT(area.isValid());
if (!c->size().isValid()) {
if (!c->frameGeometry().isValid()) {
return;
}
......
......@@ -23,8 +23,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "composite.h"
#include "idle_inhibition.h"
#include "screens.h"
#include "xdgshellclient.h"
#include "workspace.h"
#include "xdgshellclient.h"
// Client
#include <KWayland/Client/connection_thread.h>
......@@ -59,7 +59,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <KWaylandServer/blur_interface.h>
#include <KWaylandServer/outputmanagement_interface.h>
#include <KWaylandServer/outputconfiguration_interface.h>
#include <KWaylandServer/xdgdecoration_interface.h>
#include <KWaylandServer/xdgdecoration_v1_interface.h>
#include <KWaylandServer/xdgshell_interface.h>
#include <KWaylandServer/xdgforeign_interface.h>
#include <KWaylandServer/xdgoutput_interface.h>
......@@ -144,52 +144,67 @@ void WaylandServer::terminateClientConnections()
}
}