Extend lifetime of decoration to lifetime of Deleted
When a window is closed, a Deleted object will be constructed and the Window's properties will be copied over to it. The long term plan is to stop doing that, i.e. keep the Window alive but just flip a few flags to indicate that it's been closed. In order to unify decoration management, this change ensures that it's okay to have decorations live as long as the Deleted.
This commit is contained in:
parent
d563382350
commit
2dca6cd003
10 changed files with 47 additions and 42 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -81,6 +81,10 @@ public:
|
|||
{
|
||||
return m_window;
|
||||
}
|
||||
void setWindow(Window *window)
|
||||
{
|
||||
m_window = window;
|
||||
}
|
||||
KDecoration2::DecoratedClient *decoratedClient()
|
||||
{
|
||||
return KDecoration2::DecoratedClientPrivate::client();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<VirtualDesktop *> 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<VirtualDesktop *> m_desktops;
|
||||
|
||||
QRectF decoration_left;
|
||||
QRectF decoration_right;
|
||||
QRectF decoration_top;
|
||||
QRectF decoration_bottom;
|
||||
Layer m_layer;
|
||||
bool m_shade;
|
||||
QList<Window *> m_mainWindows;
|
||||
|
|
|
@ -367,8 +367,6 @@ void InternalWindow::destroyWindow()
|
|||
Deleted *deleted = Deleted::create(this);
|
||||
Q_EMIT closed(deleted);
|
||||
|
||||
destroyDecoration();
|
||||
|
||||
workspace()->removeInternalWindow(this);
|
||||
m_handle = nullptr;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<WinInfo *>(info)) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue