From a38b9b5b1a53ba9be989bed84d0368ce6701a5f1 Mon Sep 17 00:00:00 2001 From: Fan PengCheng Date: Tue, 13 Apr 2021 23:46:49 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=8F=8D=E5=A4=8D?= =?UTF-8?q?=E6=8F=92=E6=8B=94=E6=98=BE=E7=A4=BA=E5=99=A8=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E7=9A=84=E5=B4=A9=E6=BA=83=E7=8E=B0=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QScreen指针变为野指针导致,因为QDesktopWidget的screenCountChanged信号发出来的较慢,导致使用了已经销毁的QScreen指针,换成QGuiApplication的screenAdded和screenRemoved信号,从代码流程上来说,一但屏幕有变化,这两个信号就会理科发送,明显更安全 Log: 修复反复插拔显示器导致的崩溃现象 Change-Id: Ia97bad2dbf3ab45fe2cbb5b5b616bb09e887a012 --- frame/display/displaymanager.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/frame/display/displaymanager.cpp b/frame/display/displaymanager.cpp index 4a5e73e8d..969abc6fd 100644 --- a/frame/display/displaymanager.cpp +++ b/frame/display/displaymanager.cpp @@ -35,7 +35,11 @@ DisplayManager::DisplayManager(QObject *parent) , m_onlyInPrimary(Utils::SettingValue("com.deepin.dde.dock.mainwindow", "/com/deepin/dde/dock/mainwindow/", "onlyShowPrimary", false).toBool()) { connect(qApp, &QApplication::primaryScreenChanged, this, &DisplayManager::primaryScreenChanged); - connect(QApplication::desktop(), &QDesktopWidget::screenCountChanged, this, &DisplayManager::screenCountChanged); + connect(qApp, &QGuiApplication::screenAdded, this, &DisplayManager::screenCountChanged); + connect(qApp, &QGuiApplication::screenRemoved, this, &DisplayManager::screenCountChanged); + //Note: 如果只关联QDesktopWidget::screenCountChanged信号,反复插拔显示器,概率性崩溃,是因为m_screens里面的指针部分还没来得及remove就被销毁了,导致野指针 + // screenCountChanged信号不是立刻发送的,源码里面可以看到所在函数是队列连接的形式,即通过qApp->screens()拿到的的数据已经变了,这个信号仍然未发送 + // connect(QApplication::desktop(), &QDesktopWidget::screenCountChanged, this, &DisplayManager::screenCountChanged); connect(m_delayTimer, &QTimer::timeout, this, [ = ] { updateScreenDockInfo(); @@ -251,6 +255,7 @@ void DisplayManager::updateScreenDockInfo() */ void DisplayManager::screenCountChanged() { + qDebug() << __FUNCTION__; // 找到过期的screen指针 QList to_remove_list; for (auto s : m_screens) { @@ -287,6 +292,8 @@ void DisplayManager::screenCountChanged() m_screens.append(s); } + qDebug() << "屏幕数量" << m_screens.count(); + // 屏幕数量发生变化,应该刷新一下任务栏的显示 m_delayTimer->start(); }