diff options
author | Vlad Zahorodnii <vlad.zahorodnii@kde.org> | 2023-03-27 14:27:21 +0300 |
---|---|---|
committer | Vlad Zahorodnii <vlad.zahorodnii@kde.org> | 2023-04-03 14:00:42 +0300 |
commit | e7bc521fba30581546edae26be84de10c2f2a0f9 (patch) | |
tree | 93f78d5d2393a522149ff4dc5b8c32f62a90b2a5 /src | |
parent | d78e8c02846a3634445a808d9845be8613bb1bfe (diff) | |
download | qtwayland-e7bc521fba30581546edae26be84de10c2f2a0f9.tar.gz |
Client: Track parent-popup relationship in QWaylandWindow
This reduces the amount of boilerplate code that goes in shell
integration plugins providing popups.
The main motivation behind this change though is to ensure that
QWaylandWindow::addChildPopup() gets called outside the
QWaylandShellSurface constructor so one could use the popup's shell
surface object to customize parent-child relationship.
mShellSurface = mShellIntegration->createShellSurface(this);
when this code executes, addChildPopup() will be called before the
return value of createShellSurface() is assigned to mShellSurface.
Change-Id: I9ccfb21f46febb451bdd7b4aa7851a99f3a03655
Reviewed-by: David Edmundson <davidedmundson@kde.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/client/qwaylandwindow.cpp | 24 | ||||
-rw-r--r-- | src/client/qwaylandwindow_p.h | 7 | ||||
-rw-r--r-- | src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp | 10 |
3 files changed, 27 insertions, 14 deletions
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index 1111582e..74db519f 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -137,9 +137,15 @@ void QWaylandWindow::initWindow() } else if (shouldCreateShellSurface()) { Q_ASSERT(!mShellSurface); Q_ASSERT(mShellIntegration); + mTransientParent = closestTransientParent(); mShellSurface = mShellIntegration->createShellSurface(this); if (mShellSurface) { + if (mTransientParent) { + if (window()->type() == Qt::ToolTip || window()->type() == Qt::Popup) + mTransientParent->addChildPopup(this); + } + // Set initial surface title setWindowTitle(window()->title()); @@ -272,10 +278,13 @@ void QWaylandWindow::reset() emit wlSurfaceDestroyed(); QWriteLocker lock(&mSurfaceLock); invalidateSurface(); + if (mTransientParent) + mTransientParent->removeChildPopup(this); delete mShellSurface; mShellSurface = nullptr; delete mSubSurfaceWindow; mSubSurfaceWindow = nullptr; + mTransientParent = nullptr; mSurface.reset(); mViewport.reset(); mFractionalScale.reset(); @@ -1051,6 +1060,11 @@ static QWaylandWindow *closestShellSurfaceWindow(QWindow *window) QWaylandWindow *QWaylandWindow::transientParent() const { + return mTransientParent; +} + +QWaylandWindow *QWaylandWindow::closestTransientParent() const +{ // Take the closest window with a shell surface, since the transient parent may be a // QWidgetWindow or some other window without a shell surface, which is then not able to // get mouse events. @@ -1619,12 +1633,14 @@ void QWaylandWindow::setXdgActivationToken(const QString &token) mShellSurface->setXdgActivationToken(token); } -void QWaylandWindow::addChildPopup(QWaylandWindow *surface) { - mChildPopups.append(surface); +void QWaylandWindow::addChildPopup(QWaylandWindow *child) +{ + mChildPopups.append(child); } -void QWaylandWindow::removeChildPopup(QWaylandWindow *surface) { - mChildPopups.removeAll(surface); +void QWaylandWindow::removeChildPopup(QWaylandWindow *child) +{ + mChildPopups.removeAll(child); } void QWaylandWindow::closeChildPopups() { diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index d0640e7e..636cd179 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -225,8 +225,6 @@ public: void beginFrame(); void endFrame(); - void addChildPopup(QWaylandWindow* child); - void removeChildPopup(QWaylandWindow* child); void closeChildPopups(); virtual void reinit(); @@ -320,6 +318,7 @@ protected: QMargins mCustomMargins; + QPointer<QWaylandWindow> mTransientParent; QList<QPointer<QWaylandWindow>> mChildPopups; private: @@ -337,6 +336,10 @@ private: void handleScreensChanged(); void sendRecursiveExposeEvent(); + QWaylandWindow *closestTransientParent() const; + void addChildPopup(QWaylandWindow *child); + void removeChildPopup(QWaylandWindow *child); + bool mInResizeFromApplyConfigure = false; bool lastVisible = false; QRect mLastExposeGeometry; diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp index cd6e835f..bf6eb2d0 100644 --- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp @@ -211,10 +211,8 @@ QWaylandXdgSurface::Popup::Popup(QWaylandXdgSurface *xdgSurface, QWaylandWindow , m_parent(parent) { - init(xdgSurface->get_popup(m_parentXdgSurface ? m_parentXdgSurface->object() : nullptr, positioner->object())); - if (m_parent) { - m_parent->addChildPopup(m_xdgSurface->window()); - } + init(xdgSurface->get_popup(m_parentXdgSurface ? m_parentXdgSurface->object() : nullptr, + positioner->object())); } QWaylandXdgSurface::Popup::~Popup() @@ -222,10 +220,6 @@ QWaylandXdgSurface::Popup::~Popup() if (isInitialized()) destroy(); - if (m_parent) { - m_parent->removeChildPopup(m_xdgSurface->window()); - } - if (m_grabbing) { auto *shell = m_xdgSurface->m_shell; Q_ASSERT(shell->m_topmostGrabbingPopup == this); |