fix: 修复反复插拔显示器导致的崩溃现象

QScreen指针变为野指针导致,因为QDesktopWidget的screenCountChanged信号发出来的较慢,导致使用了已经销毁的QScreen指针,换成QGuiApplication的screenAdded和screenRemoved信号,从代码流程上来说,一但屏幕有变化,这两个信号就会理科发送,明显更安全

Log: 修复反复插拔显示器导致的崩溃现象
Change-Id: Ia97bad2dbf3ab45fe2cbb5b5b616bb09e887a012
This commit is contained in:
Fan PengCheng 2021-04-13 23:46:49 +08:00
parent 5da0c3d4a3
commit a38b9b5b1a

View File

@ -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<QScreen *> 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();
}