Skip to content

Commit

Permalink
Delete TitleBar buttons directly if they're not in their event handler
Browse files Browse the repository at this point in the history
If they're inside the event handler, they will be deleted later, otherwise
immediately. By doing it immediately we prevent leaks at exit and make
valgrind and other tools happy. Specially since due to the
QTBUG-83030 workaround some leaks were introduced, as QTimers don't
run after qApp went away.
  • Loading branch information
iamsergio committed Mar 20, 2024
1 parent 3db1cf4 commit 1fff6ba
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/qtwidgets/views/TitleBar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <QHBoxLayout>
#include <QLabel>
#include <QTimer>
#include <QScopedValueRollback>

using namespace KDDockWidgets;
using namespace KDDockWidgets::QtWidgets;
Expand Down Expand Up @@ -102,6 +103,14 @@ QSize Button::sizeHint() const
return QSize(m, m);
}

bool Button::event(QEvent *ev)
{
// A Button can trigger the deletion of its parent, in which case we use deleteLater.
QScopedValueRollback<bool> guard(m_inEventHandler, true);

return QToolButton::event(ev);
}

class KDDockWidgets::QtWidgets::TitleBar::Private
{
public:
Expand Down Expand Up @@ -144,6 +153,13 @@ TitleBar::~TitleBar()
if (!button)
continue;

if (auto kddwButton = qobject_cast<Button *>(button); !kddwButton->m_inEventHandler) {
// Minor optimization. If the button is not in an event handler it's safe to delete immediately.
// This saves us from memory leaks at shutdown when using the below QTimer::singleShot() hack.
delete kddwButton;
continue;
}

button->setParent(nullptr);
if (usesQTBUG83030Workaround()) {
QTimer::singleShot(0, button, [button] {
Expand Down
5 changes: 5 additions & 0 deletions src/qtwidgets/views/TitleBar.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,13 @@ class Button : public QToolButton
~Button() override;

protected:
friend class QtWidgets::TitleBar;

bool event(QEvent *ev) override;
QSize sizeHint() const override;
void paintEvent(QPaintEvent *) override;

bool m_inEventHandler = false;
};

}
Expand Down

0 comments on commit 1fff6ba

Please sign in to comment.