diff --git a/autotests/client/test_server_side_decoration.cpp b/autotests/client/test_server_side_decoration.cpp --- a/autotests/client/test_server_side_decoration.cpp +++ b/autotests/client/test_server_side_decoration.cpp @@ -47,6 +47,9 @@ void testSurfaceDestroy(); + void testPalette_data(); + void testPalette(); + private: KWayland::Server::Display *m_display = nullptr; KWayland::Server::CompositorInterface *m_compositorInterface = nullptr; @@ -324,5 +327,49 @@ QVERIFY(decorationDestroyedSpy.wait()); } +void TestServerSideDecoration::testPalette_data() +{ + QTest::addColumn("paletteName"); + QTest::newRow("blank") << QString(); + QTest::newRow("name") << QString("foobar"); + QTest::newRow("path") << QString("/usr/share/foobar"); +} + +void TestServerSideDecoration::testPalette() +{ + using namespace KWayland::Client; + using namespace KWayland::Server; + QSignalSpy serverSurfaceCreated(m_compositorInterface, &CompositorInterface::surfaceCreated); + QSignalSpy decorationCreated(m_serverSideDecorationManagerInterface, &ServerSideDecorationManagerInterface::decorationCreated); + + QScopedPointer surface(m_compositor->createSurface()); + QVERIFY(serverSurfaceCreated.wait()); + + auto serverSurface = serverSurfaceCreated.first().first().value(); + QScopedPointer serverSideDecoration(m_serverSideDecorationManager->create(surface.data())); + QCOMPARE(serverSideDecoration->mode(), ServerSideDecoration::Mode::None); + QVERIFY(decorationCreated.wait()); + auto serverDeco = decorationCreated.first().first().value(); + QVERIFY(serverDeco); + + QFETCH(QString, paletteName); + + QSignalSpy paletteChanged(serverDeco, &KWayland::Server::ServerSideDecorationInterface::paletteChanged); + QVERIFY(serverDeco->palette().isEmpty()); + + //client sets a new palette + serverSideDecoration->setPalette(paletteName); + + if (paletteName.isEmpty()) { + //no-change == no emit + QVERIFY(!paletteChanged.wait()); + } else { + QVERIFY(paletteChanged.wait()); + } + + QCOMPARE(serverDeco->palette(), paletteName); +} + + QTEST_GUILESS_MAIN(TestServerSideDecoration) #include "test_server_side_decoration.moc" diff --git a/src/client/protocols/server-decoration.xml b/src/client/protocols/server-decoration.xml --- a/src/client/protocols/server-decoration.xml +++ b/src/client/protocols/server-decoration.xml @@ -16,7 +16,7 @@ You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . ]]> - + This interface allows to coordinate whether the server should create a server-side window decoration around a wl_surface representing a @@ -58,7 +58,7 @@ - + @@ -90,5 +90,10 @@ + + + + diff --git a/src/client/registry.cpp b/src/client/registry.cpp --- a/src/client/registry.cpp +++ b/src/client/registry.cpp @@ -235,7 +235,7 @@ &Registry::dpmsRemoved }}, {Registry::Interface::ServerSideDecorationManager, { - 1, + 2, QByteArrayLiteral("org_kde_kwin_server_decoration_manager"), &org_kde_kwin_server_decoration_manager_interface, &Registry::serverSideDecorationManagerAnnounced, diff --git a/src/client/server_decoration.h b/src/client/server_decoration.h --- a/src/client/server_decoration.h +++ b/src/client/server_decoration.h @@ -227,6 +227,13 @@ **/ Mode defaultMode() const; + /* + * Color scheme that should be applied to the window decoration. + * If set to empty the default palette will be used. + * @since 5.CHANGETHIS + */ + void setPalette(const QString &paletteName); + operator org_kde_kwin_server_decoration*(); operator org_kde_kwin_server_decoration*() const; diff --git a/src/client/server_decoration.cpp b/src/client/server_decoration.cpp --- a/src/client/server_decoration.cpp +++ b/src/client/server_decoration.cpp @@ -285,6 +285,15 @@ return d->mode; } +void ServerSideDecoration::setPalette(const QString &palette) +{ + Q_ASSERT(d->serversidedecoration.isValid()); + if(wl_proxy_get_version(d->serversidedecoration) < ORG_KDE_KWIN_SERVER_DECORATION_SET_PALETTE_SINCE_VERSION) { + return; + } + org_kde_kwin_server_decoration_set_palette(d->serversidedecoration, palette.toUtf8().constData()); +} + ServerSideDecoration::Mode ServerSideDecoration::defaultMode() const { return d->defaultMode; diff --git a/src/server/server_decoration_interface.h b/src/server/server_decoration_interface.h --- a/src/server/server_decoration_interface.h +++ b/src/server/server_decoration_interface.h @@ -125,6 +125,12 @@ **/ static ServerSideDecorationInterface *get(SurfaceInterface *surface); + /** + * @returns the palette requested by the client. + * @since 5.FIXME + */ + QString palette() const; + Q_SIGNALS: /** * The client requested the provided mode. @@ -134,6 +140,12 @@ **/ void modeRequested(KWayland::Server::ServerSideDecorationManagerInterface::Mode); + /** + * Emitted when the client requests a different palette + * @since 5.FIXME + */ + void paletteChanged(const QString &paletteName); + private: explicit ServerSideDecorationInterface(ServerSideDecorationManagerInterface *parent, SurfaceInterface *surface, wl_resource *parentResource); friend class ServerSideDecorationManagerInterface; diff --git a/src/server/server_decoration_interface.cpp b/src/server/server_decoration_interface.cpp --- a/src/server/server_decoration_interface.cpp +++ b/src/server/server_decoration_interface.cpp @@ -58,7 +58,7 @@ static const quint32 s_version; }; -const quint32 ServerSideDecorationManagerInterface::Private::s_version = 1; +const quint32 ServerSideDecorationManagerInterface::Private::s_version = 2; #ifndef DOXYGEN_SHOULD_SKIP_THIS const struct org_kde_kwin_server_decoration_manager_interface ServerSideDecorationManagerInterface::Private::s_interface = { @@ -171,11 +171,13 @@ ServerSideDecorationManagerInterface::Mode mode = ServerSideDecorationManagerInterface::Mode::None; SurfaceInterface *surface; + QString palette; static ServerSideDecorationInterface *get(SurfaceInterface *s); private: static void requestModeCallback(wl_client *client, wl_resource *resource, uint32_t mode); + static void setPaletteCallback(wl_client *client, wl_resource *resource, const char *palette); ServerSideDecorationInterface *q_func() { return reinterpret_cast(q); @@ -188,7 +190,8 @@ #ifndef DOXYGEN_SHOULD_SKIP_THIS const struct org_kde_kwin_server_decoration_interface ServerSideDecorationInterface::Private::s_interface = { resourceDestroyedCallback, - requestModeCallback + requestModeCallback, + setPaletteCallback }; QVector ServerSideDecorationInterface::Private::s_all; #endif @@ -215,6 +218,18 @@ emit cast(resource)->q_func()->modeRequested(m); } +void ServerSideDecorationInterface::Private::setPaletteCallback(wl_client *client, wl_resource *resource, const char* p) +{ + Q_UNUSED(client); + auto d = cast(resource); + QString paletteName = QString::fromUtf8(p); + if (d->palette == paletteName) { + return; + } + emit d->q_func()->paletteChanged(paletteName); + d->palette = paletteName; +} + ServerSideDecorationInterface *ServerSideDecorationInterface::Private::get(SurfaceInterface *s) { auto it = std::find_if(s_all.constBegin(), s_all.constEnd(), [s] (Private *p) { return p->surface == s; }); @@ -263,6 +278,12 @@ return d->surface; } +QString ServerSideDecorationInterface::palette() const +{ + Q_D(); + return d->palette; +} + ServerSideDecorationInterface::Private *ServerSideDecorationInterface::d_func() const { return reinterpret_cast(d.data());