Make Window ref'able

This commit is contained in:
Vlad Zahorodnii 2023-03-02 22:51:46 +02:00
parent 995d509e45
commit 149db99c6a
12 changed files with 37 additions and 41 deletions

View file

@ -185,7 +185,7 @@ struct WindowUnrefDeleter
void operator()(Deleted *d)
{
if (d != nullptr) {
d->unrefWindow();
d->unref();
}
}
};
@ -244,7 +244,7 @@ void StackingOrderTest::testDeletedTransient()
// Close the top-most transient.
connect(transient2, &Window::windowClosed, this, [](Window *original, Deleted *deleted) {
deleted->refWindow();
deleted->ref();
});
QSignalSpy windowClosedSpy(transient2, &Window::windowClosed);
@ -647,7 +647,7 @@ void StackingOrderTest::testDeletedGroupTransient()
// Unmap the transient.
connect(transient, &X11Window::windowClosed, this, [](Window *original, Deleted *deleted) {
deleted->refWindow();
deleted->ref();
});
QSignalSpy windowClosedSpy(transient, &X11Window::windowClosed);

View file

@ -22,7 +22,6 @@ namespace KWin
Deleted::Deleted()
: Window()
, delete_refcount(1)
, m_frame(XCB_WINDOW_NONE)
, m_layer(UnknownLayer)
, m_shade(false)
@ -40,10 +39,6 @@ Deleted::Deleted()
Deleted::~Deleted()
{
if (delete_refcount != 0) {
qCCritical(KWIN_CORE) << "Deleted client has non-zero reference count (" << delete_refcount << ")";
}
Q_ASSERT(delete_refcount == 0);
if (workspace()) {
workspace()->removeDeleted(this);
}
@ -108,14 +103,6 @@ void Deleted::copyToDeleted(Window *window)
m_wasLockScreen = window->isLockScreen();
}
void Deleted::unrefWindow()
{
if (--delete_refcount > 0) {
return;
}
delete this;
}
QMargins Deleted::frameMargins() const
{
return m_frameMargins;

View file

@ -20,9 +20,7 @@ class KWIN_EXPORT Deleted : public Window
public:
static Deleted *create(Window *c);
// used by effects to keep the window around for e.g. fadeout effects when it's destroyed
void refWindow();
void unrefWindow();
QMargins frameMargins() const override;
int desktop() const override;
QStringList activities() const override;
@ -137,7 +135,6 @@ private:
QMargins m_frameMargins;
int delete_refcount;
int desk;
QStringList activityList;
QRectF contentsRect; // for clientPos()/clientSize()
@ -165,11 +162,6 @@ private:
bool m_wasLockScreen;
};
inline void Deleted::refWindow()
{
++delete_refcount;
}
} // namespace
Q_DECLARE_METATYPE(KWin::Deleted *)

View file

@ -1977,7 +1977,7 @@ const EffectWindowGroup *EffectWindowImpl::group() const
void EffectWindowImpl::refWindow()
{
if (auto d = static_cast<Deleted *>(m_window->isDeleted() ? m_window : nullptr)) {
return d->refWindow();
return d->ref();
}
Q_UNREACHABLE(); // TODO
}
@ -1985,7 +1985,7 @@ void EffectWindowImpl::refWindow()
void EffectWindowImpl::unrefWindow()
{
if (auto d = static_cast<Deleted *>(m_window->isDeleted() ? m_window : nullptr)) {
return d->unrefWindow(); // delays deletion in case
return d->unref(); // delays deletion in case
}
Q_UNREACHABLE(); // TODO
}

View file

@ -160,9 +160,9 @@ void InputPanelV1Window::destroyWindow()
Q_EMIT windowClosed(this, deleted);
StackingUpdatesBlocker blocker(workspace());
waylandServer()->removeWindow(this);
deleted->unrefWindow();
deleted->unref();
delete this;
unref();
}
NET::WindowType InputPanelV1Window::windowType(bool, int) const

View file

@ -371,10 +371,10 @@ void InternalWindow::destroyWindow()
workspace()->removeInternalWindow(this);
deleted->unrefWindow();
deleted->unref();
m_handle = nullptr;
delete this;
unref();
}
bool InternalWindow::hasPopupGrab() const

View file

@ -181,9 +181,9 @@ void LayerShellV1Window::destroyWindow()
StackingUpdatesBlocker blocker(workspace());
cleanGrouping();
waylandServer()->removeWindow(this);
deleted->unrefWindow();
deleted->unref();
scheduleRearrange();
delete this;
unref();
}
void LayerShellV1Window::closeWindow()

View file

@ -155,9 +155,9 @@ void Unmanaged::release(ReleaseReason releaseReason)
workspace()->removeUnmanaged(this);
if (releaseReason != ReleaseReason::KWinShutsDown) {
disownDataPassedToDeleted();
del->unrefWindow();
del->unref();
}
deleteUnmanaged(this);
unref();
}
void Unmanaged::deleteUnmanaged(Unmanaged *c)

View file

@ -130,6 +130,19 @@ Window::~Window()
delete info;
}
void Window::ref()
{
++m_refCount;
}
void Window::unref()
{
--m_refCount;
if (m_refCount == 0) {
delete this;
}
}
QDebug operator<<(QDebug debug, const Window *window)
{
QDebugStateSaver saver(debug);

View file

@ -562,6 +562,9 @@ class KWIN_EXPORT Window : public QObject
public:
~Window() override;
void ref();
void unref();
virtual xcb_window_t frameId() const;
xcb_window_t window() const;
/**
@ -1866,6 +1869,7 @@ private:
void maybeSendFrameCallback();
// when adding new data members, check also copyToDeleted()
int m_refCount = 1;
QUuid m_internalId;
Xcb::Window m_client;
bool is_shape;

View file

@ -415,9 +415,9 @@ void X11Window::releaseWindow(bool on_shutdown)
unblockGeometryUpdates(); // Don't use GeometryUpdatesBlocker, it would now set the geometry
if (!on_shutdown) {
disownDataPassedToDeleted();
del->unrefWindow();
del->unref();
}
deleteClient(this);
unref();
ungrabXServer();
}
@ -453,8 +453,8 @@ void X11Window::destroyWindow()
m_frame.reset();
unblockGeometryUpdates(); // Don't use GeometryUpdatesBlocker, it would now set the geometry
disownDataPassedToDeleted();
del->unrefWindow();
deleteClient(this);
del->unref();
unref();
}
/**

View file

@ -302,8 +302,8 @@ void XdgSurfaceWindow::destroyWindow()
setDecoration(nullptr);
cleanGrouping();
waylandServer()->removeWindow(this);
deleted->unrefWindow();
delete this;
deleted->unref();
unref();
}
void XdgSurfaceWindow::updateClientArea()