diff --git a/src/wayland/autotests/client/test_plasma_virtual_desktop.cpp b/src/wayland/autotests/client/test_plasma_virtual_desktop.cpp index aaada82d46..220d1b8a14 100644 --- a/src/wayland/autotests/client/test_plasma_virtual_desktop.cpp +++ b/src/wayland/autotests/client/test_plasma_virtual_desktop.cpp @@ -137,7 +137,7 @@ void TestVirtualDesktop::init() QSignalSpy windowSpy(m_windowManagement, SIGNAL(windowCreated(KWayland::Client::PlasmaWindow*))); QVERIFY(windowSpy.isValid()); - m_windowInterface = m_windowManagementInterface->createWindow(this); + m_windowInterface = m_windowManagementInterface->createWindow(this, QUuid::createUuid()); m_windowInterface->setPid(1337); QVERIFY(windowSpy.wait()); diff --git a/src/wayland/autotests/client/test_plasma_window_model.cpp b/src/wayland/autotests/client/test_plasma_window_model.cpp index 9f1f34bace..05f385217f 100644 --- a/src/wayland/autotests/client/test_plasma_window_model.cpp +++ b/src/wayland/autotests/client/test_plasma_window_model.cpp @@ -179,7 +179,7 @@ if (!QTest::qCompare(actual, expected, #actual, #expected, __FILE__, __LINE__))\ VERIFY(model); QSignalSpy rowInsertedSpy(model, &PlasmaWindowModel::rowsInserted); VERIFY(rowInsertedSpy.isValid()); - auto w = m_pwInterface->createWindow(m_pwInterface); + auto w = m_pwInterface->createWindow(m_pwInterface, QUuid::createUuid()); VERIFY(w); VERIFY(rowInsertedSpy.wait()); m_connection->flush(); @@ -267,7 +267,7 @@ void PlasmaWindowModelTest::testAddRemoveRows() QSignalSpy rowInsertedSpy(model, &PlasmaWindowModel::rowsInserted); QVERIFY(rowInsertedSpy.isValid()); // this happens by creating a PlasmaWindow on server side - auto w = m_pwInterface->createWindow(m_pwInterface); + auto w = m_pwInterface->createWindow(m_pwInterface, QUuid::createUuid()); QVERIFY(w); QVERIFY(rowInsertedSpy.wait()); QCOMPARE(rowInsertedSpy.count(), 1); @@ -343,7 +343,7 @@ void PlasmaWindowModelTest::testDefaultData() QVERIFY(model); QSignalSpy rowInsertedSpy(model, &PlasmaWindowModel::rowsInserted); QVERIFY(rowInsertedSpy.isValid()); - auto w = m_pwInterface->createWindow(m_pwInterface); + auto w = m_pwInterface->createWindow(m_pwInterface, QUuid::createUuid()); QVERIFY(w); QVERIFY(rowInsertedSpy.wait()); @@ -450,7 +450,7 @@ void PlasmaWindowModelTest::testGeometry() QSignalSpy rowInsertedSpy(model, &PlasmaWindowModel::rowsInserted); QVERIFY(rowInsertedSpy.isValid()); - auto w = m_pwInterface->createWindow(m_pwInterface); + auto w = m_pwInterface->createWindow(m_pwInterface, QUuid::createUuid()); QVERIFY(w); QVERIFY(rowInsertedSpy.wait()); @@ -478,7 +478,7 @@ void PlasmaWindowModelTest::testTitle() QVERIFY(model); QSignalSpy rowInsertedSpy(model, &PlasmaWindowModel::rowsInserted); QVERIFY(rowInsertedSpy.isValid()); - auto w = m_pwInterface->createWindow(m_pwInterface); + auto w = m_pwInterface->createWindow(m_pwInterface, QUuid::createUuid()); QVERIFY(w); QVERIFY(rowInsertedSpy.wait()); m_connection->flush(); @@ -503,7 +503,7 @@ void PlasmaWindowModelTest::testAppId() QVERIFY(model); QSignalSpy rowInsertedSpy(model, &PlasmaWindowModel::rowsInserted); QVERIFY(rowInsertedSpy.isValid()); - auto w = m_pwInterface->createWindow(m_pwInterface); + auto w = m_pwInterface->createWindow(m_pwInterface, QUuid::createUuid()); QVERIFY(w); QVERIFY(rowInsertedSpy.wait()); m_connection->flush(); @@ -528,7 +528,7 @@ void PlasmaWindowModelTest::testPid() QVERIFY(model); QSignalSpy rowInsertedSpy(model, &PlasmaWindowModel::rowsInserted); QVERIFY(rowInsertedSpy.isValid()); - auto w = m_pwInterface->createWindow(m_pwInterface); + auto w = m_pwInterface->createWindow(m_pwInterface, QUuid::createUuid()); w->setPid(1337); QVERIFY(w); m_connection->flush(); @@ -546,7 +546,7 @@ void PlasmaWindowModelTest::testVirtualDesktops() QVERIFY(model); QSignalSpy rowInsertedSpy(model, &PlasmaWindowModel::rowsInserted); QVERIFY(rowInsertedSpy.isValid()); - auto w = m_pwInterface->createWindow(m_pwInterface); + auto w = m_pwInterface->createWindow(m_pwInterface, QUuid::createUuid()); QVERIFY(w); QVERIFY(rowInsertedSpy.wait()); m_connection->flush(); @@ -595,7 +595,7 @@ void PlasmaWindowModelTest::testRequests() QVERIFY(model); QSignalSpy rowInsertedSpy(model, &PlasmaWindowModel::rowsInserted); QVERIFY(rowInsertedSpy.isValid()); - auto w = m_pwInterface->createWindow(m_pwInterface); + auto w = m_pwInterface->createWindow(m_pwInterface, QUuid::createUuid()); QVERIFY(w); QVERIFY(rowInsertedSpy.wait()); @@ -815,7 +815,7 @@ void PlasmaWindowModelTest::testCreateWithUnmappedWindow() // create a window in "normal way" QSignalSpy windowCreatedSpy(m_pw, &PlasmaWindowManagement::windowCreated); QVERIFY(windowCreatedSpy.isValid()); - auto w = m_pwInterface->createWindow(m_pwInterface); + auto w = m_pwInterface->createWindow(m_pwInterface, QUuid::createUuid()); QVERIFY(w); QVERIFY(windowCreatedSpy.wait()); PlasmaWindow *window = windowCreatedSpy.first().first().value(); @@ -884,7 +884,7 @@ void PlasmaWindowModelTest::testChangeWindowAfterModelDestroy() QVERIFY(model); QSignalSpy windowCreatedSpy(m_pw, &PlasmaWindowManagement::windowCreated); QVERIFY(windowCreatedSpy.isValid()); - auto w = m_pwInterface->createWindow(m_pwInterface); + auto w = m_pwInterface->createWindow(m_pwInterface, QUuid::createUuid()); QVERIFY(windowCreatedSpy.wait()); PlasmaWindow *window = windowCreatedSpy.first().first().value(); // make sure the resource is properly created on server side @@ -918,7 +918,7 @@ void PlasmaWindowModelTest::testCreateWindowAfterModelDestroy() delete model; QSignalSpy windowCreatedSpy(m_pw, &PlasmaWindowManagement::windowCreated); QVERIFY(windowCreatedSpy.isValid()); - m_pwInterface->createWindow(m_pwInterface); + m_pwInterface->createWindow(m_pwInterface, QUuid::createUuid()); QVERIFY(windowCreatedSpy.wait()); } diff --git a/src/wayland/autotests/client/test_wayland_windowmanagement.cpp b/src/wayland/autotests/client/test_wayland_windowmanagement.cpp index 018acc53d4..1d9075b457 100644 --- a/src/wayland/autotests/client/test_wayland_windowmanagement.cpp +++ b/src/wayland/autotests/client/test_wayland_windowmanagement.cpp @@ -145,7 +145,7 @@ void TestWindowManagement::init() QSignalSpy windowSpy(m_windowManagement, SIGNAL(windowCreated(KWayland::Client::PlasmaWindow*))); QVERIFY(windowSpy.isValid()); - m_windowInterface = m_windowManagementInterface->createWindow(this); + m_windowInterface = m_windowManagementInterface->createWindow(this, QUuid::createUuid()); m_windowInterface->setPid(1337); QVERIFY(windowSpy.wait()); @@ -323,7 +323,7 @@ void TestWindowManagement::testCreateAfterUnmap() QCOMPARE(m_windowManagement->children().count(), 1); // create and unmap in one go // client will first handle the create, the unmap will be sent once the server side is bound - auto serverWindow = m_windowManagementInterface->createWindow(this); + auto serverWindow = m_windowManagementInterface->createWindow(this, QUuid::createUuid()); serverWindow->unmap(); QCOMPARE(m_windowManagementInterface->children().count(), 0); QCoreApplication::instance()->processEvents(); @@ -518,7 +518,7 @@ void TestWindowManagement::testParentWindow() // now let's create a second window QSignalSpy windowAddedSpy(m_windowManagement, &PlasmaWindowManagement::windowCreated); QVERIFY(windowAddedSpy.isValid()); - auto serverTransient = m_windowManagementInterface->createWindow(this); + auto serverTransient = m_windowManagementInterface->createWindow(this, QUuid::createUuid()); serverTransient->setParentWindow(m_windowInterface); QVERIFY(windowAddedSpy.wait()); auto transient = windowAddedSpy.first().first().value(); @@ -625,7 +625,7 @@ void TestWindowManagement::testPid() QVERIFY(m_window->pid() == 1337); //test server not setting a PID for whatever reason - QScopedPointer newWindowInterface(m_windowManagementInterface->createWindow(this)); + QScopedPointer newWindowInterface(m_windowManagementInterface->createWindow(this, QUuid::createUuid())); QSignalSpy windowSpy(m_windowManagement, SIGNAL(windowCreated(KWayland::Client::PlasmaWindow*))); QVERIFY(windowSpy.wait()); QScopedPointer newWindow( windowSpy.first().first().value()); diff --git a/src/wayland/plasmawindowmanagement_interface.cpp b/src/wayland/plasmawindowmanagement_interface.cpp index 5b891ab48b..52be7995e9 100644 --- a/src/wayland/plasmawindowmanagement_interface.cpp +++ b/src/wayland/plasmawindowmanagement_interface.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -37,11 +38,13 @@ public: QPointer plasmaVirtualDesktopManagementInterface = nullptr; quint32 windowIdCounter = 0; QVector stackingOrder; + QVector stackingOrderUuids; 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); + static void getWindowByUuidCallback(wl_client *client, wl_resource *resource, uint32_t id, const char* uuid); void bind(wl_client *client, uint32_t version, uint32_t id) override; void sendShowingDesktopState(wl_resource *r); @@ -82,6 +85,7 @@ public: QMetaObject::Connection parentWindowDestroyConnection; QStringList plasmaVirtualDesktops; QRect geometry; + QByteArray uuid; private: static void unbind(wl_resource *resource); @@ -114,7 +118,7 @@ private: static const struct org_kde_plasma_window_interface s_interface; }; -const quint32 PlasmaWindowManagementInterface::Private::s_version = 11; +const quint32 PlasmaWindowManagementInterface::Private::s_version = 12; PlasmaWindowManagementInterface::Private::Private(PlasmaWindowManagementInterface *q, Display *d) : Global::Private(d, &org_kde_plasma_window_management_interface, s_version) @@ -125,7 +129,8 @@ PlasmaWindowManagementInterface::Private::Private(PlasmaWindowManagementInterfac #ifndef K_DOXYGEN const struct org_kde_plasma_window_management_interface PlasmaWindowManagementInterface::Private::s_interface = { showDesktopCallback, - getWindowCallback + getWindowCallback, + getWindowByUuidCallback }; #endif @@ -175,6 +180,14 @@ void PlasmaWindowManagementInterface::Private::sendStackingOrderChanged(wl_resou org_kde_plasma_window_management_send_stacking_order_changed(r, &wlIds); wl_array_release(&wlIds); + + QByteArray uuids; + for (const auto &uuid : qAsConst(stackingOrderUuids)) { + uuids += uuid; + uuids += ';'; + } + + org_kde_plasma_window_management_send_stacking_order_uuid_changed(r, uuids.constData()); } void PlasmaWindowManagementInterface::Private::showDesktopCallback(wl_client *client, wl_resource *resource, uint32_t state) @@ -212,6 +225,26 @@ void PlasmaWindowManagementInterface::Private::getWindowCallback(wl_client *clie (*it)->d->createResource(resource, id); } +void PlasmaWindowManagementInterface::Private::getWindowByUuidCallback(wl_client *client, wl_resource *resource, uint32_t id, const char* uuid) +{ + Q_UNUSED(client) + auto p = reinterpret_cast(wl_resource_get_user_data(resource)); + auto it = std::find_if(p->windows.constBegin(), p->windows.constEnd(), + [uuid] (PlasmaWindowInterface *window) { + return window->d->uuid == uuid; + } + ); + if (it == p->windows.constEnd()) { + qWarning() << "Could not find window with uuid" << uuid; + // 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) { @@ -230,7 +263,11 @@ void PlasmaWindowManagementInterface::Private::bind(wl_client *client, uint32_t 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); + if (wl_resource_get_version(shell) >= ORG_KDE_PLASMA_WINDOW_MANAGEMENT_WINDOW_WITH_UUID_SINCE_VERSION) { + org_kde_plasma_window_management_send_window_with_uuid(shell, (*it)->d->windowId, (*it)->d->uuid.constData()); + } else { + org_kde_plasma_window_management_send_window(shell, (*it)->d->windowId); + } } sendStackingOrderChanged(shell); } @@ -256,14 +293,20 @@ PlasmaWindowManagementInterface::Private *PlasmaWindowManagementInterface::d_fun return reinterpret_cast(d.data()); } -PlasmaWindowInterface *PlasmaWindowManagementInterface::createWindow(QObject *parent) +PlasmaWindowInterface *PlasmaWindowManagementInterface::createWindow(QObject *parent, const QUuid &uuid) { Q_D(); PlasmaWindowInterface *window = new PlasmaWindowInterface(this, parent); - // TODO: improve window ids so that it cannot wrap around - window->d->windowId = ++d->windowIdCounter; + + window->d->uuid = uuid.toByteArray(); + window->d->windowId = ++d->windowIdCounter; //NOTE the window id is deprecated + for (auto it = d->resources.constBegin(); it != d->resources.constEnd(); ++it) { - org_kde_plasma_window_management_send_window(*it, window->d->windowId); + if (wl_resource_get_version(*it) >= ORG_KDE_PLASMA_WINDOW_MANAGEMENT_WINDOW_WITH_UUID_SINCE_VERSION) { + org_kde_plasma_window_management_send_window_with_uuid(*it, window->d->windowId, window->d->uuid.constData()); + } else { + org_kde_plasma_window_management_send_window(*it, window->d->windowId); + } } d->windows << window; connect(window, &QObject::destroyed, this, diff --git a/src/wayland/plasmawindowmanagement_interface.h b/src/wayland/plasmawindowmanagement_interface.h index 17a20ce1b1..82c3194471 100644 --- a/src/wayland/plasmawindowmanagement_interface.h +++ b/src/wayland/plasmawindowmanagement_interface.h @@ -37,7 +37,7 @@ public: }; void setShowingDesktopState(ShowingDesktopState state); - PlasmaWindowInterface *createWindow(QObject *parent); + PlasmaWindowInterface *createWindow(QObject *parent, const QUuid &uuid); QList windows() const; /** @@ -233,6 +233,13 @@ public: */ quint32 internalId() const; + /** + * @return a unique string that identifies this window + * + * @since Plasma 5.20 + */ + QByteArray uuid() const; + Q_SIGNALS: void closeRequested(); /**