diff --git a/src/wayland/CMakeLists.txt b/src/wayland/CMakeLists.txt
index 466363466f..25f42634b6 100644
--- a/src/wayland/CMakeLists.txt
+++ b/src/wayland/CMakeLists.txt
@@ -12,6 +12,7 @@ set(SERVER_LIB_SRCS
logging.cpp
output_interface.cpp
pointer_interface.cpp
+ plasmashell_interface.cpp
region_interface.cpp
resource.cpp
seat_interface.cpp
@@ -21,6 +22,11 @@ set(SERVER_LIB_SRCS
touch_interface.cpp
)
+ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
+ PROTOCOL ${KWAYLAND_SOURCE_DIR}/src/client/protocols/plasma-shell.xml
+ BASENAME plasma-shell
+)
+
add_library(KF5WaylandServer ${SERVER_LIB_SRCS})
generate_export_header(KF5WaylandServer
BASE_NAME
@@ -68,6 +74,7 @@ install(FILES
keyboard_interface.h
output_interface.h
pointer_interface.h
+ plasmashell_interface.h
region_interface.h
resource.h
seat_interface.h
diff --git a/src/wayland/display.cpp b/src/wayland/display.cpp
index 1796f53f9e..fd985f8eb3 100644
--- a/src/wayland/display.cpp
+++ b/src/wayland/display.cpp
@@ -22,6 +22,7 @@ License along with this library. If not, see .
#include "datadevicemanager_interface.h"
#include "logging_p.h"
#include "output_interface.h"
+#include "plasmashell_interface.h"
#include "seat_interface.h"
#include "shell_interface.h"
#include "subcompositor_interface.h"
@@ -223,6 +224,13 @@ DataDeviceManagerInterface *Display::createDataDeviceManager(QObject *parent)
return m;
}
+PlasmaShellInterface *Display::createPlasmaShell(QObject* parent)
+{
+ auto s = new PlasmaShellInterface(this, parent);
+ connect(this, &Display::aboutToTerminate, s, [this, s] { delete s; });
+ return s;
+}
+
void Display::createShm()
{
Q_ASSERT(d->display);
diff --git a/src/wayland/display.h b/src/wayland/display.h
index 74865992df..ea004e316a 100644
--- a/src/wayland/display.h
+++ b/src/wayland/display.h
@@ -39,6 +39,7 @@ namespace Server
class CompositorInterface;
class DataDeviceManagerInterface;
class OutputInterface;
+class PlasmaShellInterface;
class SeatInterface;
class ShellInterface;
class SubCompositorInterface;
@@ -114,6 +115,7 @@ public:
SeatInterface *createSeat(QObject *parent = nullptr);
SubCompositorInterface *createSubCompositor(QObject *parent = nullptr);
DataDeviceManagerInterface *createDataDeviceManager(QObject *parent = nullptr);
+ PlasmaShellInterface *createPlasmaShell(QObject *parent = nullptr);
/**
* Gets the ClientConnection for the given @p client.
diff --git a/src/wayland/plasmashell_interface.cpp b/src/wayland/plasmashell_interface.cpp
new file mode 100644
index 0000000000..4bf4f785e2
--- /dev/null
+++ b/src/wayland/plasmashell_interface.cpp
@@ -0,0 +1,258 @@
+/********************************************************************
+Copyright 2015 Martin Gräßlin
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) version 3, or any
+later version accepted by the membership of KDE e.V. (or its
+successor approved by the membership of KDE e.V.), which shall
+act as a proxy defined in Section 6 of version 3 of the license.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library. If not, see .
+*********************************************************************/
+#include "plasmashell_interface.h"
+#include "global_p.h"
+#include "resource_p.h"
+#include "display.h"
+#include "surface_interface.h"
+
+#include
+
+#include
+#include
+
+namespace KWayland
+{
+namespace Server
+{
+
+static const quint32 s_version = 1;
+
+class PlasmaShellInterface::Private : public Global::Private
+{
+public:
+ Private(PlasmaShellInterface *q, Display *d);
+
+ QList surfaces;
+
+private:
+ static void createSurfaceCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface);
+ void bind(wl_client *client, uint32_t version, uint32_t id) override;
+ void createSurface(wl_client *client, uint32_t version, uint32_t id, SurfaceInterface *surface, wl_resource *parentResource);
+
+ PlasmaShellInterface *q;
+ static const struct org_kde_plasma_shell_interface s_interface;
+};
+
+PlasmaShellInterface::Private::Private(PlasmaShellInterface *q, Display *d)
+ : Global::Private(d, &org_kde_plasma_shell_interface, s_version)
+ , q(q)
+{
+}
+
+const struct org_kde_plasma_shell_interface PlasmaShellInterface::Private::s_interface = {
+ createSurfaceCallback
+};
+
+
+
+class PlasmaShellSurfaceInterface::Private : public Resource::Private
+{
+public:
+ Private(PlasmaShellSurfaceInterface *q, PlasmaShellInterface *shell, SurfaceInterface *surface, wl_resource *parentResource);
+
+ SurfaceInterface *surface;
+ QPoint m_globalPos;
+ Role m_role;
+ bool m_positionSet = false;
+
+private:
+ // interface callbacks
+ static void destroyCallback(wl_client *client, wl_resource *resource);
+ static void setOutputCallback(wl_client *client, wl_resource *resource, wl_resource *output);
+ static void setPositionCallback(wl_client *client, wl_resource *resource, int32_t x, int32_t y);
+ static void setRoleCallback(wl_client *client, wl_resource *resource, uint32_t role);
+
+ void setPosition(const QPoint &globalPos);
+ void setRole(uint32_t role);
+
+ PlasmaShellSurfaceInterface *q_func() {
+ return reinterpret_cast(q);
+ }
+
+ static const struct org_kde_plasma_surface_interface s_interface;
+};
+
+PlasmaShellInterface::PlasmaShellInterface(Display *display, QObject *parent)
+ : Global(new Private(this, display), parent)
+{
+}
+
+PlasmaShellInterface::~PlasmaShellInterface() = default;
+
+void PlasmaShellInterface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
+{
+ auto c = display->getConnection(client);
+ wl_resource *shell = c->createResource(&org_kde_plasma_shell_interface, qMin(version, s_version), id);
+ if (!shell) {
+ wl_client_post_no_memory(client);
+ return;
+ }
+ wl_resource_set_implementation(shell, &s_interface, this, nullptr);
+}
+
+void PlasmaShellInterface::Private::createSurfaceCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface)
+{
+ auto s = reinterpret_cast(wl_resource_get_user_data(resource));
+ s->createSurface(client, wl_resource_get_version(resource), id, SurfaceInterface::get(surface), resource);
+}
+
+void PlasmaShellInterface::Private::createSurface(wl_client *client, uint32_t version, uint32_t id, SurfaceInterface *surface, wl_resource *parentResource)
+{
+ auto it = std::find_if(surfaces.constBegin(), surfaces.constEnd(),
+ [surface](PlasmaShellSurfaceInterface *s) {
+ return surface == s->surface();
+ }
+ );
+ if (it != surfaces.constEnd()) {
+ wl_resource_post_error(surface->resource(), WL_DISPLAY_ERROR_INVALID_OBJECT, "PlasmaShellSurface already created");
+ return;
+ }
+ PlasmaShellSurfaceInterface *shellSurface = new PlasmaShellSurfaceInterface(q, surface, parentResource);
+ surfaces << shellSurface;
+ QObject::connect(shellSurface, &PlasmaShellSurfaceInterface::destroyed, q,
+ [this, shellSurface] {
+ surfaces.removeAll(shellSurface);
+ }
+ );
+ shellSurface->d->create(display->getConnection(client), version, id);
+ emit q->surfaceCreated(shellSurface);
+}
+
+/*********************************
+ * ShellSurfaceInterface
+ *********************************/
+PlasmaShellSurfaceInterface::Private::Private(PlasmaShellSurfaceInterface *q, PlasmaShellInterface *shell, SurfaceInterface *surface, wl_resource *parentResource)
+ : Resource::Private(q, shell, parentResource, &org_kde_plasma_surface_interface, &s_interface)
+ , surface(surface)
+{
+}
+
+const struct org_kde_plasma_surface_interface PlasmaShellSurfaceInterface::Private::s_interface = {
+ destroyCallback,
+ setOutputCallback,
+ setPositionCallback,
+ setRoleCallback
+};
+
+PlasmaShellSurfaceInterface::PlasmaShellSurfaceInterface(PlasmaShellInterface *shell, SurfaceInterface *parent, wl_resource *parentResource)
+ : Resource(new Private(this, shell, parent, parentResource), parent)
+{
+}
+
+PlasmaShellSurfaceInterface::~PlasmaShellSurfaceInterface() = default;
+
+SurfaceInterface *PlasmaShellSurfaceInterface::surface() const {
+ Q_D();
+ return d->surface;
+}
+
+PlasmaShellInterface *PlasmaShellSurfaceInterface::shell() const {
+ Q_D();
+ return reinterpret_cast(d->global);
+}
+
+PlasmaShellSurfaceInterface::Private *PlasmaShellSurfaceInterface::d_func() const
+{
+ return reinterpret_cast(d.data());
+}
+
+void PlasmaShellSurfaceInterface::Private::destroyCallback(wl_client *client, wl_resource *resource)
+{
+ Q_UNUSED(client)
+ wl_resource_destroy(resource);
+}
+
+void PlasmaShellSurfaceInterface::Private::setOutputCallback(wl_client *client, wl_resource *resource, wl_resource *output)
+{
+ Q_UNUSED(client)
+ Q_UNUSED(resource)
+ Q_UNUSED(output)
+ // TODO: implement
+}
+
+void PlasmaShellSurfaceInterface::Private::setPositionCallback(wl_client *client, wl_resource *resource, int32_t x, int32_t y)
+{
+ auto s = cast(resource);
+ Q_ASSERT(client == *s->client);
+ s->setPosition(QPoint(x, y));
+}
+
+void PlasmaShellSurfaceInterface::Private::setPosition(const QPoint &globalPos)
+{
+ if (m_globalPos == globalPos && m_positionSet) {
+ return;
+ }
+ m_positionSet = true;
+ m_globalPos = globalPos;
+ Q_Q(PlasmaShellSurfaceInterface);
+ emit q->positionChanged();
+}
+
+void PlasmaShellSurfaceInterface::Private::setRoleCallback(wl_client *client, wl_resource *resource, uint32_t role)
+{
+ auto s = cast(resource);
+ Q_ASSERT(client == *s->client);
+ s->setRole(role);
+}
+
+void PlasmaShellSurfaceInterface::Private::setRole(uint32_t role)
+{
+ Role r = Role::Normal;
+ switch (role) {
+ case ORG_KDE_PLASMA_SURFACE_ROLE_DESKTOP:
+ r = Role::Desktop;
+ break;
+ case ORG_KDE_PLASMA_SURFACE_ROLE_PANEL:
+ r = Role::Panel;
+ break;
+ case ORG_KDE_PLASMA_SURFACE_ROLE_NORMAL:
+ default:
+ r = Role::Normal;
+ break;
+ }
+ if (r == m_role) {
+ return;
+ }
+ m_role = r;
+ Q_Q(PlasmaShellSurfaceInterface);
+ emit q->roleChanged();
+}
+
+QPoint PlasmaShellSurfaceInterface::position() const
+{
+ Q_D();
+ return d->m_globalPos;
+}
+
+PlasmaShellSurfaceInterface::Role PlasmaShellSurfaceInterface::role() const
+{
+ Q_D();
+ return d->m_role;
+}
+
+bool PlasmaShellSurfaceInterface::isPositionSet() const
+{
+ Q_D();
+ return d->m_positionSet;
+}
+
+}
+}
diff --git a/src/wayland/plasmashell_interface.h b/src/wayland/plasmashell_interface.h
new file mode 100644
index 0000000000..2e07a52594
--- /dev/null
+++ b/src/wayland/plasmashell_interface.h
@@ -0,0 +1,90 @@
+/********************************************************************
+Copyright 2015 Martin Gräßlin
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) version 3, or any
+later version accepted by the membership of KDE e.V. (or its
+successor approved by the membership of KDE e.V.), which shall
+act as a proxy defined in Section 6 of version 3 of the license.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library. If not, see .
+*********************************************************************/
+#ifndef WAYLAND_SERVER_PLASMA_SHELL_INTERFACE_H
+#define WAYLAND_SERVER_PLASMA_SHELL_INTERFACE_H
+
+#include
+
+#include
+
+#include "global.h"
+#include "resource.h"
+
+class QSize;
+struct wl_resource;
+
+namespace KWayland
+{
+namespace Server
+{
+
+class Display;
+class SurfaceInterface;
+class PlasmaShellSurfaceInterface;
+
+class KWAYLANDSERVER_EXPORT PlasmaShellInterface : public Global
+{
+ Q_OBJECT
+public:
+ virtual ~PlasmaShellInterface();
+
+Q_SIGNALS:
+ void surfaceCreated(KWayland::Server::PlasmaShellSurfaceInterface*);
+
+private:
+ friend class Display;
+ explicit PlasmaShellInterface(Display *display, QObject *parent);
+ class Private;
+};
+
+class KWAYLANDSERVER_EXPORT PlasmaShellSurfaceInterface : public Resource
+{
+ Q_OBJECT
+public:
+ virtual ~PlasmaShellSurfaceInterface();
+
+ SurfaceInterface *surface() const;
+ PlasmaShellInterface *shell() const;
+
+ QPoint position() const;
+ bool isPositionSet() const;
+
+ enum class Role {
+ Normal,
+ Desktop,
+ Panel
+ };
+ Role role() const;
+
+Q_SIGNALS:
+ void positionChanged();
+ void roleChanged();
+
+private:
+ friend class PlasmaShellInterface;
+ explicit PlasmaShellSurfaceInterface(PlasmaShellInterface *shell, SurfaceInterface *parent, wl_resource *parentResource);
+ class Private;
+ Private *d_func() const;
+};
+
+}
+}
+
+#endif