kwin/src/wayland/plasmawindowmanagement_interface.cpp
Andreas Cord-Landwehr 9267f146fd KWayland: Convert license headers to SPDX
Summary:
Convert license headers to SPDX expressions and add license files as
required by REUSE specification.

Reviewers: zzag

Reviewed By: zzag

Subscribers: kde-frameworks-devel

Tags: #frameworks

Maniphest Tasks: T11550

Differential Revision: https://phabricator.kde.org/D28058
2020-03-16 19:57:44 +01:00

953 lines
31 KiB
C++

/*
SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "plasmawindowmanagement_interface.h"
#include "global_p.h"
#include "resource_p.h"
#include "display.h"
#include "surface_interface.h"
#include "plasmavirtualdesktop_interface.h"
#include <QtConcurrentRun>
#include <QFile>
#include <QIcon>
#include <QList>
#include <QVector>
#include <QRect>
#include <QHash>
#include <wayland-server.h>
#include <wayland-plasma-window-management-server-protocol.h>
namespace KWayland
{
namespace Server
{
class PlasmaWindowManagementInterface::Private : public Global::Private
{
public:
Private(PlasmaWindowManagementInterface *q, Display *d);
void sendShowingDesktopState();
ShowingDesktopState state = ShowingDesktopState::Disabled;
QVector<wl_resource*> resources;
QList<PlasmaWindowInterface*> windows;
QPointer<PlasmaVirtualDesktopManagementInterface> plasmaVirtualDesktopManagementInterface = nullptr;
quint32 windowIdCounter = 0;
private:
static void unbind(wl_resource *resource);
static void showDesktopCallback(wl_client *client, wl_resource *resource, uint32_t state);
static void getWindowCallback(wl_client *client, wl_resource *resource, uint32_t id, uint32_t internalWindowId);
void bind(wl_client *client, uint32_t version, uint32_t id) override;
void sendShowingDesktopState(wl_resource *r);
PlasmaWindowManagementInterface *q;
static const struct org_kde_plasma_window_management_interface s_interface;
static const quint32 s_version;
};
class PlasmaWindowInterface::Private
{
public:
Private(PlasmaWindowManagementInterface *wm, PlasmaWindowInterface *q);
~Private();
void createResource(wl_resource *parent, uint32_t id);
void setTitle(const QString &title);
void setAppId(const QString &appId);
void setPid(quint32 pid);
void setThemedIconName(const QString &iconName);
void setIcon(const QIcon &icon);
void setVirtualDesktop(quint32 desktop);
void unmap();
void setState(org_kde_plasma_window_management_state flag, bool set);
void setParentWindow(PlasmaWindowInterface *parent);
void setGeometry(const QRect &geometry);
void setApplicationMenuPaths(const QString &service, const QString &object);
wl_resource *resourceForParent(PlasmaWindowInterface *parent, wl_resource *child) const;
QVector<wl_resource*> resources;
quint32 windowId = 0;
QHash<SurfaceInterface*, QRect> minimizedGeometries;
PlasmaWindowManagementInterface *wm;
bool unmapped = false;
PlasmaWindowInterface *parentWindow = nullptr;
QMetaObject::Connection parentWindowDestroyConnection;
QStringList plasmaVirtualDesktops;
QRect geometry;
private:
static void unbind(wl_resource *resource);
static void setStateCallback(wl_client *client, wl_resource *resource, uint32_t flags, uint32_t state);
static void setVirtualDesktopCallback(wl_client *client, wl_resource *resource, uint32_t number);
static void closeCallback(wl_client *client, wl_resource *resource);
static void requestMoveCallback(wl_client *client, wl_resource *resource);
static void requestResizeCallback(wl_client *client, wl_resource *resource);
static void setMinimizedGeometryCallback(wl_client *client, wl_resource *resource, wl_resource *panel, uint32_t x, uint32_t y, uint32_t width, uint32_t height);
static void unsetMinimizedGeometryCallback(wl_client *client, wl_resource *resource, wl_resource *panel);
static void destroyCallback(wl_client *client, wl_resource *resource);
static void getIconCallback(wl_client *client, wl_resource *resource, int32_t fd);
static void requestEnterVirtualDesktopCallback(wl_client *client, wl_resource *resource, const char *id);
static void requestEnterNewVirtualDesktopCallback(wl_client *client, wl_resource *resource);
static void requestLeaveVirtualDesktopCallback(wl_client *client, wl_resource *resource, const char *id);
static Private *cast(wl_resource *resource) {
return reinterpret_cast<Private*>(wl_resource_get_user_data(resource));
}
PlasmaWindowInterface *q;
QString m_title;
QString m_appId;
quint32 m_pid = 0;
QString m_themedIconName;
QIcon m_icon;
quint32 m_virtualDesktop = 0;
quint32 m_state = 0;
wl_listener listener;
static const struct org_kde_plasma_window_interface s_interface;
};
const quint32 PlasmaWindowManagementInterface::Private::s_version = 10;
PlasmaWindowManagementInterface::Private::Private(PlasmaWindowManagementInterface *q, Display *d)
: Global::Private(d, &org_kde_plasma_window_management_interface, s_version)
, q(q)
{
}
#ifndef K_DOXYGEN
const struct org_kde_plasma_window_management_interface PlasmaWindowManagementInterface::Private::s_interface = {
showDesktopCallback,
getWindowCallback
};
#endif
void PlasmaWindowManagementInterface::Private::sendShowingDesktopState()
{
for (wl_resource *r : resources) {
sendShowingDesktopState(r);
}
}
void PlasmaWindowManagementInterface::Private::sendShowingDesktopState(wl_resource *r)
{
uint32_t s = 0;
switch (state) {
case ShowingDesktopState::Enabled:
s = ORG_KDE_PLASMA_WINDOW_MANAGEMENT_SHOW_DESKTOP_ENABLED;
break;
case ShowingDesktopState::Disabled:
s = ORG_KDE_PLASMA_WINDOW_MANAGEMENT_SHOW_DESKTOP_DISABLED;
break;
default:
Q_UNREACHABLE();
break;
}
org_kde_plasma_window_management_send_show_desktop_changed(r, s);
}
void PlasmaWindowManagementInterface::Private::showDesktopCallback(wl_client *client, wl_resource *resource, uint32_t state)
{
Q_UNUSED(client)
ShowingDesktopState s = ShowingDesktopState::Disabled;
switch (state) {
case ORG_KDE_PLASMA_WINDOW_MANAGEMENT_SHOW_DESKTOP_ENABLED:
s = ShowingDesktopState::Enabled;
break;
case ORG_KDE_PLASMA_WINDOW_MANAGEMENT_SHOW_DESKTOP_DISABLED:
default:
s = ShowingDesktopState::Disabled;
break;
}
emit reinterpret_cast<Private*>(wl_resource_get_user_data(resource))->q->requestChangeShowingDesktop(s);
}
void PlasmaWindowManagementInterface::Private::getWindowCallback(wl_client *client, wl_resource *resource, uint32_t id, uint32_t internalWindowId)
{
Q_UNUSED(client)
auto p = reinterpret_cast<Private*>(wl_resource_get_user_data(resource));
auto it = std::find_if(p->windows.constBegin(), p->windows.constEnd(),
[internalWindowId] (PlasmaWindowInterface *window) {
return window->d->windowId == internalWindowId;
}
);
if (it == p->windows.constEnd()) {
// create a temp window just for the resource and directly send an unmapped
PlasmaWindowInterface *window = new PlasmaWindowInterface(p->q, p->q);
window->d->unmapped = true;
window->d->createResource(resource, id);
return;
}
(*it)->d->createResource(resource, id);
}
PlasmaWindowManagementInterface::PlasmaWindowManagementInterface(Display *display, QObject *parent)
: Global(new Private(this, display), parent)
{
}
PlasmaWindowManagementInterface::~PlasmaWindowManagementInterface() = default;
void PlasmaWindowManagementInterface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
{
auto c = display->getConnection(client);
wl_resource *shell = c->createResource(&org_kde_plasma_window_management_interface, qMin(version, s_version), id);
if (!shell) {
wl_client_post_no_memory(client);
return;
}
wl_resource_set_implementation(shell, &s_interface, this, unbind);
resources << shell;
for (auto it = windows.constBegin(); it != windows.constEnd(); ++it) {
org_kde_plasma_window_management_send_window(shell, (*it)->d->windowId);
}
}
void PlasmaWindowManagementInterface::Private::unbind(wl_resource *resource)
{
auto wm = reinterpret_cast<Private*>(wl_resource_get_user_data(resource));
wm->resources.removeAll(resource);
}
void PlasmaWindowManagementInterface::setShowingDesktopState(PlasmaWindowManagementInterface::ShowingDesktopState state)
{
Q_D();
if (d->state == state) {
return;
}
d->state = state;
d->sendShowingDesktopState();
}
PlasmaWindowManagementInterface::Private *PlasmaWindowManagementInterface::d_func() const
{
return reinterpret_cast<Private*>(d.data());
}
PlasmaWindowInterface *PlasmaWindowManagementInterface::createWindow(QObject *parent)
{
Q_D();
PlasmaWindowInterface *window = new PlasmaWindowInterface(this, parent);
// TODO: improve window ids so that it cannot wrap around
window->d->windowId = ++d->windowIdCounter;
for (auto it = d->resources.constBegin(); it != d->resources.constEnd(); ++it) {
org_kde_plasma_window_management_send_window(*it, window->d->windowId);
}
d->windows << window;
connect(window, &QObject::destroyed, this,
[this, window] {
Q_D();
d->windows.removeAll(window);
}
);
return window;
}
QList<PlasmaWindowInterface*> PlasmaWindowManagementInterface::windows() const
{
Q_D();
return d->windows;
}
void PlasmaWindowManagementInterface::unmapWindow(PlasmaWindowInterface *window)
{
if (!window) {
return;
}
Q_D();
d->windows.removeOne(window);
Q_ASSERT(!d->windows.contains(window));
window->d->unmap();
}
void PlasmaWindowManagementInterface::setPlasmaVirtualDesktopManagementInterface(PlasmaVirtualDesktopManagementInterface *manager)
{
Q_D();
if (d->plasmaVirtualDesktopManagementInterface == manager) {
return;
}
d->plasmaVirtualDesktopManagementInterface = manager;
}
PlasmaVirtualDesktopManagementInterface *PlasmaWindowManagementInterface::plasmaVirtualDesktopManagementInterface() const
{
Q_D();
return d->plasmaVirtualDesktopManagementInterface;
}
#ifndef K_DOXYGEN
const struct org_kde_plasma_window_interface PlasmaWindowInterface::Private::s_interface = {
setStateCallback,
setVirtualDesktopCallback,
setMinimizedGeometryCallback,
unsetMinimizedGeometryCallback,
closeCallback,
requestMoveCallback,
requestResizeCallback,
destroyCallback,
getIconCallback,
requestEnterVirtualDesktopCallback,
requestEnterNewVirtualDesktopCallback,
requestLeaveVirtualDesktopCallback
};
#endif
PlasmaWindowInterface::Private::Private(PlasmaWindowManagementInterface *wm, PlasmaWindowInterface *q)
: wm(wm)
, q(q)
{
}
PlasmaWindowInterface::Private::~Private()
{
// need to copy, as destroy goes through the destroy listener and modifies the list as we iterate
const auto c = resources;
for (const auto &r : c) {
auto client = wl_resource_get_client(r);
org_kde_plasma_window_send_unmapped(r);
wl_resource_destroy(r);
wl_client_flush(client);
}
}
void PlasmaWindowInterface::Private::destroyCallback(wl_client *, wl_resource *r)
{
Private *p = cast(r);
p->resources.removeAll(r);
wl_resource_destroy(r);
if (p->unmapped && p->resources.isEmpty()) {
p->q->deleteLater();
}
}
void PlasmaWindowInterface::Private::unbind(wl_resource *resource)
{
Private *p = reinterpret_cast<Private*>(wl_resource_get_user_data(resource));
p->resources.removeAll(resource);
if (p->unmapped && p->resources.isEmpty()) {
p->q->deleteLater();
}
}
void PlasmaWindowInterface::Private::createResource(wl_resource *parent, uint32_t id)
{
ClientConnection *c = wm->display()->getConnection(wl_resource_get_client(parent));
wl_resource *resource = c->createResource(&org_kde_plasma_window_interface, wl_resource_get_version(parent), id);
if (!resource) {
return;
}
wl_resource_set_implementation(resource, &s_interface, this, unbind);
resources << resource;
org_kde_plasma_window_send_virtual_desktop_changed(resource, m_virtualDesktop);
for (const auto &desk : plasmaVirtualDesktops) {
org_kde_plasma_window_send_virtual_desktop_entered(resource, desk.toUtf8().constData());
}
if (!m_appId.isEmpty()) {
org_kde_plasma_window_send_app_id_changed(resource, m_appId.toUtf8().constData());
}
if (m_pid != 0) {
org_kde_plasma_window_send_pid_changed(resource, m_pid);
}
if (!m_title.isEmpty()) {
org_kde_plasma_window_send_title_changed(resource, m_title.toUtf8().constData());
}
org_kde_plasma_window_send_state_changed(resource, m_state);
if (!m_themedIconName.isEmpty()) {
org_kde_plasma_window_send_themed_icon_name_changed(resource, m_themedIconName.toUtf8().constData());
} else {
if (wl_resource_get_version(resource) >= ORG_KDE_PLASMA_WINDOW_ICON_CHANGED_SINCE_VERSION) {
org_kde_plasma_window_send_icon_changed(resource);
}
}
org_kde_plasma_window_send_parent_window(resource, resourceForParent(parentWindow, resource));
if (unmapped) {
org_kde_plasma_window_send_unmapped(resource);
}
if (geometry.isValid() && wl_resource_get_version(resource) >= ORG_KDE_PLASMA_WINDOW_GEOMETRY_SINCE_VERSION) {
org_kde_plasma_window_send_geometry(resource, geometry.x(), geometry.y(), geometry.width(), geometry.height());
}
if (wl_resource_get_version(resource) >= ORG_KDE_PLASMA_WINDOW_INITIAL_STATE_SINCE_VERSION) {
org_kde_plasma_window_send_initial_state(resource);
}
c->flush();
}
void PlasmaWindowInterface::Private::setAppId(const QString &appId)
{
if (m_appId == appId) {
return;
}
m_appId = appId;
const QByteArray utf8 = m_appId.toUtf8();
for (auto it = resources.constBegin(); it != resources.constEnd(); ++it) {
org_kde_plasma_window_send_app_id_changed(*it, utf8.constData());
}
}
void PlasmaWindowInterface::Private::setPid(quint32 pid)
{
if (m_pid == pid) {
return;
}
m_pid = pid;
for (auto it = resources.constBegin(); it != resources.constEnd(); ++it) {
org_kde_plasma_window_send_pid_changed(*it, pid);
}
}
void PlasmaWindowInterface::Private::setThemedIconName(const QString &iconName)
{
if (m_themedIconName == iconName) {
return;
}
m_themedIconName = iconName;
const QByteArray utf8 = m_themedIconName.toUtf8();
for (auto it = resources.constBegin(); it != resources.constEnd(); ++it) {
org_kde_plasma_window_send_themed_icon_name_changed(*it, utf8.constData());
}
}
void PlasmaWindowInterface::Private::setIcon(const QIcon &icon)
{
m_icon = icon;
setThemedIconName(m_icon.name());
if (m_icon.name().isEmpty()) {
for (auto it = resources.constBegin(); it != resources.constEnd(); ++it) {
if (wl_resource_get_version(*it) >= ORG_KDE_PLASMA_WINDOW_ICON_CHANGED_SINCE_VERSION) {
org_kde_plasma_window_send_icon_changed(*it);
}
}
}
}
void PlasmaWindowInterface::Private::getIconCallback(wl_client *client, wl_resource *resource, int32_t fd)
{
Q_UNUSED(client)
Private *p = cast(resource);
QtConcurrent::run(
[fd] (const QIcon &icon) {
QFile file;
file.open(fd, QIODevice::WriteOnly, QFileDevice::AutoCloseHandle);
QDataStream ds(&file);
ds << icon;
file.close();
}, p->m_icon
);
}
void PlasmaWindowInterface::Private::requestEnterVirtualDesktopCallback(wl_client *client, wl_resource *resource, const char *id)
{
Q_UNUSED(client)
Private *p = cast(resource);
emit p->q->enterPlasmaVirtualDesktopRequested(QString::fromUtf8(id));
}
void PlasmaWindowInterface::Private::requestEnterNewVirtualDesktopCallback(wl_client *client, wl_resource *resource)
{
Q_UNUSED(client)
Private *p = cast(resource);
emit p->q->enterNewPlasmaVirtualDesktopRequested();
}
void PlasmaWindowInterface::Private::requestLeaveVirtualDesktopCallback(wl_client *client, wl_resource *resource, const char *id)
{
Q_UNUSED(client)
Private *p = cast(resource);
emit p->q->leavePlasmaVirtualDesktopRequested(QString::fromUtf8(id));
}
void PlasmaWindowInterface::Private::setTitle(const QString &title)
{
if (m_title == title) {
return;
}
m_title = title;
const QByteArray utf8 = m_title.toUtf8();
for (auto it = resources.constBegin(); it != resources.constEnd(); ++it) {
org_kde_plasma_window_send_title_changed(*it, utf8.constData());
}
}
void PlasmaWindowInterface::Private::setVirtualDesktop(quint32 desktop)
{
if (m_virtualDesktop == desktop) {
return;
}
m_virtualDesktop = desktop;
for (auto it = resources.constBegin(); it != resources.constEnd(); ++it) {
org_kde_plasma_window_send_virtual_desktop_changed(*it, m_virtualDesktop);
}
}
void PlasmaWindowInterface::Private::unmap()
{
unmapped = true;
for (auto it = resources.constBegin(); it != resources.constEnd(); ++it) {
org_kde_plasma_window_send_unmapped(*it);
}
if (resources.isEmpty()) {
q->deleteLater();
}
}
void PlasmaWindowInterface::Private::setState(org_kde_plasma_window_management_state flag, bool set)
{
quint32 newState = m_state;
if (set) {
newState |= flag;
} else {
newState &= ~flag;
}
if (newState == m_state) {
return;
}
m_state = newState;
for (auto it = resources.constBegin(); it != resources.constEnd(); ++it) {
org_kde_plasma_window_send_state_changed(*it, m_state);
}
}
wl_resource *PlasmaWindowInterface::Private::resourceForParent(PlasmaWindowInterface *parent, wl_resource *child) const
{
if (!parent) {
return nullptr;
}
auto it = std::find_if(parent->d->resources.begin(), parent->d->resources.end(),
[child] (wl_resource *parentResource) {
return wl_resource_get_client(child) == wl_resource_get_client(parentResource);
}
);
if (it != parent->d->resources.end()) {
return *it;
}
return nullptr;
}
void PlasmaWindowInterface::Private::setParentWindow(PlasmaWindowInterface *window)
{
if (parentWindow == window) {
return;
}
QObject::disconnect(parentWindowDestroyConnection);
parentWindowDestroyConnection = QMetaObject::Connection();
parentWindow = window;
if (parentWindow) {
parentWindowDestroyConnection = QObject::connect(window, &QObject::destroyed, q,
[this] {
parentWindow = nullptr;
parentWindowDestroyConnection = QMetaObject::Connection();
for (auto it = resources.constBegin(); it != resources.constEnd(); ++it) {
org_kde_plasma_window_send_parent_window(*it, nullptr);
}
}
);
}
for (auto it = resources.constBegin(); it != resources.constEnd(); ++it) {
org_kde_plasma_window_send_parent_window(*it, resourceForParent(window, *it));
}
}
void PlasmaWindowInterface::Private::setGeometry(const QRect &geo)
{
if (geometry == geo) {
return;
}
geometry = geo;
if (!geometry.isValid()) {
return;
}
for (auto it = resources.constBegin(); it != resources.constEnd(); ++it) {
auto resource = *it;
if (wl_resource_get_version(resource) < ORG_KDE_PLASMA_WINDOW_GEOMETRY_SINCE_VERSION) {
continue;
}
org_kde_plasma_window_send_geometry(resource, geometry.x(), geometry.y(), geometry.width(), geometry.height());
}
}
void PlasmaWindowInterface::Private::setApplicationMenuPaths(const QString &service, const QString &object)
{
for (auto it = resources.constBegin(); it != resources.constEnd(); ++it) {
auto resource = *it;
if (wl_resource_get_version(resource) < ORG_KDE_PLASMA_WINDOW_APPLICATION_MENU_SINCE_VERSION) {
continue;
}
org_kde_plasma_window_send_application_menu(resource, qUtf8Printable(service), qUtf8Printable(object));
}
}
void PlasmaWindowInterface::Private::closeCallback(wl_client *client, wl_resource *resource)
{
Q_UNUSED(client)
Private *p = cast(resource);
emit p->q->closeRequested();
}
void PlasmaWindowInterface::Private::requestMoveCallback(wl_client *client, wl_resource *resource)
{
Q_UNUSED(client)
Private *p = cast(resource);
emit p->q->moveRequested();
}
void PlasmaWindowInterface::Private::requestResizeCallback(wl_client *client, wl_resource *resource)
{
Q_UNUSED(client)
Private *p = cast(resource);
emit p->q->resizeRequested();
}
void PlasmaWindowInterface::Private::setVirtualDesktopCallback(wl_client *client, wl_resource *resource, uint32_t number)
{
Q_UNUSED(client)
Private *p = cast(resource);
emit p->q->virtualDesktopRequested(number);
}
void PlasmaWindowInterface::Private::setStateCallback(wl_client *client, wl_resource *resource, uint32_t flags, uint32_t state)
{
Q_UNUSED(client)
Private *p = cast(resource);
if (flags & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_ACTIVE) {
emit p->q->activeRequested(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_ACTIVE);
}
if (flags & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MINIMIZED) {
emit p->q->minimizedRequested(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MINIMIZED);
}
if (flags & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MAXIMIZED) {
emit p->q->maximizedRequested(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MAXIMIZED);
}
if (flags & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_FULLSCREEN) {
emit p->q->fullscreenRequested(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_FULLSCREEN);
}
if (flags & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_KEEP_ABOVE) {
emit p->q->keepAboveRequested(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_KEEP_ABOVE);
}
if (flags & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_KEEP_BELOW) {
emit p->q->keepBelowRequested(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_KEEP_BELOW);
}
if (flags & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_DEMANDS_ATTENTION) {
emit p->q->demandsAttentionRequested(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_DEMANDS_ATTENTION);
}
if (flags & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_CLOSEABLE) {
emit p->q->closeableRequested(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_CLOSEABLE);
}
if (flags & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MINIMIZABLE) {
emit p->q->minimizeableRequested(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MINIMIZABLE);
}
if (flags & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MAXIMIZABLE) {
emit p->q->maximizeableRequested(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MAXIMIZABLE);
}
if (flags & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_FULLSCREENABLE) {
emit p->q->fullscreenableRequested(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_FULLSCREENABLE);
}
if (flags & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SKIPTASKBAR) {
emit p->q->skipTaskbarRequested(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SKIPTASKBAR);
}
if (flags & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SKIPSWITCHER) {
emit p->q->skipSwitcherRequested(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SKIPSWITCHER);
}
if (flags & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADEABLE) {
emit p->q->shadeableRequested(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADEABLE);
}
if (flags & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADED) {
emit p->q->shadedRequested(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADED);
}
if (flags & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MOVABLE) {
emit p->q->movableRequested(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MOVABLE);
}
if (flags & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_RESIZABLE) {
emit p->q->resizableRequested(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_RESIZABLE);
}
if (flags & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_VIRTUAL_DESKTOP_CHANGEABLE) {
emit p->q->virtualDesktopChangeableRequested(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_VIRTUAL_DESKTOP_CHANGEABLE);
}
}
void PlasmaWindowInterface::Private::setMinimizedGeometryCallback(wl_client *client, wl_resource *resource, wl_resource *panel, uint32_t x, uint32_t y, uint32_t width, uint32_t height)
{
Q_UNUSED(client)
Private *p = cast(resource);
SurfaceInterface *panelSurface = SurfaceInterface::get(panel);
if (!panelSurface) {
return;
}
if (p->minimizedGeometries.value(panelSurface) == QRect(x, y, width, height)) {
return;
}
p->minimizedGeometries[panelSurface] = QRect(x, y, width, height);
emit p->q->minimizedGeometriesChanged();
connect(panelSurface, &QObject::destroyed, p->q, [p, panelSurface] () {
if (p->minimizedGeometries.remove(panelSurface)) {
emit p->q->minimizedGeometriesChanged();
}
});
}
void PlasmaWindowInterface::Private::unsetMinimizedGeometryCallback(wl_client *client, wl_resource *resource, wl_resource *panel)
{
Q_UNUSED(client)
Private *p = cast(resource);
SurfaceInterface *panelSurface = SurfaceInterface::get(panel);
if (!panelSurface) {
return;
}
if (!p->minimizedGeometries.contains(panelSurface)) {
return;
}
p->minimizedGeometries.remove(panelSurface);
emit p->q->minimizedGeometriesChanged();
}
PlasmaWindowInterface::PlasmaWindowInterface(PlasmaWindowManagementInterface *wm, QObject *parent)
: QObject(parent)
, d(new Private(wm, this))
{
}
PlasmaWindowInterface::~PlasmaWindowInterface() = default;
void PlasmaWindowInterface::setAppId(const QString &appId)
{
d->setAppId(appId);
}
void PlasmaWindowInterface::setPid(quint32 pid)
{
d->setPid(pid);
}
void PlasmaWindowInterface::setTitle(const QString &title)
{
d->setTitle(title);
}
void PlasmaWindowInterface::setVirtualDesktop(quint32 desktop)
{
d->setVirtualDesktop(desktop);
}
void PlasmaWindowInterface::unmap()
{
d->wm->unmapWindow(this);
}
QHash<SurfaceInterface*, QRect> PlasmaWindowInterface::minimizedGeometries() const
{
return d->minimizedGeometries;
}
void PlasmaWindowInterface::setActive(bool set)
{
d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_ACTIVE, set);
}
void PlasmaWindowInterface::setFullscreen(bool set)
{
d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_FULLSCREEN, set);
}
void PlasmaWindowInterface::setKeepAbove(bool set)
{
d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_KEEP_ABOVE, set);
}
void PlasmaWindowInterface::setKeepBelow(bool set)
{
d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_KEEP_BELOW, set);
}
void PlasmaWindowInterface::setMaximized(bool set)
{
d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MAXIMIZED, set);
}
void PlasmaWindowInterface::setMinimized(bool set)
{
d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MINIMIZED, set);
}
void PlasmaWindowInterface::setOnAllDesktops(bool set)
{
//the deprecated vd management
d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_ON_ALL_DESKTOPS, set);
if (!d->wm->plasmaVirtualDesktopManagementInterface()) {
return;
}
//the current vd management
if (set) {
if (d->plasmaVirtualDesktops.isEmpty()) {
return;
}
//leaving everything means on all desktops
for (auto desk : plasmaVirtualDesktops()) {
for (auto it = d->resources.constBegin(); it != d->resources.constEnd(); ++it) {
org_kde_plasma_window_send_virtual_desktop_left(*it, desk.toUtf8().constData());
}
}
d->plasmaVirtualDesktops.clear();
} else {
if (!d->plasmaVirtualDesktops.isEmpty()) {
return;
}
//enters the desktops which are active (usually only one but not a given)
for (auto desk : d->wm->plasmaVirtualDesktopManagementInterface()->desktops()) {
if (desk->isActive() && !d->plasmaVirtualDesktops.contains(desk->id())) {
d->plasmaVirtualDesktops << desk->id();
for (auto it = d->resources.constBegin(); it != d->resources.constEnd(); ++it) {
org_kde_plasma_window_send_virtual_desktop_entered(*it, desk->id().toUtf8().constData());
}
}
}
}
}
void PlasmaWindowInterface::setDemandsAttention(bool set)
{
d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_DEMANDS_ATTENTION, set);
}
void PlasmaWindowInterface::setCloseable(bool set)
{
d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_CLOSEABLE, set);
}
void PlasmaWindowInterface::setFullscreenable(bool set)
{
d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_FULLSCREENABLE, set);
}
void PlasmaWindowInterface::setMaximizeable(bool set)
{
d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MAXIMIZABLE, set);
}
void PlasmaWindowInterface::setMinimizeable(bool set)
{
d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MINIMIZABLE, set);
}
void PlasmaWindowInterface::setSkipTaskbar(bool set)
{
d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SKIPTASKBAR, set);
}
void PlasmaWindowInterface::setSkipSwitcher(bool skip)
{
d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SKIPSWITCHER, skip);
}
void PlasmaWindowInterface::setThemedIconName(const QString &iconName)
{
d->setThemedIconName(iconName);
}
void PlasmaWindowInterface::setIcon(const QIcon &icon)
{
d->setIcon(icon);
}
void PlasmaWindowInterface::addPlasmaVirtualDesktop(const QString &id)
{
//don't add a desktop we're not sure it exists
if (!d->wm->plasmaVirtualDesktopManagementInterface() || d->plasmaVirtualDesktops.contains(id)) {
return;
}
PlasmaVirtualDesktopInterface *desktop = d->wm->plasmaVirtualDesktopManagementInterface()->desktop(id);
if (!desktop) {
return;
}
d->plasmaVirtualDesktops << id;
//if the desktop dies, remove it from or list
connect(desktop, &QObject::destroyed,
this, [this, id](){removePlasmaVirtualDesktop(id);});
for (auto it = d->resources.constBegin(); it != d->resources.constEnd(); ++it) {
org_kde_plasma_window_send_virtual_desktop_entered(*it, id.toUtf8().constData());
}
}
void PlasmaWindowInterface::removePlasmaVirtualDesktop(const QString &id)
{
if (!d->plasmaVirtualDesktops.contains(id)) {
return;
}
d->plasmaVirtualDesktops.removeAll(id);
for (auto it = d->resources.constBegin(); it != d->resources.constEnd(); ++it) {
org_kde_plasma_window_send_virtual_desktop_left(*it, id.toUtf8().constData());
}
//we went on all desktops
if (d->plasmaVirtualDesktops.isEmpty()) {
setOnAllDesktops(true);
}
}
QStringList PlasmaWindowInterface::plasmaVirtualDesktops() const
{
return d->plasmaVirtualDesktops;
}
void PlasmaWindowInterface::setShadeable(bool set)
{
d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADEABLE, set);
}
void PlasmaWindowInterface::setShaded(bool set)
{
d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADED, set);
}
void PlasmaWindowInterface::setMovable(bool set)
{
d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MOVABLE, set);
}
void PlasmaWindowInterface::setResizable(bool set)
{
d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_RESIZABLE, set);
}
void PlasmaWindowInterface::setVirtualDesktopChangeable(bool set)
{
d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_VIRTUAL_DESKTOP_CHANGEABLE, set);
}
void PlasmaWindowInterface::setParentWindow(PlasmaWindowInterface *parentWindow)
{
d->setParentWindow(parentWindow);
}
void PlasmaWindowInterface::setGeometry(const QRect &geometry)
{
d->setGeometry(geometry);
}
void PlasmaWindowInterface::setApplicationMenuPaths(const QString &serviceName, const QString &objectPath)
{
d->setApplicationMenuPaths(serviceName, objectPath);
}
}
}