fix: 修复找不到屏幕信息导致的任务栏不显示的情况

Display服务给出的屏幕名有时候是异常的,比如VGA的屏幕刚接上的时候有时候后端给出的服务名时":0.0",导致获取不到正确的屏幕信息,从而导致任务栏显示位置异常

Log: 修复任务栏偶尔不显示的情况
Bug: https://pms.uniontech.com/zentao/bug-view-69484.html
Change-Id: Id6d6505255ddd2fd24bb873dbc9307fa0bb2c5c1
This commit is contained in:
Fan PengCheng 2021-04-01 13:58:04 +08:00
parent 6e00ab1323
commit dc4074b4bd
4 changed files with 68 additions and 9 deletions

View File

@ -80,6 +80,8 @@ void Monitor::setName(const QString &name)
{
qDebug() << "screen name change from :" << m_name << " to: " << name;
m_name = name;
Q_EMIT nameChanged(m_name);
}
void Monitor::setPath(const QString &path)

View File

@ -104,6 +104,7 @@ public:
Q_SIGNALS:
void geometryChanged() const;
void enableChanged(bool enable) const;
void nameChanged(const QString &name) const;
public Q_SLOTS:
void setX(const int x);

View File

@ -303,11 +303,23 @@ void MultiScreenWorker::monitorAdded(const QString &path)
// 这里有可能在使用Monitor中的数据时但实际上Monitor数据还未准备好以Monitor中的信号为准不能以MonitorInter中信号为准
connect(mon, &Monitor::geometryChanged, this, &MultiScreenWorker::requestUpdateMonitorInfo);
connect(mon, &Monitor::enableChanged, this, &MultiScreenWorker::requestUpdateMonitorInfo);
connect(mon, &Monitor::nameChanged, this, &MultiScreenWorker::requestUpdateMonitorInfo);
// NOTE: DO NOT using async dbus call. because we need to have a unique name to distinguish each monitor
Q_ASSERT(inter->isValid());
mon->setName(inter->name());
#if 0 // 模拟屏幕名称中途发生变化的情况,测试任务栏是否还能正常显示
QTimer::singleShot(5000, this, [ = ]{
if (mon->name() == "VGA-0")
mon->setName(":0.0");
});
QTimer::singleShot(10000, this, [ = ]{
if (mon->name() == ":0.0")
mon->setName("VGA-0");
});
#endif
mon->setMonitorEnable(inter->enabled());
mon->setPath(path);
mon->setX(inter->x());
@ -382,6 +394,16 @@ void MultiScreenWorker::onWindowSizeChanged(uint value)
void MultiScreenWorker::primaryScreenChanged()
{
QString primaryName = m_displayInter->primary();
if (primaryName.isEmpty() && qApp->primaryScreen()->name().isEmpty()) {
qWarning() << "current primary screen:" << primaryName;
return;
}
// 后端数据不准确使用qt获取的数据
if (primaryName.isEmpty())
primaryName = qApp->primaryScreen()->name();
// 先更新主屏信息
m_ds.updatePrimary(m_displayInter->primary());
m_mtrInfo.setPrimary(m_displayInter->primary());
@ -538,9 +560,8 @@ void MultiScreenWorker::onHideStateChanged()
m_hideState = state;
// 检查当前屏幕的当前位置是否允许显示,不允许需要更新显示信息(这里应该在函数外部就处理好,不应该走到这里)
Monitor *currentMonitor = monitorByName(m_mtrInfo.validMonitor(), m_ds.current());
Monitor *currentMonitor = waitAndGetScreen(m_ds.current());
if (!currentMonitor) {
qWarning() << "cannot find monitor by name: " << m_ds.current();
return;
}
@ -971,9 +992,9 @@ void MultiScreenWorker::onRequestDelayShowDock(const QString &screenName)
m_ds.updateDockedScreen(screenName);
Monitor *currentMonitor = monitorByName(m_mtrInfo.validMonitor(), screenName);
// 检查当前屏幕的当前位置是否允许显示,不允许需要更新显示信息(这里应该在函数外部就处理好,不应该走到这里)
Monitor *currentMonitor = waitAndGetScreen(screenName);
if (!currentMonitor) {
qWarning() << "cannot find monitor by name: " << screenName;
return;
}
@ -1031,6 +1052,8 @@ void MultiScreenWorker::initConnection()
* qt-dbus-factory DBusExtendedAbstractInterface::internalPropGet
* qt-dbus-factory 广
*/
connect(qApp, &QApplication::primaryScreenChanged, this, &MultiScreenWorker::primaryScreenChanged, Qt::QueuedConnection);
#if 0
// connect(m_dockInter, &DBusDock::PositionChanged, this, &MultiScreenWorker::onPositionChanged);
// connect(m_dockInter, &DBusDock::DisplayModeChanged, this, &MultiScreenWorker::onDisplayModeChanged);
@ -1437,15 +1460,19 @@ QString MultiScreenWorker::getValidScreen(const Position &pos)
}
}
if (primaryName.isEmpty()) {
if (primaryName.isEmpty() && qApp->primaryScreen()->name().isEmpty()) {
qWarning() << "cannnot find primary screen, wait for 3s to update...";
QTimer::singleShot(3000, this, &MultiScreenWorker::requestUpdateMonitorInfo);
return QString();
}
Monitor *primaryMonitor = monitorByName(m_mtrInfo.validMonitor(), primaryName);
if (primaryName.isEmpty()) {
primaryName = qApp->primaryScreen()->name();
m_ds.updatePrimary(primaryName);
}
Monitor *primaryMonitor = waitAndGetScreen(primaryName);
if (!primaryMonitor) {
qWarning() << "cannot find monitor by name: " << primaryName;
return QString();
}
@ -1470,9 +1497,8 @@ void MultiScreenWorker::resetDockScreen()
{
QList<Monitor *> monitorList = m_mtrInfo.validMonitor();
if (monitorList.size() == 2) {
Monitor *primaryMonitor = monitorByName(m_mtrInfo.validMonitor(), m_ds.primary());
Monitor *primaryMonitor = waitAndGetScreen(m_ds.primary());
if (!primaryMonitor) {
qWarning() << "cannot find monitor by name: " << m_ds.primary();
return;
}
if (!primaryMonitor->dockPosition().docked(position())) {
@ -1967,3 +1993,31 @@ void MultiScreenWorker::onGSettingsChange(const QString &changeKey)
emit requestUpdateMonitorInfo();
}
}
/**
* @brief MultiScreenWorker::wait_and_get_screen
* @param screenName screenName对应的指针m_mtrInfo数据异常了Display服务中查询数据了
* @return
*/
Monitor *MultiScreenWorker::waitAndGetScreen(const QString& screenName)
{
Monitor *currentMonitor = nullptr;
int tryNum =0;
do {
currentMonitor = monitorByName(m_mtrInfo.validMonitor(), screenName);
if (currentMonitor)
break;
tryNum ++;
qWarning() << "cannot find monitor by name: " << m_ds.current() << ", try " << tryNum << "times";
// 阻塞200ms尝试等待数据正常
QThread::msleep(200);
} while (!currentMonitor && tryNum <= 30); // 最多等待6秒还是获取不到就绝对是数据异常了
if (!currentMonitor) {
qWarning() << "cannot find monitor by name: " << m_ds.current();
}
return currentMonitor;
}

View File

@ -311,6 +311,8 @@ private slots:
// gsetting配置改变响应槽
void onGSettingsChange(const QString &changeKey);
Monitor *waitAndGetScreen(const QString& screenName);
private:
MainWindow *parent();
// 初始化数据信息