19#include <KWayland/Client/compositor.h>
20#include <KWayland/Client/shm_pool.h>
21#include <KWayland/Client/surface.h>
23#include <KDecoration2/DecoratedClient>
24#include <KDecoration2/Decoration>
25#include <KDecoration2/DecorationSettings>
31static const QString s_socketName = QStringLiteral(
"wayland_test_kwin_maximized-0");
41 void testMaximizedPassedToDeco();
42 void testInitiallyMaximizedBorderless();
43 void testBorderlessMaximizedWindow();
44 void testMaximizedGainFocusAndBeActivated();
47void TestMaximized::initTestCase()
49 qRegisterMetaType<KWin::Window *>();
53 QRect(0, 0, 1280, 1024),
54 QRect(1280, 0, 1280, 1024),
57 kwinApp()->setConfig(KSharedConfig::openConfig(QString(), KConfig::SimpleConfig));
60 QVERIFY(applicationStartedSpy.wait());
63 QCOMPARE(outputs[0]->geometry(), QRect(0, 0, 1280, 1024));
64 QCOMPARE(outputs[1]->geometry(), QRect(1280, 0, 1280, 1024));
67void TestMaximized::init()
75void TestMaximized::cleanup()
80 auto group = kwinApp()->config()->group(QStringLiteral(
"Windows"));
81 group.writeEntry(
"BorderlessMaximizedWindows",
false);
87void TestMaximized::testMaximizedPassedToDeco()
98 surface->commit(KWayland::Client::Surface::CommitFlag::None);
99 QVERIFY(surfaceConfigureRequestedSpy.wait());
101 shellSurface->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.last().at(0).value<quint32>());
104 QVERIFY(window->isDecorated());
106 auto decoration = window->decoration();
108 QCOMPARE(window->maximizeMode(), MaximizeMode::MaximizeRestore);
111 QVERIFY(surfaceConfigureRequestedSpy.wait());
112 QCOMPARE(surfaceConfigureRequestedSpy.count(), 2);
119 QSignalSpy bordersChangedSpy(decoration, &KDecoration2::Decoration::bordersChanged);
120 QSignalSpy maximizedChangedSpy(decoration->client(), &KDecoration2::DecoratedClient::maximizedChanged);
121 QSignalSpy frameGeometryChangedSpy(window, &Window::frameGeometryChanged);
124 QVERIFY(surfaceConfigureRequestedSpy.wait());
125 QCOMPARE(surfaceConfigureRequestedSpy.count(), 3);
126 QCOMPARE(toplevelConfigureRequestedSpy.last().at(0).toSize(), QSize(1280, 1024 - decoration->borderTop()));
127 shellSurface->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.last().at(0).value<quint32>());
128 Test::render(surface.get(), toplevelConfigureRequestedSpy.last().at(0).toSize(), Qt::red);
129 QVERIFY(frameGeometryChangedSpy.wait());
132 QCOMPARE(frameGeometryChangedSpy.count(), hasBorders ? 2 : 1);
133 QCOMPARE(window->maximizeMode(), MaximizeMode::MaximizeFull);
134 QCOMPARE(maximizedChangedSpy.count(), 1);
135 QCOMPARE(maximizedChangedSpy.last().first().toBool(),
true);
136 QCOMPARE(bordersChangedSpy.count(), hasBorders ? 1 : 0);
137 QCOMPARE(decoration->borderLeft(), 0);
138 QCOMPARE(decoration->borderBottom(), 0);
139 QCOMPARE(decoration->borderRight(), 0);
140 QVERIFY(decoration->borderTop() != 0);
144 QVERIFY(surfaceConfigureRequestedSpy.wait());
145 QCOMPARE(surfaceConfigureRequestedSpy.count(), 4);
146 QCOMPARE(toplevelConfigureRequestedSpy.last().at(0).toSize(), QSize(100, 50));
148 shellSurface->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.last().at(0).value<quint32>());
150 QVERIFY(frameGeometryChangedSpy.wait());
151 QCOMPARE(frameGeometryChangedSpy.count(), hasBorders ? 4 : 2);
152 QCOMPARE(window->maximizeMode(), MaximizeMode::MaximizeRestore);
153 QCOMPARE(maximizedChangedSpy.count(), 2);
154 QCOMPARE(maximizedChangedSpy.last().first().toBool(),
false);
155 QCOMPARE(bordersChangedSpy.count(), hasBorders ? 2 : 0);
156 QVERIFY(decoration->borderTop() != 0);
157 QVERIFY(decoration->borderLeft() != !hasBorders);
158 QVERIFY(decoration->borderRight() != !hasBorders);
159 QVERIFY(decoration->borderBottom() != !hasBorders);
162 shellSurface.reset();
166void TestMaximized::testInitiallyMaximizedBorderless()
171 auto group = kwinApp()->config()->group(QStringLiteral(
"Windows"));
172 group.writeEntry(
"BorderlessMaximizedWindows",
true);
184 shellSurface->set_maximized();
186 decoration->set_mode(Test::XdgToplevelDecorationV1::mode_server_side);
187 surface->commit(KWayland::Client::Surface::CommitFlag::None);
190 Test::XdgToplevel::States states;
191 QVERIFY(surfaceConfigureRequestedSpy.wait());
192 QCOMPARE(surfaceConfigureRequestedSpy.count(), 1);
193 QCOMPARE(toplevelConfigureRequestedSpy.last().at(0).toSize(), QSize(1280, 1024));
194 states = toplevelConfigureRequestedSpy.last().at(1).value<Test::XdgToplevel::States>();
195 QVERIFY(!states.testFlag(Test::XdgToplevel::State::Activated));
196 QVERIFY(states.testFlag(Test::XdgToplevel::State::Maximized));
198 shellSurface->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.last().at(0).value<quint32>());
201 QVERIFY(!window->isDecorated());
202 QVERIFY(window->isActive());
203 QVERIFY(window->isMaximizable());
204 QCOMPARE(window->maximizeMode(), MaximizeMode::MaximizeFull);
205 QCOMPARE(window->requestedMaximizeMode(), MaximizeMode::MaximizeFull);
206 QCOMPARE(window->frameGeometry(), QRect(0, 0, 1280, 1024));
207 QCOMPARE(decorationConfigureRequestedSpy.last().at(0).value<Test::XdgToplevelDecorationV1::mode>(),
208 Test::XdgToplevelDecorationV1::mode_server_side);
211 shellSurface.reset();
215void TestMaximized::testBorderlessMaximizedWindow()
221 auto group = kwinApp()->config()->group(QStringLiteral(
"Windows"));
222 group.writeEntry(
"BorderlessMaximizedWindows",
true);
235 decoration->set_mode(Test::XdgToplevelDecorationV1::mode_server_side);
236 surface->commit(KWayland::Client::Surface::CommitFlag::None);
239 Test::XdgToplevel::States states;
240 QVERIFY(surfaceConfigureRequestedSpy.wait());
241 QCOMPARE(surfaceConfigureRequestedSpy.count(), 1);
242 QCOMPARE(toplevelConfigureRequestedSpy.last().at(0).toSize(), QSize(0, 0));
243 states = toplevelConfigureRequestedSpy.last().at(1).value<Test::XdgToplevel::States>();
244 QVERIFY(!states.testFlag(Test::XdgToplevel::State::Activated));
245 QVERIFY(!states.testFlag(Test::XdgToplevel::State::Maximized));
248 shellSurface->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.last().at(0).value<quint32>());
251 QVERIFY(window->isActive());
252 QCOMPARE(window->maximizeMode(), MaximizeMode::MaximizeRestore);
253 QCOMPARE(window->requestedMaximizeMode(), MaximizeMode::MaximizeRestore);
254 QCOMPARE(window->isDecorated(),
true);
257 QVERIFY(surfaceConfigureRequestedSpy.wait());
258 QCOMPARE(surfaceConfigureRequestedSpy.count(), 2);
259 states = toplevelConfigureRequestedSpy.last().at(1).value<Test::XdgToplevel::States>();
260 QVERIFY(states.testFlag(Test::XdgToplevel::State::Activated));
261 QVERIFY(!states.testFlag(Test::XdgToplevel::State::Maximized));
264 const QRectF maximizeRestoreGeometry = window->frameGeometry();
266 QVERIFY(surfaceConfigureRequestedSpy.wait());
267 QCOMPARE(surfaceConfigureRequestedSpy.count(), 3);
268 QCOMPARE(toplevelConfigureRequestedSpy.last().at(0).toSize(), QSize(1280, 1024));
269 states = toplevelConfigureRequestedSpy.last().at(1).value<Test::XdgToplevel::States>();
270 QVERIFY(states.testFlag(Test::XdgToplevel::State::Activated));
271 QVERIFY(states.testFlag(Test::XdgToplevel::State::Maximized));
273 QSignalSpy frameGeometryChangedSpy(window, &Window::frameGeometryChanged);
274 shellSurface->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.last().at(0).value<quint32>());
275 Test::render(surface.get(), QSize(1280, 1024), Qt::blue);
276 QVERIFY(frameGeometryChangedSpy.wait());
277 QCOMPARE(window->frameGeometry(), QRect(0, 0, 1280, 1024));
278 QCOMPARE(window->maximizeMode(), MaximizeMode::MaximizeFull);
279 QCOMPARE(window->requestedMaximizeMode(), MaximizeMode::MaximizeFull);
280 QCOMPARE(window->isDecorated(),
false);
284 QVERIFY(surfaceConfigureRequestedSpy.wait());
285 QCOMPARE(surfaceConfigureRequestedSpy.count(), 4);
286 QCOMPARE(toplevelConfigureRequestedSpy.last().at(0).toSize(), QSize(100, 50));
287 states = toplevelConfigureRequestedSpy.last().at(1).value<Test::XdgToplevel::States>();
288 QVERIFY(states.testFlag(Test::XdgToplevel::State::Activated));
289 QVERIFY(!states.testFlag(Test::XdgToplevel::State::Maximized));
291 shellSurface->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.last().at(0).value<quint32>());
293 QVERIFY(frameGeometryChangedSpy.wait());
294 QCOMPARE(window->frameGeometry(), maximizeRestoreGeometry);
295 QCOMPARE(window->maximizeMode(), MaximizeMode::MaximizeRestore);
296 QCOMPARE(window->requestedMaximizeMode(), MaximizeMode::MaximizeRestore);
297 QCOMPARE(window->isDecorated(),
true);
300 shellSurface.reset();
304void TestMaximized::testMaximizedGainFocusAndBeActivated()
314 QVERIFY(!window->isActive());
315 QVERIFY(window2->isActive());
316 QCOMPARE(
workspace()->stackingOrder(), (QList<Window *>{window, window2}));
320 QVERIFY(window->isActive());
321 QVERIFY(!window2->isActive());
322 QCOMPARE(
workspace()->stackingOrder(), (QList<Window *>{window2, window}));
324 xdgShellSurface.reset();
326 xdgShellSurface2.reset();
331#include "maximize_test.moc"
std::unique_ptr< KDecoration2::DecorationSettingsPrivate > settings(KDecoration2::DecorationSettings *parent) override
bool borderlessMaximizedWindows
void configureRequested(quint32 serial)
void configureRequested(QtWayland::zxdg_toplevel_decoration_v1::mode mode)
void configureRequested(const QSize &size, KWin::Test::XdgToplevel::States states)
void slotWindowMaximize()
void performWindowOperation(KWin::Window *window, Options::WindowOperation op)
Decoration::DecorationBridge * decorationBridge() const
static Workspace * self()
QList< Output * > outputs() const
void setActiveOutput(Output *output)
#define WAYLANDTEST_MAIN(TestObject)
Window * renderAndWaitForShown(KWayland::Client::Surface *surface, const QSize &size, const QColor &color, const QImage::Format &format=QImage::Format_ARGB32, int timeout=5000)
void destroyWaylandConnection()
void setOutputConfig(const QList< QRect > &geometries)
bool setupWaylandConnection(AdditionalWaylandInterfaces flags=AdditionalWaylandInterfaces())
void render(KWayland::Client::Surface *surface, const QSize &size, const QColor &color, const QImage::Format &format=QImage::Format_ARGB32_Premultiplied)
QList< KWayland::Client::Output * > outputs
std::unique_ptr< KWayland::Client::Surface > createSurface()
XdgToplevel * createXdgToplevelSurface(KWayland::Client::Surface *surface, QObject *parent=nullptr)
XdgToplevelDecorationV1 * createXdgToplevelDecorationV1(XdgToplevel *toplevel, QObject *parent=nullptr)
bool waitForWindowClosed(Window *window)
WaylandServer * waylandServer()
InputRedirection * input()