diff --git a/src/decorations/decoratedclient.cpp b/src/decorations/decoratedclient.cpp index 91189019a6..bcbafb6e12 100644 --- a/src/decorations/decoratedclient.cpp +++ b/src/decorations/decoratedclient.cpp @@ -139,6 +139,9 @@ DELEGATE(WId, decorationId, frameId) #define DELEGATE(name, op) \ void DecoratedClientImpl::name() \ { \ + if (m_window->isDeleted()) { \ + return; \ + } \ Workspace::self()->performWindowOperation(m_window, Options::op); \ } @@ -152,6 +155,9 @@ DELEGATE(requestToggleKeepBelow, KeepBelowOp) #define DELEGATE(name, clientName) \ void DecoratedClientImpl::name() \ { \ + if (m_window->isDeleted()) { \ + return; \ + } \ m_window->clientName(); \ } @@ -166,6 +172,9 @@ void DecoratedClientImpl::requestMinimize() void DecoratedClientImpl::requestClose() { + if (m_window->isDeleted()) { + return; + } QMetaObject::invokeMethod(m_window, &Window::closeWindow, Qt::QueuedConnection); } @@ -181,6 +190,9 @@ QColor DecoratedClientImpl::color(KDecoration2::ColorGroup group, KDecoration2:: void DecoratedClientImpl::requestShowToolTip(const QString &text) { + if (m_window->isDeleted()) { + return; + } if (!workspace()->decorationBridge()->showToolTips()) { return; } @@ -200,21 +212,33 @@ void DecoratedClientImpl::requestHideToolTip() void DecoratedClientImpl::requestShowWindowMenu(const QRect &rect) { + if (m_window->isDeleted()) { + return; + } Workspace::self()->showWindowMenu(QRectF(m_window->pos() + rect.topLeft(), m_window->pos() + rect.bottomRight()).toRect(), m_window); } void DecoratedClientImpl::requestShowApplicationMenu(const QRect &rect, int actionId) { + if (m_window->isDeleted()) { + return; + } Workspace::self()->showApplicationMenu(rect, m_window, actionId); } void DecoratedClientImpl::showApplicationMenu(int actionId) { + if (m_window->isDeleted()) { + return; + } decoration()->showApplicationMenu(actionId); } void DecoratedClientImpl::requestToggleMaximization(Qt::MouseButtons buttons) { + if (m_window->isDeleted()) { + return; + } auto operation = options->operationMaxButtonClick(buttons); QMetaObject::invokeMethod( this, [this, operation] { @@ -225,6 +249,9 @@ void DecoratedClientImpl::requestToggleMaximization(Qt::MouseButtons buttons) void DecoratedClientImpl::delayedRequestToggleMaximization(Options::WindowOperation operation) { + if (m_window->isDeleted()) { + return; + } Workspace::self()->performWindowOperation(m_window, operation); } diff --git a/src/decorations/decoratedclient.h b/src/decorations/decoratedclient.h index 9bd5907a46..68fbb09bee 100644 --- a/src/decorations/decoratedclient.h +++ b/src/decorations/decoratedclient.h @@ -81,6 +81,10 @@ public: { return m_window; } + void setWindow(Window *window) + { + m_window = window; + } KDecoration2::DecoratedClient *decoratedClient() { return KDecoration2::DecoratedClientPrivate::client(); diff --git a/src/deleted.cpp b/src/deleted.cpp index b552803e4a..2b99c5e257 100644 --- a/src/deleted.cpp +++ b/src/deleted.cpp @@ -56,7 +56,6 @@ void Deleted::copyToDeleted(Window *window) { Q_ASSERT(!window->isDeleted()); Window::copyToDeleted(window); - m_frameMargins = window->frameMargins(); desk = window->desktop(); m_desktops = window->desktops(); activityList = window->activities(); @@ -66,12 +65,6 @@ void Deleted::copyToDeleted(Window *window) m_type = window->windowType(); m_windowRole = window->windowRole(); m_shade = window->isShade(); - if (window->isDecorated()) { - window->layoutDecorationRects(decoration_left, - decoration_top, - decoration_right, - decoration_bottom); - } m_mainWindows = window->mainWindows(); for (Window *w : std::as_const(m_mainWindows)) { connect(w, &Window::closed, this, &Deleted::mainWindowClosed); @@ -90,11 +83,6 @@ void Deleted::copyToDeleted(Window *window) m_wasLockScreen = window->isLockScreen(); } -QMargins Deleted::frameMargins() const -{ - return m_frameMargins; -} - int Deleted::desktop() const { return desk; @@ -115,14 +103,6 @@ QPointF Deleted::clientPos() const return contentsRect.topLeft(); } -void Deleted::layoutDecorationRects(QRectF &left, QRectF &top, QRectF &right, QRectF &bottom) const -{ - left = decoration_left; - top = decoration_top; - right = decoration_right; - bottom = decoration_bottom; -} - bool Deleted::isDeleted() const { return true; diff --git a/src/deleted.h b/src/deleted.h index cb1e594a5e..f4f179efe3 100644 --- a/src/deleted.h +++ b/src/deleted.h @@ -21,14 +21,12 @@ class KWIN_EXPORT Deleted : public Window public: static Deleted *create(Window *c); - QMargins frameMargins() const override; int desktop() const override; QStringList activities() const override; QVector desktops() const override; QPointF clientPos() const override; bool isDeleted() const override; xcb_window_t frameId() const override; - void layoutDecorationRects(QRectF &left, QRectF &top, QRectF &right, QRectF &bottom) const override; Layer layer() const override { return m_layer; @@ -107,18 +105,12 @@ private: void copyToDeleted(Window *c); ~Deleted() override; // deleted only using unrefWindow() - QMargins m_frameMargins; - int desk; QStringList activityList; QRectF contentsRect; // for clientPos()/clientSize() xcb_window_t m_frame; QVector m_desktops; - QRectF decoration_left; - QRectF decoration_right; - QRectF decoration_top; - QRectF decoration_bottom; Layer m_layer; bool m_shade; QList m_mainWindows; diff --git a/src/internalwindow.cpp b/src/internalwindow.cpp index c0da0020f2..77d55c27ac 100644 --- a/src/internalwindow.cpp +++ b/src/internalwindow.cpp @@ -367,8 +367,6 @@ void InternalWindow::destroyWindow() Deleted *deleted = Deleted::create(this); Q_EMIT closed(deleted); - destroyDecoration(); - workspace()->removeInternalWindow(this); m_handle = nullptr; diff --git a/src/scene/decorationitem.cpp b/src/scene/decorationitem.cpp index 5798277f5b..c483f6dba7 100644 --- a/src/scene/decorationitem.cpp +++ b/src/scene/decorationitem.cpp @@ -168,10 +168,6 @@ void DecorationItem::handleFrameGeometryChanged() void DecorationItem::handleWindowClosed(Window *deleted) { m_window = deleted; - - // If the decoration is about to be destroyed, render the decoration for the last time. - effects->makeOpenGLContextCurrent(); - preprocess(); } DecorationRenderer *DecorationItem::renderer() const diff --git a/src/window.cpp b/src/window.cpp index ee8bfe11d7..37757aba60 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -126,7 +126,6 @@ Window::~Window() m_tile->removeWindow(this); } Q_ASSERT(m_blockGeometryUpdates == 0); - Q_ASSERT(m_decoration.decoration == nullptr); delete info; } @@ -224,6 +223,16 @@ void Window::copyToDeleted(Window *c) m_modal = c->m_modal; m_keepAbove = c->m_keepAbove; m_keepBelow = c->m_keepBelow; + m_active = c->m_active; + m_palette = c->m_palette; + if (c->m_decoration.decoration) { + c->m_decoration.decoration->setParent(this); + m_decoration.decoration = c->m_decoration.decoration; + } + if (c->m_decoration.client) { + c->m_decoration.client->setWindow(this); + m_decoration.client = c->m_decoration.client; + } } // before being deleted, remove references to everything that's now diff --git a/src/window.h b/src/window.h index ee0b188f29..52649c3dea 100644 --- a/src/window.h +++ b/src/window.h @@ -592,7 +592,7 @@ public: * * Default implementation returns a margins object with all margins set to 0. */ - virtual QMargins frameMargins() const; + QMargins frameMargins() const; /** * The geometry of the Window which accepts input events. This might be larger * than the actual geometry, e.g. to support resizing outside the window. @@ -1237,7 +1237,7 @@ public: void setDecoratedClient(Decoration::DecoratedClientImpl *client); bool decorationHasAlpha() const; void triggerDecorationRepaint(); - virtual void layoutDecorationRects(QRectF &left, QRectF &top, QRectF &right, QRectF &bottom) const; + void layoutDecorationRects(QRectF &left, QRectF &top, QRectF &right, QRectF &bottom) const; void processDecorationMove(const QPointF &localPos, const QPointF &globalPos); bool processDecorationButtonPress(QMouseEvent *event, bool ignoreMenu = false); void processDecorationButtonRelease(QMouseEvent *event); diff --git a/src/x11window.cpp b/src/x11window.cpp index f236a76770..6f681dda29 100644 --- a/src/x11window.cpp +++ b/src/x11window.cpp @@ -386,7 +386,6 @@ void X11Window::releaseWindow(bool on_shutdown) workspace()->windowHidden(this); } m_frame.unmap(); // Destroying decoration would cause ugly visual effect - destroyDecoration(); cleanGrouping(); workspace()->removeX11Window(this); if (!on_shutdown) { @@ -401,7 +400,8 @@ void X11Window::releaseWindow(bool on_shutdown) m_client.deleteProperty(atoms->kde_net_wm_user_creation_time); m_client.deleteProperty(atoms->net_frame_extents); m_client.deleteProperty(atoms->kde_net_wm_frame_strut); - m_client.reparent(kwinApp()->x11RootWindow(), m_bufferGeometry.x(), m_bufferGeometry.y()); + const QPointF grav = calculateGravitation(true); + m_client.reparent(kwinApp()->x11RootWindow(), grav.x(), grav.y()); xcb_change_save_set(c, XCB_SET_MODE_DELETE, m_client); m_client.selectInput(XCB_EVENT_MASK_NO_EVENT); if (on_shutdown) { @@ -450,7 +450,6 @@ void X11Window::destroyWindow() setModal(false); hidden = true; // So that it's not considered visible anymore workspace()->windowHidden(this); - destroyDecoration(); cleanGrouping(); workspace()->removeX11Window(this); if (WinInfo *cinfo = dynamic_cast(info)) { diff --git a/src/xdgshellwindow.cpp b/src/xdgshellwindow.cpp index 7b1f8f7f81..17ad39f548 100644 --- a/src/xdgshellwindow.cpp +++ b/src/xdgshellwindow.cpp @@ -90,7 +90,6 @@ XdgSurfaceWindow::XdgSurfaceWindow(XdgSurfaceInterface *shellSurface) XdgSurfaceWindow::~XdgSurfaceWindow() { - qDeleteAll(m_configureEvents); } NET::WindowType XdgSurfaceWindow::windowType(bool direct, int supported_types) const @@ -294,12 +293,13 @@ void XdgSurfaceWindow::destroyWindow() Q_EMIT interactiveMoveResizeFinished(); } m_configureTimer->stop(); + qDeleteAll(m_configureEvents); + m_configureEvents.clear(); cleanTabBox(); Deleted *deleted = Deleted::create(this); Q_EMIT closed(deleted); StackingUpdatesBlocker blocker(workspace()); workspace()->rulebook()->discardUsed(this, true); - setDecoration(nullptr); cleanGrouping(); waylandServer()->removeWindow(this);