From ccb4ac42802ca9df9f2b1560560d1a2b46a663fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Fri, 15 Jul 2016 13:31:12 +0200 Subject: [PATCH] Add a geometry event to PlasmaWindow Summary: This allows the compositor to expose the absolute window geometry to processes which need it. Reviewers: #plasma_on_wayland Subscribers: plasma-devel Tags: #plasma_on_wayland Differential Revision: https://phabricator.kde.org/D2183 --- .../client/test_wayland_windowmanagement.cpp | 34 +++++++++++++++++++ .../plasmawindowmanagement_interface.cpp | 31 ++++++++++++++++- .../plasmawindowmanagement_interface.h | 8 +++++ 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/src/wayland/autotests/client/test_wayland_windowmanagement.cpp b/src/wayland/autotests/client/test_wayland_windowmanagement.cpp index 7d51dffb45..fbd92bd301 100644 --- a/src/wayland/autotests/client/test_wayland_windowmanagement.cpp +++ b/src/wayland/autotests/client/test_wayland_windowmanagement.cpp @@ -65,6 +65,7 @@ private Q_SLOTS: void testRequestShowingDesktop_data(); void testRequestShowingDesktop(); void testParentWindow(); + void testGeometry(); void cleanup(); @@ -509,5 +510,38 @@ void TestWindowManagement::testParentWindow() QVERIFY(transient->parentWindow().isNull()); } +void TestWindowManagement::testGeometry() +{ + using namespace KWayland::Client; + QVERIFY(m_window); + QCOMPARE(m_window->geometry(), QRect()); + QSignalSpy windowGeometryChangedSpy(m_window, &PlasmaWindow::geometryChanged); + QVERIFY(windowGeometryChangedSpy.isValid()); + m_windowInterface->setGeometry(QRect(20, -10, 30, 40)); + QVERIFY(windowGeometryChangedSpy.wait()); + QCOMPARE(m_window->geometry(), QRect(20, -10, 30, 40)); + // setting an empty geometry should not be sent to the client + m_windowInterface->setGeometry(QRect()); + QVERIFY(!windowGeometryChangedSpy.wait(10)); + // setting to the geometry which the client still has should not trigger signal + m_windowInterface->setGeometry(QRect(20, -10, 30, 40)); + QVERIFY(!windowGeometryChangedSpy.wait(10)); + // setting another geometry should work, though + m_windowInterface->setGeometry(QRect(0, 0, 35, 45)); + QVERIFY(windowGeometryChangedSpy.wait()); + QCOMPARE(windowGeometryChangedSpy.count(), 2); + QCOMPARE(m_window->geometry(), QRect(0, 0, 35, 45)); + + // let's bind a second PlasmaWindowManagement to verify the initial setting + QScopedPointer pm(m_registry->createPlasmaWindowManagement(m_registry->interface(Registry::Interface::PlasmaWindowManagement).name, + m_registry->interface(Registry::Interface::PlasmaWindowManagement).version)); + QVERIFY(!pm.isNull()); + QSignalSpy windowAddedSpy(pm.data(), &PlasmaWindowManagement::windowCreated); + QVERIFY(windowAddedSpy.isValid()); + QVERIFY(windowAddedSpy.wait()); + auto window = pm->windows().first(); + QCOMPARE(window->geometry(), QRect(0, 0, 35, 45)); +} + QTEST_GUILESS_MAIN(TestWindowManagement) #include "test_wayland_windowmanagement.moc" diff --git a/src/wayland/plasmawindowmanagement_interface.cpp b/src/wayland/plasmawindowmanagement_interface.cpp index 17084c4340..35f961ed4b 100644 --- a/src/wayland/plasmawindowmanagement_interface.cpp +++ b/src/wayland/plasmawindowmanagement_interface.cpp @@ -74,6 +74,7 @@ public: void unmap(); void setState(org_kde_plasma_window_management_state flag, bool set); void setParentWindow(PlasmaWindowInterface *parent); + void setGeometry(const QRect &geometry); wl_resource *resourceForParent(PlasmaWindowInterface *parent, wl_resource *child) const; QVector resources; @@ -84,6 +85,7 @@ public: bool unmapped = false; PlasmaWindowInterface *parentWindow = nullptr; QMetaObject::Connection parentWindowDestroyConnection; + QRect geometry; private: static void unbind(wl_resource *resource); @@ -109,7 +111,7 @@ private: static const struct org_kde_plasma_window_interface s_interface; }; -const quint32 PlasmaWindowManagementInterface::Private::s_version = 5; +const quint32 PlasmaWindowManagementInterface::Private::s_version = 6; PlasmaWindowManagementInterface::Private::Private(PlasmaWindowManagementInterface *q, Display *d) : Global::Private(d, &org_kde_plasma_window_management_interface, s_version) @@ -332,6 +334,10 @@ void PlasmaWindowInterface::Private::createResource(wl_resource *parent, uint32_ 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); } @@ -453,6 +459,24 @@ void PlasmaWindowInterface::Private::setParentWindow(PlasmaWindowInterface *wind } } +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::closeCallback(wl_client *client, wl_resource *resource) { Q_UNUSED(client) @@ -710,5 +734,10 @@ void PlasmaWindowInterface::setParentWindow(PlasmaWindowInterface *parentWindow) d->setParentWindow(parentWindow); } +void PlasmaWindowInterface::setGeometry(const QRect &geometry) +{ + d->setGeometry(geometry); +} + } } diff --git a/src/wayland/plasmawindowmanagement_interface.h b/src/wayland/plasmawindowmanagement_interface.h index 76f9950f65..6b12bb3bf7 100644 --- a/src/wayland/plasmawindowmanagement_interface.h +++ b/src/wayland/plasmawindowmanagement_interface.h @@ -147,6 +147,14 @@ public: **/ void setParentWindow(PlasmaWindowInterface *parentWindow); + /** + * Sets the window @p geometry of this PlasmaWindow. + * + * @param geometry The geometry in absolute coordinates + * @since 5.25 + **/ + void setGeometry(const QRect &geometry); + Q_SIGNALS: void closeRequested(); /**