summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVlad Zahorodnii <vlad.zahorodnii@kde.org>2023-03-27 14:27:21 +0300
committerVlad Zahorodnii <vlad.zahorodnii@kde.org>2023-04-03 14:00:42 +0300
commite7bc521fba30581546edae26be84de10c2f2a0f9 (patch)
tree93f78d5d2393a522149ff4dc5b8c32f62a90b2a5 /src
parentd78e8c02846a3634445a808d9845be8613bb1bfe (diff)
downloadqtwayland-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.cpp24
-rw-r--r--src/client/qwaylandwindow_p.h7
-rw-r--r--src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp10
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);