Gui: Workaround for crash on close of MDI window

The Qt6 (up to Qt 6.7.3 now) contains bug, which can lead, under
specific circumstances, to crash of the application, when the
MDI window is closed. The circumstances are:

* at least 2 MDI windows needs to be open
* stylesheet muset set different size (border, margin) for activated and un-activated tabBar tab
* the closed window must be inactive, but created before the window now active and open
* race condition must occur betwee the closing and resize event handlers for the tabBar
  (see qt bug for details)

So this bug only occures with Qt6 with the Dark or Light styles selected (no classic) and only if
specific sequence of steps is followed during opening and closing the MDI windows.

The bug is in Qt code path executed when QMdiArea::ActivationHistoryOrder is set.

The other possible workaround might be to change all the affected stylesheets, but this seems to me
impractical and also fragile, because the affected code path will be still active.

https://bugreports.qt.io/browse/QTBUG-129596
This commit is contained in:
Jiří Pinkava
2024-10-02 15:53:00 +02:00
committed by Chris Hennes
parent 95f0bd0a5c
commit fed918a151
4 changed files with 14 additions and 1 deletions

View File

@@ -449,6 +449,13 @@ Application::Application(bool GUIenabled)
PyModule_AddFunctions(module, Application::Methods);
}
Py::Module(module).setAttr(std::string("ActiveDocument"), Py::None());
Py::Module(module).setAttr(std::string("HasQtBug_129596"),
#ifdef HAS_QTBUG_129596
Py::True()
#else
Py::False()
#endif
);
UiLoaderPy::init_type();
Base::Interpreter().addType(UiLoaderPy::type_object(), module, "UiLoader");

View File

@@ -30,6 +30,10 @@
#include <App/Application.h>
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
# define HAS_QTBUG_129596
#endif
class QCloseEvent;
class SoNode;
class NavlibInterface;

View File

@@ -450,7 +450,9 @@ MainWindow::MainWindow(QWidget * parent, Qt::WindowFlags f)
d->mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
d->mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
d->mdiArea->setOption(QMdiArea::DontMaximizeSubWindowOnActivation, false);
#ifndef HAS_QTBUG_129596
d->mdiArea->setActivationOrder(QMdiArea::ActivationHistoryOrder);
#endif
d->mdiArea->setBackground(QBrush(QColor(160,160,160)));
setCentralWidget(d->mdiArea);

View File

@@ -2092,7 +2092,7 @@ class DocumentObserverCases(unittest.TestCase):
FreeCAD.closeDocument(self.Doc2.Name)
self.assertEqual(self.Obs.signal.pop(), "DocDeleted")
self.assertTrue(self.Obs.parameter.pop() is self.Doc2)
if FreeCAD.GuiUp:
if FreeCAD.GuiUp and not FreeCAD.Gui.HasQtBug_129596:
# only has document activated signal when running in GUI mode
self.assertEqual(self.Obs.signal.pop(), "DocActivated")
self.assertTrue(self.Obs.parameter.pop() is self.Doc1)