From 390af54e0d5439e5a992bfd4c042c90d5272c5e6 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Wed, 22 Feb 2023 12:15:50 +0100 Subject: client: Add support for xdg_popup_configure This amends 59a5fe99e1569421b920d99c5b20cdafcdcf43a9. Since set_constraint_adjustment() was supported, popup should reposition itself from configure. Need to find a way to test clientSideMargins() and etc in the future. Fixes: QTBUG-110623 Task-number: QTBUG-87303 Done-with: Ilya Fedin Change-Id: I734acfcde3ba5a35b6f4222358bc93e49fa43f7c Reviewed-by: Qt CI Bot Reviewed-by: David Edmundson (cherry picked from commit 2eeefbb706d8fce8d70d454c5e9ceda3ecae2479) Reviewed-by: Qt Cherry-pick Bot --- .../xdg-shell/qwaylandxdgshell.cpp | 23 ++++++++++++++++++++++ .../xdg-shell/qwaylandxdgshell_p.h | 6 ++++++ tests/auto/client/xdgshell/tst_xdgshell.cpp | 22 +++++++++++++++++++-- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp index 6303fbc9..eebfb9e0 100644 --- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp @@ -243,6 +243,22 @@ QWaylandXdgSurface::Popup::~Popup() } } +void QWaylandXdgSurface::Popup::applyConfigure() +{ + if (m_pendingGeometry.isValid()) { + QRect geometryWithMargins = m_pendingGeometry.marginsAdded(m_xdgSurface->m_window->windowContentMargins()); + QMargins parentMargins = m_parent->windowContentMargins() - m_parent->clientSideMargins(); + QRect globalGeometry = geometryWithMargins.translated(m_parent->geometry().topLeft() + QPoint(parentMargins.left(), parentMargins.top())); + m_xdgSurface->setGeometryFromApplyConfigure(globalGeometry.topLeft(), globalGeometry.size()); + } + resetConfiguration(); +} + +void QWaylandXdgSurface::Popup::resetConfiguration() +{ + m_pendingGeometry = QRect(); +} + void QWaylandXdgSurface::Popup::grab(QWaylandInputDevice *seat, uint serial) { m_xdgSurface->m_shell->m_topmostGrabbingPopup = this; @@ -250,6 +266,11 @@ void QWaylandXdgSurface::Popup::grab(QWaylandInputDevice *seat, uint serial) m_grabbing = true; } +void QWaylandXdgSurface::Popup::xdg_popup_configure(int32_t x, int32_t y, int32_t width, int32_t height) +{ + m_pendingGeometry = QRect(x, y, width, height); +} + void QWaylandXdgSurface::Popup::xdg_popup_popup_done() { m_xdgSurface->m_window->window()->close(); @@ -364,6 +385,8 @@ void QWaylandXdgSurface::applyConfigure() if (m_toplevel) m_toplevel->applyConfigure(); + if (m_popup) + m_popup->applyConfigure(); m_appliedConfigureSerial = m_pendingConfigureSerial; m_configured = true; diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h index 58860269..11147af2 100644 --- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h +++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h @@ -115,13 +115,19 @@ private: Popup(QWaylandXdgSurface *xdgSurface, QWaylandWindow *parent, QtWayland::xdg_positioner *positioner); ~Popup() override; + void applyConfigure(); + void resetConfiguration(); + void grab(QWaylandInputDevice *seat, uint serial); + void xdg_popup_configure(int32_t x, int32_t y, int32_t width, int32_t height) override; void xdg_popup_popup_done() override; QWaylandXdgSurface *m_xdgSurface = nullptr; QWaylandXdgSurface *m_parentXdgSurface = nullptr; QWaylandWindow *m_parent = nullptr; bool m_grabbing = false; + + QRect m_pendingGeometry; }; void setToplevel(); diff --git a/tests/auto/client/xdgshell/tst_xdgshell.cpp b/tests/auto/client/xdgshell/tst_xdgshell.cpp index 101baecc..82fb50e3 100644 --- a/tests/auto/client/xdgshell/tst_xdgshell.cpp +++ b/tests/auto/client/xdgshell/tst_xdgshell.cpp @@ -13,6 +13,7 @@ class tst_xdgshell : public QObject, private DefaultCompositor { Q_OBJECT private slots: + void init(); void cleanup() { QTRY_VERIFY2(isClean(), qPrintable(dirtyMessage())); } void showMinimized(); void basicConfigure(); @@ -31,6 +32,11 @@ private slots: void nativeResources(); }; +void tst_xdgshell::init() +{ + setenv("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1", 1); +} + void tst_xdgshell::showMinimized() { // On xdg-shell there's really no way for the compositor to tell the window if it's minimized @@ -239,8 +245,8 @@ void tst_xdgshell::popup() QRasterWindow *popup = window.m_popup.get(); QVERIFY(!popup->isExposed()); // wait for configure - //TODO: Verify it works with a different configure window geometry - exec([=] { xdgPopup()->sendConfigure(QRect(100, 100, 100, 100)); }); + QRect rect1 = QRect(100, 100, 100, 100); + exec([=] { xdgPopup()->sendConfigure(rect1); }); // Nothing should happen before the *xdg_surface* configure QTRY_VERIFY(!popup->isExposed()); // Popup shouldn't be exposed before the first configure event @@ -256,6 +262,18 @@ void tst_xdgshell::popup() // The client is now going to ack the configure QTRY_COMPARE(popupConfigureSpy.size(), 1); QCOMPARE(popupConfigureSpy.takeFirst().at(0).toUInt(), configureSerial); + QCOMPARE(popup->geometry(), rect1); + + QRect rect2 = QRect(50, 50, 150, 150); + exec([=] { xdgPopup()->sendConfigure(rect2); }); + + const uint configureSerial2 = exec([=] { + return xdgPopup()->m_xdgSurface->sendConfigure(); + }); + + QTRY_COMPARE(popupConfigureSpy.size(), 1); + QCOMPARE(popupConfigureSpy.takeFirst().at(0).toUInt(), configureSerial2); + QCOMPARE(popup->geometry(), rect2); // And attach a buffer exec([&] { -- cgit v1.2.1