fix: panel/window bugs surfaced by new gtest coverage

- MainWindowLayoutInfo: toXml() iterated open_sequences_ for the
  <viewers> section and fromXml() never parsed it, so open footage
  viewers were lost on layout save/load
- PanelWidget never set QObject::objectName, so
  PanelManager::GetPanelWithName() always returned nullptr and every
  caller (layout restore, NodeView param panel lookup) was dead code
- PanelManager::DestroyInstance() left instance_ dangling (UAF on any
  later RegisterPanel), unlike the other singletons
This commit is contained in:
2026-07-17 16:53:13 +08:00
parent 0dae545cba
commit c812f6ea28
3 changed files with 21 additions and 2 deletions
+5
View File
@@ -42,6 +42,11 @@ PanelWidget::PanelWidget(const QString &object_name)
, border_visible_(false)
, signal_instead_of_close_(false)
{
// KDDockWidgets stores object_name as its uniqueName but does not set it
// as the QObject::objectName; PanelManager::GetPanelWithName() (and layout
// restore in MainWindow) look panels up by objectName, so mirror it here
setObjectName(object_name);
View<QWidget>::setFocusPolicy(Qt::ClickFocus);
connect(this, &PanelWidget::shown, this,
+1
View File
@@ -98,6 +98,7 @@ void PanelManager::CreateInstance()
void PanelManager::DestroyInstance()
{
delete instance_;
instance_ = nullptr;
}
PanelManager *PanelManager::instance()
+15 -2
View File
@@ -48,10 +48,10 @@ void MainWindowLayoutInfo::toXml(QXmlStreamWriter *writer) const
writer->writeStartElement(QStringLiteral("viewers"));
foreach (Sequence *sequence, open_sequences_) {
foreach (ViewerOutput *viewer, open_viewers_) {
writer->writeTextElement(
QStringLiteral("viewer"),
QString::number(reinterpret_cast<quintptr>(sequence)));
QString::number(reinterpret_cast<quintptr>(viewer)));
}
writer->writeEndElement(); // viewers
@@ -129,6 +129,19 @@ MainWindowLayoutInfo::fromXml(QXmlStreamReader *reader,
}
}
} else if (reader->name() == QStringLiteral("viewers")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("viewer")) {
quintptr item_id = reader->readElementText().toULongLong();
ViewerOutput *open_viewer =
static_cast<ViewerOutput *>(node_ptrs.value(item_id));
info.open_viewers_.push_back(open_viewer);
} else {
reader->skipCurrentElement();
}
}
} else if (reader->name() == QStringLiteral("state")) {
info.state_ =
QByteArray::fromBase64(reader->readElementText().toLatin1());