diff --git a/src/client/plasmawindowmanagement.h b/src/client/plasmawindowmanagement.h --- a/src/client/plasmawindowmanagement.h +++ b/src/client/plasmawindowmanagement.h @@ -156,6 +156,11 @@ **/ PlasmaWindowModel *createWindowModel(); + /** + * @returns windows stacking order + */ + QVector stackingOrder() const; + Q_SIGNALS: /** * This signal is emitted right before the interface is released. @@ -192,6 +197,12 @@ **/ void removed(); + /** + * The stacking order changed + * @since 5.70 + **/ + void stackingOrderChanged(); + private: class Private; QScopedPointer d; diff --git a/src/client/plasmawindowmanagement.cpp b/src/client/plasmawindowmanagement.cpp --- a/src/client/plasmawindowmanagement.cpp +++ b/src/client/plasmawindowmanagement.cpp @@ -34,14 +34,17 @@ bool showingDesktop = false; QList windows; PlasmaWindow *activeWindow = nullptr; + QVector stackingOrder; void setup(org_kde_plasma_window_management *wm); private: static void showDesktopCallback(void *data, org_kde_plasma_window_management *org_kde_plasma_window_management, uint32_t state); static void windowCallback(void *data, org_kde_plasma_window_management *org_kde_plasma_window_management, uint32_t id); + static void stackingOrderCallback(void *data, org_kde_plasma_window_management *org_kde_plasma_window_management, wl_array *ids); void setShowDesktop(bool set); void windowCreated(org_kde_plasma_window *id, quint32 internalId); + void setStackingOrder(const QVector &ids); static struct org_kde_plasma_window_management_listener s_listener; PlasmaWindowManagement *q; @@ -139,7 +142,8 @@ org_kde_plasma_window_management_listener PlasmaWindowManagement::Private::s_listener = { showDesktopCallback, - windowCallback + windowCallback, + stackingOrderCallback }; void PlasmaWindowManagement::Private::setup(org_kde_plasma_window_management *windowManagement) @@ -235,6 +239,25 @@ ); } +void PlasmaWindowManagement::Private::stackingOrderCallback(void *data, org_kde_plasma_window_management *interface, wl_array *ids) +{ + auto wm = reinterpret_cast(data); + Q_ASSERT(wm->wm == interface); + QVector destination; + destination.resize(ids->size / sizeof(uint32_t)); + memcpy(destination.data(), ids->data, ids->size); + wm->setStackingOrder(destination); +} + +void PlasmaWindowManagement::Private::setStackingOrder(const QVector &ids) +{ + if (stackingOrder == ids) { + return; + } + stackingOrder = ids; + emit q->stackingOrderChanged(); +} + PlasmaWindowManagement::PlasmaWindowManagement(QObject *parent) : QObject(parent) , d(new Private(this)) @@ -329,6 +352,11 @@ return new PlasmaWindowModel(this); } +QVector PlasmaWindowManagement::stackingOrder() const +{ + return d->stackingOrder; +} + org_kde_plasma_window_listener PlasmaWindow::Private::s_listener = { titleChangedCallback, appIdChangedCallback, diff --git a/src/client/protocols/plasma-window-management.xml b/src/client/protocols/plasma-window-management.xml --- a/src/client/protocols/plasma-window-management.xml +++ b/src/client/protocols/plasma-window-management.xml @@ -6,7 +6,7 @@ SPDX-License-Identifier: LGPL-2.1-or-later ]]> - + This interface manages application windows. It provides requests to show and hide the desktop and emits @@ -71,9 +71,16 @@ + + + + This event will be sent when stacking order changed and on bind + + + - + Manages and control an application window. diff --git a/src/client/registry.cpp b/src/client/registry.cpp --- a/src/client/registry.cpp +++ b/src/client/registry.cpp @@ -171,7 +171,7 @@ &Registry::plasmaVirtualDesktopManagementRemoved }}, {Registry::Interface::PlasmaWindowManagement, { - 10, + 11, QByteArrayLiteral("org_kde_plasma_window_management"), &org_kde_plasma_window_management_interface, &Registry::plasmaWindowManagementAnnounced, diff --git a/src/server/plasmawindowmanagement_interface.h b/src/server/plasmawindowmanagement_interface.h --- a/src/server/plasmawindowmanagement_interface.h +++ b/src/server/plasmawindowmanagement_interface.h @@ -73,6 +73,13 @@ */ PlasmaVirtualDesktopManagementInterface *plasmaVirtualDesktopManagementInterface() const; + + /** + * Associate stacking order to this window management + * @since 5.70 + */ + void setStackingOrder(const QVector &stackingOrder); + Q_SIGNALS: void requestChangeShowingDesktop(ShowingDesktopState requestedState); @@ -221,6 +228,13 @@ */ void setApplicationMenuPaths(const QString &serviceName, const QString &objectPath); + /** + * Return the window internal id + * + * @since 5.70 + */ + quint32 internalId() const; + Q_SIGNALS: void closeRequested(); /** diff --git a/src/server/plasmawindowmanagement_interface.cpp b/src/server/plasmawindowmanagement_interface.cpp --- a/src/server/plasmawindowmanagement_interface.cpp +++ b/src/server/plasmawindowmanagement_interface.cpp @@ -31,20 +31,23 @@ public: Private(PlasmaWindowManagementInterface *q, Display *d); void sendShowingDesktopState(); + void sendStackingOrderChanged(); ShowingDesktopState state = ShowingDesktopState::Disabled; QVector resources; QList windows; QPointer plasmaVirtualDesktopManagementInterface = nullptr; quint32 windowIdCounter = 0; + QVector stackingOrder; 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); + void sendStackingOrderChanged(wl_resource *r); PlasmaWindowManagementInterface *q; static const struct org_kde_plasma_window_management_interface s_interface; @@ -113,7 +116,7 @@ static const struct org_kde_plasma_window_interface s_interface; }; -const quint32 PlasmaWindowManagementInterface::Private::s_version = 10; +const quint32 PlasmaWindowManagementInterface::Private::s_version = 11; PlasmaWindowManagementInterface::Private::Private(PlasmaWindowManagementInterface *q, Display *d) : Global::Private(d, &org_kde_plasma_window_management_interface, s_version) @@ -152,6 +155,30 @@ org_kde_plasma_window_management_send_show_desktop_changed(r, s); } +void PlasmaWindowManagementInterface::Private::sendStackingOrderChanged() +{ + for (wl_resource *r : resources) { + sendStackingOrderChanged(r); + } +} + +void PlasmaWindowManagementInterface::Private::sendStackingOrderChanged(wl_resource *r) +{ + if (wl_resource_get_version(r) < ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STACKING_ORDER_CHANGED_SINCE_VERSION) { + return; + } + + wl_array wlIds; + wl_array_init(&wlIds); + const size_t memLength = sizeof(uint32_t) * stackingOrder.size(); + void *s = wl_array_add(&wlIds, memLength); + memcpy(s, stackingOrder.data(), memLength); + + org_kde_plasma_window_management_send_stacking_order_changed(r, &wlIds); + + wl_array_release(&wlIds); +} + void PlasmaWindowManagementInterface::Private::showDesktopCallback(wl_client *client, wl_resource *resource, uint32_t state) { Q_UNUSED(client) @@ -207,6 +234,7 @@ for (auto it = windows.constBegin(); it != windows.constEnd(); ++it) { org_kde_plasma_window_management_send_window(shell, (*it)->d->windowId); } + sendStackingOrderChanged(); } void PlasmaWindowManagementInterface::Private::unbind(wl_resource *resource) @@ -266,6 +294,16 @@ window->d->unmap(); } +void PlasmaWindowManagementInterface::setStackingOrder(const QVector& stackingOrder) +{ + Q_D(); + if (d->stackingOrder == stackingOrder) { + return; + } + d->stackingOrder = stackingOrder; + d->sendStackingOrderChanged(); +} + void PlasmaWindowManagementInterface::setPlasmaVirtualDesktopManagementInterface(PlasmaVirtualDesktopManagementInterface *manager) { Q_D(); @@ -958,5 +996,10 @@ d->setApplicationMenuPaths(serviceName, objectPath); } +quint32 PlasmaWindowInterface::internalId() const +{ + return d->windowId; +} + } }