client: Add support for xdg_popup_configure

This amends 6d1d6ebb60ce3f239f83c3459f4465746fcba65c.

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
Pick-to: 5.15 6.2 6.4 6.5
Done-with: Ilya Fedin <fedin-ilja2010@ya.ru>
Change-Id: I734acfcde3ba5a35b6f4222358bc93e49fa43f7c
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: David Edmundson <davidedmundson@kde.org>
This commit is contained in:
Liang Qi 2023-02-22 12:15:50 +01:00
parent 0db6b5d6c5
commit 33a371758b
3 changed files with 49 additions and 2 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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([&] {