fix: 修复切换显示器模式时任务栏概率性不显示的问题

当连接双屏,从仅某屏切换到仅显示到另外一个屏幕时,这个时候屏幕的坐标未发生变化,但实际上屏幕名已经变化了,但使用的qt库中没有类似QScreen的nameChanged信号,收不到此消息,导致任务栏仍然显示在之前的屏幕上的位置。
还因为以前为了减少耗时,多次屏幕信息变化会被延迟10ms后总结为一次变化通知任务栏更新位置,导致概率性获取任务栏的信息错误。

Log: 修复任务栏概率性不显示的问题
Bug: https://pms.uniontech.com/zentao/bug-view-78399.html
Change-Id: Id784c3a6142586645bc837e08964489e6987c2f4
This commit is contained in:
Fan PengCheng 2021-05-08 21:35:35 +08:00
parent e6b38b14bd
commit d0cef89503
3 changed files with 31 additions and 27 deletions

View File

@ -29,34 +29,19 @@
DisplayManager::DisplayManager(QObject *parent)
: QObject(parent)
, m_display(new DisplayInter("com.deepin.daemon.Display", "/com/deepin/daemon/Display", QDBusConnection::sessionBus(), this))
, m_delayTimer(new QTimer(this))
, m_gsettings(Utils::SettingsPtr("com.deepin.dde.dock.mainwindow", "/com/deepin/dde/dock/mainwindow/", this))
, 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(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();
#ifdef QT_DEBUG
qInfo() << m_screenPositionMap;
#endif
Q_EMIT screenInfoChanged();
});
if (m_gsettings)
connect(m_gsettings, &QGSettings::changed, this, &DisplayManager::onGSettingsChanged);
m_delayTimer->setInterval(10);
m_delayTimer->setSingleShot(true);
screenCountChanged();
updateScreenDockInfo();
QTimer::singleShot(0, this, &DisplayManager::screenInfoChanged);
}
/**
@ -80,7 +65,6 @@ QScreen *DisplayManager::screen(const QString &screenName) const
return s;
}
qWarning() << "Screen: " << screenName << " can`t be found!";
return nullptr;
}
@ -284,15 +268,33 @@ void DisplayManager::screenCountChanged()
| Qt::InvertedLandscapeOrientation
| Qt::InvertedPortraitOrientation);
connect(s, &QScreen::geometryChanged, m_delayTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
connect(s, &QScreen::primaryOrientationChanged, m_delayTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
connect(s, &QScreen::orientationChanged, m_delayTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
// 显示器信息发生任何变化时,都应该重新刷新一次任务栏的显示位置
connect(s, &QScreen::geometryChanged, this, &DisplayManager::dockInfoChanged);
connect(s, &QScreen::availableGeometryChanged, this, &DisplayManager::dockInfoChanged);
connect(s, &QScreen::physicalSizeChanged, this, &DisplayManager::dockInfoChanged);
connect(s, &QScreen::physicalDotsPerInchChanged, this, &DisplayManager::dockInfoChanged);
connect(s, &QScreen::logicalDotsPerInchChanged, this, &DisplayManager::dockInfoChanged);
connect(s, &QScreen::virtualGeometryChanged, this, &DisplayManager::dockInfoChanged);
connect(s, &QScreen::primaryOrientationChanged, this, &DisplayManager::dockInfoChanged);
connect(s, &QScreen::orientationChanged, this, &DisplayManager::dockInfoChanged);
connect(s, &QScreen::refreshRateChanged, this, &DisplayManager::dockInfoChanged);
m_screens.append(s);
}
// 屏幕数量发生变化,应该刷新一下任务栏的显示
m_delayTimer->start();
dockInfoChanged();
}
void DisplayManager::dockInfoChanged()
{
updateScreenDockInfo();
#ifdef QT_DEBUG
qInfo() << m_screenPositionMap;
#endif
Q_EMIT screenInfoChanged();
}
/**
@ -305,8 +307,6 @@ void DisplayManager::onGSettingsChanged(const QString &key)
if (key == "onlyShowPrimary") {
m_onlyInPrimary = Utils::SettingValue("com.deepin.dde.dock.mainwindow", "/com/deepin/dde/dock/mainwindow/", "onlyShowPrimary", false).toBool();
updateScreenDockInfo();
m_delayTimer->start();
dockInfoChanged();
}
}

View File

@ -55,6 +55,7 @@ private:
private Q_SLOTS:
void screenCountChanged();
void dockInfoChanged();
void onGSettingsChanged(const QString &key);
Q_SIGNALS:
@ -62,8 +63,6 @@ Q_SIGNALS:
void screenInfoChanged(); // 屏幕信息发生变化,需要调整任务栏显示,只需要这一个信号,其他的都不要,简化流程
private:
DisplayInter *m_display;
QTimer *m_delayTimer;
QList <QScreen *> m_screens;
QMap <QScreen *, QMap <Position, bool>> m_screenPositionMap;
const QGSettings *m_gsettings; // 多屏配置控制

View File

@ -242,6 +242,9 @@ void MultiScreenWorker::onExtralRegionMonitorChanged(int x, int y, const QString
if (m_extralRegisterKey != key)
return;
// FIXME:每次都要重置一下是因为qt中的QScreen类缺少nameChanged信号后面会给上游提交patch修复
resetDockScreen();
// 鼠标移动到任务栏界面之外停止计时器延时2秒改变任务栏所在屏幕
m_delayWakeTimer->stop();
@ -783,6 +786,8 @@ void MultiScreenWorker::onRequestUpdatePosition(const Position &fromPos, const P
void MultiScreenWorker::onRequestUpdateMonitorInfo()
{
resetDockScreen();
// 只需要在屏幕信息变化的时候更新,其他时间不需要更新
onRequestUpdateRegionMonitor();