fix: 修复重启AM后任务栏崩溃的问题

1、重启AM后,需要重新更新每个子部件的dockInter,因为这些字部件的dockInter是从MultiScreenWorker类中获取的,而MultiScreenWorker类中的dockInter已经被释放重新获取了;
2、重新启动AM后,由于任务栏会重新执行positionChanged的方法,在这个过程中会执行300毫秒的动画,在动画执行完成后,会判断当前服务是否重启过,如果重启过服务,则重新刷新界面

Log: 修复重启AM后任务栏崩溃的问题
Influence: 重启AM服务,观察任务栏是否重启
Task: https://pms.uniontech.com/task-view-225201.html
Change-Id: I1d5337fe7a0101450dfce7338d32aad73c14f697
This commit is contained in:
donghualin 2022-12-08 08:20:54 +00:00
parent 541cdf60e7
commit 477bc09965
14 changed files with 89 additions and 34 deletions

View File

@ -87,6 +87,11 @@ bool RecentAppHelper::dockAppIsVisible() const
|| m_appWidget->layout()->count() > 0); || m_appWidget->layout()->count() > 0);
} }
void RecentAppHelper::updateDockInter(DockInter *dockInter)
{
m_dockInter = dockInter;
}
bool RecentAppHelper::eventFilter(QObject *watched, QEvent *event) bool RecentAppHelper::eventFilter(QObject *watched, QEvent *event)
{ {
if (watched == m_appWidget || watched == m_recentWidget) { if (watched == m_appWidget || watched == m_recentWidget) {

View File

@ -47,6 +47,7 @@ public:
void removeAppItem(DockItem *dockItem); void removeAppItem(DockItem *dockItem);
bool recentIsVisible() const; bool recentIsVisible() const;
bool dockAppIsVisible() const; bool dockAppIsVisible() const;
void updateDockInter(DockInter *dockInter);
Q_SIGNALS: Q_SIGNALS:
void requestUpdate(); void requestUpdate();

View File

@ -32,9 +32,9 @@
#define DIS_INS DisplayManager::instance() #define DIS_INS DisplayManager::instance()
MenuWorker::MenuWorker(QObject *parent) MenuWorker::MenuWorker(DockInter *dockInter, QObject *parent)
: QObject(parent) : QObject(parent)
, m_dockInter(new DockInter(dockServiceName(), dockServicePath(), QDBusConnection::sessionBus(), this)) , m_dockInter(dockInter)
{ {
} }

View File

@ -35,7 +35,7 @@ class MenuWorker : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit MenuWorker(QObject *parent = nullptr); explicit MenuWorker(DockInter *dockInter, QObject *parent = nullptr);
void exec(); void exec();

View File

@ -63,16 +63,15 @@ MultiScreenWorker::MultiScreenWorker(QObject *parent)
, m_appearanceInter(new Appearance("org.deepin.dde.Appearance1", "/org/deepin/dde/Appearance1", QDBusConnection::sessionBus(), this)) , m_appearanceInter(new Appearance("org.deepin.dde.Appearance1", "/org/deepin/dde/Appearance1", QDBusConnection::sessionBus(), this))
, m_monitorUpdateTimer(new QTimer(this)) , m_monitorUpdateTimer(new QTimer(this))
, m_delayWakeTimer(new QTimer(this)) , m_delayWakeTimer(new QTimer(this))
, m_position(Dock::Position::Bottom) , m_position(Dock::Position(-1))
, m_hideMode(Dock::HideMode::KeepShowing) , m_hideMode(Dock::HideMode(-1))
, m_hideState(Dock::HideState::Show) , m_hideState(Dock::HideState(-1))
, m_displayMode(Dock::DisplayMode::Efficient) , m_displayMode(Dock::DisplayMode(-1))
, m_state(AutoHide) , m_state(AutoHide)
{ {
initConnection(); initConnection();
initMembers(); initMembers();
initDockMode(); initDockMode();
initUI();
QMetaObject::invokeMethod(this, &MultiScreenWorker::initDisplayData, Qt::QueuedConnection); QMetaObject::invokeMethod(this, &MultiScreenWorker::initDisplayData, Qt::QueuedConnection);
} }
@ -252,7 +251,7 @@ void MultiScreenWorker::onHideModeChanged(int hideMode)
void MultiScreenWorker::onHideStateChanged(int state) void MultiScreenWorker::onHideStateChanged(int state)
{ {
if (state == Dock::Unknown) if (state == m_hideState)
return; return;
m_hideState = static_cast<HideState>(state); m_hideState = static_cast<HideState>(state);
@ -573,11 +572,6 @@ void MultiScreenWorker::initConnection()
connect(m_launcherInter, static_cast<void (DBusLuncher::*)(bool) const>(&DBusLuncher::VisibleChanged), this, [ = ](bool value) { setStates(LauncherDisplay, value); }); connect(m_launcherInter, static_cast<void (DBusLuncher::*)(bool) const>(&DBusLuncher::VisibleChanged), this, [ = ](bool value) { setStates(LauncherDisplay, value); });
connect(m_dockInter, &DockInter::PositionChanged, this, &MultiScreenWorker::onPositionChanged);
connect(m_dockInter, &DockInter::DisplayModeChanged, this, &MultiScreenWorker::onDisplayModeChanged);
connect(m_dockInter, &DockInter::HideModeChanged, this, &MultiScreenWorker::onHideModeChanged);
connect(m_dockInter, &DockInter::HideStateChanged, this, &MultiScreenWorker::onHideStateChanged);
connect(this, &MultiScreenWorker::requestUpdatePosition, this, &MultiScreenWorker::onRequestUpdatePosition); connect(this, &MultiScreenWorker::requestUpdatePosition, this, &MultiScreenWorker::onRequestUpdatePosition);
connect(this, &MultiScreenWorker::requestUpdateMonitorInfo, this, &MultiScreenWorker::onRequestUpdateMonitorInfo); connect(this, &MultiScreenWorker::requestUpdateMonitorInfo, this, &MultiScreenWorker::onRequestUpdateMonitorInfo);
@ -587,22 +581,14 @@ void MultiScreenWorker::initConnection()
connect(m_monitorUpdateTimer, &QTimer::timeout, this, &MultiScreenWorker::updateDisplay); connect(m_monitorUpdateTimer, &QTimer::timeout, this, &MultiScreenWorker::updateDisplay);
} }
void MultiScreenWorker::initUI()
{
onPositionChanged(dockInter()->position());
onDisplayModeChanged(dockInter()->displayMode());
onHideModeChanged(dockInter()->hideMode());
onOpacityChanged(m_appearanceInter->opacity());
}
void MultiScreenWorker::initDockMode() void MultiScreenWorker::initDockMode()
{ {
if (m_dockInter->isValid()) { if (m_dockInter->isValid()) {
m_position = static_cast<Dock::Position >(m_dockInter->position()); onPositionChanged(dockInter()->position());
m_hideMode = static_cast<Dock::HideMode >(m_dockInter->hideMode()); onDisplayModeChanged(dockInter()->displayMode());
m_hideState = static_cast<Dock::HideState >(m_dockInter->hideState()); onHideModeChanged(dockInter()->hideMode());
m_displayMode = static_cast<Dock::DisplayMode >(m_dockInter->displayMode()); onHideStateChanged(m_dockInter->hideState());
m_opacity = m_dockInter->opacity(); onOpacityChanged(m_dockInter->opacity());
DockItem::setDockPosition(m_position); DockItem::setDockPosition(m_position);
qApp->setProperty(PROP_POSITION, QVariant::fromValue(m_position)); qApp->setProperty(PROP_POSITION, QVariant::fromValue(m_position));
@ -714,6 +700,10 @@ void MultiScreenWorker::checkDaemonDockService()
}); });
connect(dockInter, &DockInter::WindowSizeEfficientChanged, this, &MultiScreenWorker::onWindowSizeChanged); connect(dockInter, &DockInter::WindowSizeEfficientChanged, this, &MultiScreenWorker::onWindowSizeChanged);
connect(dockInter, &DockInter::WindowSizeFashionChanged, this, &MultiScreenWorker::onWindowSizeChanged); connect(dockInter, &DockInter::WindowSizeFashionChanged, this, &MultiScreenWorker::onWindowSizeChanged);
connect(dockInter, &DockInter::PositionChanged, this, &MultiScreenWorker::onPositionChanged);
connect(dockInter, &DockInter::DisplayModeChanged, this, &MultiScreenWorker::onDisplayModeChanged);
connect(dockInter, &DockInter::HideModeChanged, this, &MultiScreenWorker::onHideModeChanged);
connect(dockInter, &DockInter::HideStateChanged, this, &MultiScreenWorker::onHideStateChanged);
}; };
QDBusConnectionInterface *ifc = QDBusConnection::sessionBus().interface(); QDBusConnectionInterface *ifc = QDBusConnection::sessionBus().interface();
@ -728,6 +718,9 @@ void MultiScreenWorker::checkDaemonDockService()
// connect // connect
connectionInit(m_dockInter); connectionInit(m_dockInter);
// 通知主窗体服务已经重启了需要重新获取DockInter
emit serviceRestart();
// reinit data // reinit data
reInitDisplayData(); reInitDisplayData();

View File

@ -127,6 +127,9 @@ signals:
void requestPlayAnimation(const QString &screenName, const Position &position, const Dock::AniAction &animation, bool containMouse = false, bool updatePos = false); void requestPlayAnimation(const QString &screenName, const Position &position, const Dock::AniAction &animation, bool containMouse = false, bool updatePos = false);
void requestChangeDockPosition(const QString &fromScreen, const QString &toScreen, const Position &fromPos, const Position &toPos); void requestChangeDockPosition(const QString &fromScreen, const QString &toScreen, const Position &fromPos, const Position &toPos);
// 服务重新启动的信号
void serviceRestart();
public slots: public slots:
void onAutoHideChanged(const bool autoHide); void onAutoHideChanged(const bool autoHide);
void onRequestUpdateRegionMonitor(); void onRequestUpdateRegionMonitor();
@ -163,7 +166,6 @@ private:
void initMembers(); void initMembers();
void initDockMode(); void initDockMode();
void initConnection(); void initConnection();
void initUI();
void initDisplayData(); void initDisplayData();
void reInitDisplayData(); void reInitDisplayData();

View File

@ -971,6 +971,12 @@ void MainPanelControl::updatePluginsLayout()
} }
} }
void MainPanelControl::updateDockInter(DockInter *dockInter)
{
m_dockInter = dockInter;
m_recentHelper->updateDockInter(dockInter);
}
QSize MainPanelControl::suitableSize(const Position &position, int screenSize, double deviceRatio) const QSize MainPanelControl::suitableSize(const Position &position, int screenSize, double deviceRatio) const
{ {
if (screenSize <= 0) if (screenSize <= 0)

View File

@ -52,6 +52,7 @@ public:
void setDisplayMode(DisplayMode dislayMode); void setDisplayMode(DisplayMode dislayMode);
void resizeDockIcon(); void resizeDockIcon();
void updatePluginsLayout(); void updatePluginsLayout();
void updateDockInter(DockInter *dockInter);
QSize suitableSize(const Position &position, int screenSize, double deviceRatio) const; QSize suitableSize(const Position &position, int screenSize, double deviceRatio) const;

View File

@ -60,6 +60,7 @@ MainWindow::MainWindow(MultiScreenWorker *multiScreenWorker, QWidget *parent)
: MainWindowBase(multiScreenWorker, parent) : MainWindowBase(multiScreenWorker, parent)
, m_mainPanel(new MainPanelControl(multiScreenWorker->dockInter(), this)) , m_mainPanel(new MainPanelControl(multiScreenWorker->dockInter(), this))
, m_multiScreenWorker(multiScreenWorker) , m_multiScreenWorker(multiScreenWorker)
, m_needUpdateUi(false)
{ {
m_mainPanel->setDisplayMode(m_multiScreenWorker->displayMode()); m_mainPanel->setDisplayMode(m_multiScreenWorker->displayMode());
@ -169,3 +170,20 @@ void MainWindow::resetPanelGeometry()
m_mainPanel->setFixedSize(size()); m_mainPanel->setFixedSize(size());
m_mainPanel->move(0, 0); m_mainPanel->move(0, 0);
} }
void MainWindow::serviceRestart()
{
m_mainPanel->updateDockInter(m_multiScreenWorker->dockInter());
// 在重启服务后MultiScreenWorker会通知WindowManager类执行PositionChanged动画在执行此动作过程中
// 会执行动画,动画需要消耗时间,因此, 在重启服务后需要标记更新UI,在稍后动画执行结束后,需要重新刷新界面的显示,否则任务栏显示错误
m_needUpdateUi = true;
}
void MainWindow::animationFinished(bool showOrHide)
{
if (m_needUpdateUi) {
// 在动画执行结束后如果收到需要更新UI的标记那么则需要重新请求更新界面在更新结束后再将更新UI标记为false,那么在下次进来的时候无需再次更新UI
Q_EMIT requestUpdate();
m_needUpdateUi = false;
}
}

View File

@ -59,6 +59,8 @@ public:
void updateParentGeometry(const Dock::Position &pos, const QRect &rect) override; void updateParentGeometry(const Dock::Position &pos, const QRect &rect) override;
QSize suitableSize(const Dock::Position &pos, const int &screenSize, const double &deviceRatio) const override; QSize suitableSize(const Dock::Position &pos, const int &screenSize, const double &deviceRatio) const override;
void resetPanelGeometry() override; void resetPanelGeometry() override;
void serviceRestart() override;
void animationFinished(bool showOrHide) override;
private: private:
using QWidget::show; using QWidget::show;
@ -74,6 +76,7 @@ private:
QString m_registerKey; QString m_registerKey;
QStringList m_registerKeys; QStringList m_registerKeys;
bool m_needUpdateUi;
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

View File

@ -54,7 +54,6 @@ MainWindowBase::MainWindowBase(MultiScreenWorker *multiScreenWorker, QWidget *pa
: DBlurEffectWidget(parent) : DBlurEffectWidget(parent)
, m_displayMode(Dock::DisplayMode::Efficient) , m_displayMode(Dock::DisplayMode::Efficient)
, m_position(Dock::Position::Bottom) , m_position(Dock::Position::Bottom)
, m_dockInter(multiScreenWorker->dockInter())
, m_dragWidget(new DragWidget(this)) , m_dragWidget(new DragWidget(this))
, m_multiScreenWorker(multiScreenWorker) , m_multiScreenWorker(multiScreenWorker)
, m_updateDragAreaTimer(new QTimer(this)) , m_updateDragAreaTimer(new QTimer(this))
@ -571,9 +570,9 @@ Dock::Position MainWindowBase::position() const
int MainWindowBase::windowSize() const int MainWindowBase::windowSize() const
{ {
if (m_displayMode == Dock::DisplayMode::Efficient) if (m_displayMode == Dock::DisplayMode::Efficient)
return m_dockInter->windowSizeEfficient(); return m_multiScreenWorker->dockInter()->windowSizeEfficient();
return m_dockInter->windowSizeFashion(); return m_multiScreenWorker->dockInter()->windowSizeFashion();
} }
bool MainWindowBase::isDraging() const bool MainWindowBase::isDraging() const
@ -633,7 +632,7 @@ void MainWindowBase::mousePressEvent(QMouseEvent *event)
{ {
if (event->button() == Qt::RightButton && geometry().contains(QCursor::pos())) { if (event->button() == Qt::RightButton && geometry().contains(QCursor::pos())) {
m_multiScreenWorker->onAutoHideChanged(false); m_multiScreenWorker->onAutoHideChanged(false);
MenuWorker menuWorker; MenuWorker menuWorker(m_multiScreenWorker->dockInter());
menuWorker.exec(); menuWorker.exec();
m_multiScreenWorker->onAutoHideChanged(true); m_multiScreenWorker->onAutoHideChanged(true);
} }

View File

@ -63,6 +63,8 @@ public:
QVariantAnimation *createAnimation(QScreen *screen, const Dock::Position &pos, const Dock::AniAction &act); QVariantAnimation *createAnimation(QScreen *screen, const Dock::Position &pos, const Dock::AniAction &act);
virtual void resetPanelGeometry() {} // 重置内部区域,为了让内部区域和当前区域始终保持一致 virtual void resetPanelGeometry() {} // 重置内部区域,为了让内部区域和当前区域始终保持一致
virtual int dockSpace() const; // 与后面窗体之间的间隔 virtual int dockSpace() const; // 与后面窗体之间的间隔
virtual void serviceRestart() {} // 服务重新启动后的操作
virtual void animationFinished(bool showOrHide) {}
Q_SIGNALS: Q_SIGNALS:
void requestUpdate(); void requestUpdate();
@ -105,7 +107,6 @@ private Q_SLOTS:
private: private:
Dock::DisplayMode m_displayMode; Dock::DisplayMode m_displayMode;
Dock::Position m_position; Dock::Position m_position;
DockInter *m_dockInter;
DragWidget *m_dragWidget; DragWidget *m_dragWidget;
MultiScreenWorker *m_multiScreenWorker; MultiScreenWorker *m_multiScreenWorker;
QTimer *m_updateDragAreaTimer; QTimer *m_updateDragAreaTimer;

View File

@ -325,6 +325,16 @@ void WindowManager::showAniFinish()
onRequestNotifyWindowManager(); onRequestNotifyWindowManager();
} }
void WindowManager::animationFinish(bool showOrHide)
{
for (MainWindowBase *mainWindow : m_topWindows) {
if (!mainWindow->isVisible())
continue;
mainWindow->animationFinished(showOrHide);
}
}
void WindowManager::hideAniFinish() void WindowManager::hideAniFinish()
{ {
DockItem::setDockPosition(m_position); DockItem::setDockPosition(m_position);
@ -416,6 +426,8 @@ void WindowManager::updateDockGeometry(const QRect &rect)
return; return;
QScreen *screen = DIS_INS->screen(DOCKSCREEN_INS->current()); QScreen *screen = DIS_INS->screen(DOCKSCREEN_INS->current());
if (!screen || m_position == Dock::Position(-1))
return;
for (MainWindowBase *mainWindow : m_topWindows) { for (MainWindowBase *mainWindow : m_topWindows) {
if (!mainWindow->isVisible()) if (!mainWindow->isVisible())
@ -444,6 +456,7 @@ void WindowManager::updateDockGeometry(const QRect &rect)
windowShowSize.setWidth(rect.width()); windowShowSize.setWidth(rect.width());
break; break;
} }
default: break;
} }
mainWindow->blockSignals(true); mainWindow->blockSignals(true);
@ -462,11 +475,12 @@ void WindowManager::initConnection()
{ {
connect(m_dbusDaemonInterface, &QDBusConnectionInterface::serviceOwnerChanged, this, &WindowManager::onDbusNameOwnerChanged); connect(m_dbusDaemonInterface, &QDBusConnectionInterface::serviceOwnerChanged, this, &WindowManager::onDbusNameOwnerChanged);
connect(m_multiScreenWorker, &MultiScreenWorker::requestUpdateDockGeometry, this, &WindowManager::onUpdateDockGeometry); connect(m_multiScreenWorker, &MultiScreenWorker::serviceRestart, this, &WindowManager::onServiceRestart);
connect(m_multiScreenWorker, &MultiScreenWorker::positionChanged, this, &WindowManager::onPositionChanged); connect(m_multiScreenWorker, &MultiScreenWorker::positionChanged, this, &WindowManager::onPositionChanged);
connect(m_multiScreenWorker, &MultiScreenWorker::displayModeChanged, this, &WindowManager::onDisplayModeChanged); connect(m_multiScreenWorker, &MultiScreenWorker::displayModeChanged, this, &WindowManager::onDisplayModeChanged);
connect(m_multiScreenWorker, &MultiScreenWorker::requestPlayAnimation, this, &WindowManager::onPlayAnimation); connect(m_multiScreenWorker, &MultiScreenWorker::requestPlayAnimation, this, &WindowManager::onPlayAnimation);
connect(m_multiScreenWorker, &MultiScreenWorker::requestChangeDockPosition, this, &WindowManager::onChangeDockPosition); connect(m_multiScreenWorker, &MultiScreenWorker::requestChangeDockPosition, this, &WindowManager::onChangeDockPosition);
connect(m_multiScreenWorker, &MultiScreenWorker::requestUpdateDockGeometry, this, &WindowManager::onUpdateDockGeometry);
connect(m_multiScreenWorker, &MultiScreenWorker::requestUpdateFrontendGeometry, this, &WindowManager::onRequestUpdateFrontendGeometry); connect(m_multiScreenWorker, &MultiScreenWorker::requestUpdateFrontendGeometry, this, &WindowManager::onRequestUpdateFrontendGeometry);
connect(m_multiScreenWorker, &MultiScreenWorker::requestNotifyWindowManager, this, &WindowManager::onRequestNotifyWindowManager); connect(m_multiScreenWorker, &MultiScreenWorker::requestNotifyWindowManager, this, &WindowManager::onRequestNotifyWindowManager);
connect(m_multiScreenWorker, &MultiScreenWorker::requestUpdateFrontendGeometry, DockItemManager::instance(), &DockItemManager::requestUpdateDockItem); connect(m_multiScreenWorker, &MultiScreenWorker::requestUpdateFrontendGeometry, DockItemManager::instance(), &DockItemManager::requestUpdateDockItem);
@ -557,12 +571,14 @@ void WindowManager::onPlayAnimation(const QString &screenName, const Dock::Posit
if (updatePos) if (updatePos)
onPositionChanged(m_multiScreenWorker->position()); onPositionChanged(m_multiScreenWorker->position());
m_multiScreenWorker->setStates(MultiScreenWorker::ShowAnimationStart, false); m_multiScreenWorker->setStates(MultiScreenWorker::ShowAnimationStart, false);
animationFinish(true);
break; break;
case Dock::AniAction::Hide: case Dock::AniAction::Hide:
hideAniFinish(); hideAniFinish();
if (updatePos) if (updatePos)
onPositionChanged(m_multiScreenWorker->position()); onPositionChanged(m_multiScreenWorker->position());
m_multiScreenWorker->setStates(MultiScreenWorker::HideAnimationStart, false); m_multiScreenWorker->setStates(MultiScreenWorker::HideAnimationStart, false);
animationFinish(false);
break; break;
} }
}); });
@ -642,6 +658,7 @@ void WindowManager::onChangeDockPosition(QString fromScreen, QString toScreen, c
// 结束之后需要根据确定需要再隐藏 // 结束之后需要根据确定需要再隐藏
showAniFinish(); showAniFinish();
m_multiScreenWorker->setStates(MultiScreenWorker::ChangePositionAnimationStart, false); m_multiScreenWorker->setStates(MultiScreenWorker::ChangePositionAnimationStart, false);
animationFinish(true);
}); });
for (QParallelAnimationGroup *ani : animations) { for (QParallelAnimationGroup *ani : animations) {
@ -805,3 +822,9 @@ void WindowManager::onRequestNotifyWindowManager()
static_cast<uint>(strutEnd)); // 设置任务栏终点坐标上下为x左右为y static_cast<uint>(strutEnd)); // 设置任务栏终点坐标上下为x左右为y
} }
} }
void WindowManager::onServiceRestart()
{
for (MainWindowBase *mainWindow : m_topWindows)
mainWindow->serviceRestart();
}

View File

@ -63,6 +63,7 @@ private:
QParallelAnimationGroup *createAnimationGroup(const Dock::AniAction &aniAction, const QString &screenName, const Dock::Position &position) const; QParallelAnimationGroup *createAnimationGroup(const Dock::AniAction &aniAction, const QString &screenName, const Dock::Position &position) const;
void showAniFinish(); void showAniFinish();
void animationFinish(bool showOrHide);
void hideAniFinish(); void hideAniFinish();
QRect getDockGeometry(bool withoutScale = false) const; // 计算左右侧加起来的区域大小 QRect getDockGeometry(bool withoutScale = false) const; // 计算左右侧加起来的区域大小
@ -81,6 +82,8 @@ private Q_SLOTS:
void onRequestUpdateFrontendGeometry(); void onRequestUpdateFrontendGeometry();
void onRequestNotifyWindowManager(); void onRequestNotifyWindowManager();
void onServiceRestart();
private: private:
MultiScreenWorker *m_multiScreenWorker; MultiScreenWorker *m_multiScreenWorker;
QString m_sniHostService; QString m_sniHostService;