dde-dock/frame/window/mainwindow.cpp
donghualin 477bc09965 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
2022-12-14 01:33:00 +00:00

190 lines
6.2 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: sbw <sbw@sbw.so>
*
* Maintainer: sbw <sbw@sbw.so>
* zhaolong <zhaolong@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mainwindow.h"
#include "mainpanelcontrol.h"
#include "dockitemmanager.h"
#include "menuworker.h"
#include "proxyplugincontroller.h"
#include "windowmanager.h"
#include "dockscreen.h"
#include "dragwidget.h"
#include "multiscreenworker.h"
#include "constants.h"
#include "displaymanager.h"
#include <DStyle>
#include <DPlatformWindowHandle>
#include <DSysInfo>
#include <DPlatformTheme>
#include <DDBusSender>
#include <QDebug>
#include <QEvent>
#include <QResizeEvent>
#include <QScreen>
#include <QGuiApplication>
#include <QX11Info>
#include <QtConcurrent>
#include <qpa/qplatformwindow.h>
#include <qpa/qplatformscreen.h>
#include <qpa/qplatformnativeinterface.h>
#include <QMenu>
#include <X11/X.h>
#include <X11/Xutil.h>
#define DOCK_SCREEN DockScreen::instance()
#define DIS_INS DisplayManager::instance()
MainWindow::MainWindow(MultiScreenWorker *multiScreenWorker, QWidget *parent)
: MainWindowBase(multiScreenWorker, parent)
, m_mainPanel(new MainPanelControl(multiScreenWorker->dockInter(), this))
, m_multiScreenWorker(multiScreenWorker)
, m_needUpdateUi(false)
{
m_mainPanel->setDisplayMode(m_multiScreenWorker->displayMode());
initConnections();
for (auto item : DockItemManager::instance()->itemList())
m_mainPanel->insertItem(-1, item);
}
void MainWindow::resizeEvent(QResizeEvent *event)
{
MainWindowBase::resizeEvent(event);
m_mainPanel->updatePluginsLayout();
}
void MainWindow::initConnections()
{
connect(DockItemManager::instance(), &DockItemManager::itemInserted, m_mainPanel, &MainPanelControl::insertItem, Qt::DirectConnection);
connect(DockItemManager::instance(), &DockItemManager::itemRemoved, m_mainPanel, &MainPanelControl::removeItem, Qt::DirectConnection);
connect(DockItemManager::instance(), &DockItemManager::itemUpdated, m_mainPanel, &MainPanelControl::itemUpdated, Qt::DirectConnection);
connect(DockItemManager::instance(), &DockItemManager::trayVisableCountChanged, this, &MainWindow::resizeDockIcon, Qt::QueuedConnection);
connect(m_mainPanel, &MainPanelControl::itemMoved, DockItemManager::instance(), &DockItemManager::itemMoved, Qt::DirectConnection);
connect(m_mainPanel, &MainPanelControl::itemAdded, DockItemManager::instance(), &DockItemManager::itemAdded, Qt::DirectConnection);
connect(m_mainPanel, &MainPanelControl::requestUpdate, this, &MainWindow::requestUpdate);
}
/**
* @brief MainWindow::getTrayVisableItemCount
* 重新获取以下当前托盘区域有多少个可见的图标,并更新图标的大小
*/
void MainWindow::resizeDockIcon()
{
m_mainPanel->resizeDockIcon();
}
/**
* @brief MainWindow::setGeometry
* @param rect 设置任务栏的位置和大小重写此函数时为了及时发出panelGeometryChanged信号最终供外部DBus调用方使用
*/
void MainWindow::setGeometry(const QRect &rect)
{
if (rect == this->geometry())
return;
DBlurEffectWidget::setGeometry(rect);
}
MainWindowBase::DockWindowType MainWindow::windowType() const
{
return DockWindowType::MainWindow;
}
void MainWindow::setPosition(const Position &position)
{
MainWindowBase::setPosition(position);
m_mainPanel->setPositonValue(position);
// 更新鼠标拖拽样式在类内部设置到qApp单例上去
if ((Top == position) || (Bottom == position))
m_mainPanel->setCursor(Qt::SizeVerCursor);
else
m_mainPanel->setCursor(Qt::SizeHorCursor);
}
void MainWindow::setDisplayMode(const Dock::DisplayMode &displayMode)
{
m_mainPanel->setDisplayMode(displayMode);
MainWindowBase::setDisplayMode(displayMode);
}
void MainWindow::updateParentGeometry(const Position &pos, const QRect &rect)
{
setFixedSize(rect.size());
setGeometry(rect);
int panelSize = windowSize();
QRect panelRect = rect;
switch (pos) {
case Position::Top:
m_mainPanel->move(0, rect.height() - panelSize);
panelRect.setHeight(panelSize);
break;
case Position::Left:
m_mainPanel->move(width() - panelSize, 0);
panelRect.setWidth(panelSize);
break;
case Position::Bottom:
m_mainPanel->move(0, 0);
panelRect.setHeight(panelSize);
break;
case Position::Right:
m_mainPanel->move(0, 0);
panelRect.setWidth(panelSize);
break;
}
m_mainPanel->setFixedSize(panelRect.size());
}
QSize MainWindow::suitableSize(const Position &pos, const int &screenSize, const double &deviceRatio) const
{
return m_mainPanel->suitableSize(pos, screenSize, deviceRatio);
}
void MainWindow::resetPanelGeometry()
{
m_mainPanel->setFixedSize(size());
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;
}
}