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>
This commit is contained in:
parent
eabe2a039b
commit
e1ef4a7f89
@ -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);
|
||||
|
@ -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();
|
||||
@ -1050,6 +1059,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
|
||||
@ -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() {
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user