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

View file

@ -22,7 +22,6 @@ namespace KWin
Deleted::Deleted() Deleted::Deleted()
: Window() : Window()
, delete_refcount(1)
, m_frame(XCB_WINDOW_NONE) , m_frame(XCB_WINDOW_NONE)
, m_layer(UnknownLayer) , m_layer(UnknownLayer)
, m_shade(false) , m_shade(false)
@ -40,10 +39,6 @@ Deleted::Deleted()
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()) { if (workspace()) {
workspace()->removeDeleted(this); workspace()->removeDeleted(this);
} }
@ -108,14 +103,6 @@ void Deleted::copyToDeleted(Window *window)
m_wasLockScreen = window->isLockScreen(); m_wasLockScreen = window->isLockScreen();
} }
void Deleted::unrefWindow()
{
if (--delete_refcount > 0) {
return;
}
delete this;
}
QMargins Deleted::frameMargins() const QMargins Deleted::frameMargins() const
{ {
return m_frameMargins; return m_frameMargins;

View file

@ -20,9 +20,7 @@ class KWIN_EXPORT Deleted : public Window
public: public:
static Deleted *create(Window *c); 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; QMargins frameMargins() const override;
int desktop() const override; int desktop() const override;
QStringList activities() const override; QStringList activities() const override;
@ -137,7 +135,6 @@ private:
QMargins m_frameMargins; QMargins m_frameMargins;
int delete_refcount;
int desk; int desk;
QStringList activityList; QStringList activityList;
QRectF contentsRect; // for clientPos()/clientSize() QRectF contentsRect; // for clientPos()/clientSize()
@ -165,11 +162,6 @@ private:
bool m_wasLockScreen; bool m_wasLockScreen;
}; };
inline void Deleted::refWindow()
{
++delete_refcount;
}
} // namespace } // namespace
Q_DECLARE_METATYPE(KWin::Deleted *) Q_DECLARE_METATYPE(KWin::Deleted *)

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -130,6 +130,19 @@ Window::~Window()
delete info; 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) QDebug operator<<(QDebug debug, const Window *window)
{ {
QDebugStateSaver saver(debug); QDebugStateSaver saver(debug);

View file

@ -562,6 +562,9 @@ class KWIN_EXPORT Window : public QObject
public: public:
~Window() override; ~Window() override;
void ref();
void unref();
virtual xcb_window_t frameId() const; virtual xcb_window_t frameId() const;
xcb_window_t window() const; xcb_window_t window() const;
/** /**
@ -1866,6 +1869,7 @@ private:
void maybeSendFrameCallback(); void maybeSendFrameCallback();
// when adding new data members, check also copyToDeleted() // when adding new data members, check also copyToDeleted()
int m_refCount = 1;
QUuid m_internalId; QUuid m_internalId;
Xcb::Window m_client; Xcb::Window m_client;
bool is_shape; 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 unblockGeometryUpdates(); // Don't use GeometryUpdatesBlocker, it would now set the geometry
if (!on_shutdown) { if (!on_shutdown) {
disownDataPassedToDeleted(); disownDataPassedToDeleted();
del->unrefWindow(); del->unref();
} }
deleteClient(this); unref();
ungrabXServer(); ungrabXServer();
} }
@ -453,8 +453,8 @@ void X11Window::destroyWindow()
m_frame.reset(); m_frame.reset();
unblockGeometryUpdates(); // Don't use GeometryUpdatesBlocker, it would now set the geometry unblockGeometryUpdates(); // Don't use GeometryUpdatesBlocker, it would now set the geometry
disownDataPassedToDeleted(); disownDataPassedToDeleted();
del->unrefWindow(); del->unref();
deleteClient(this); unref();
} }
/** /**

View file

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