fix(system-tray): crash when refresh wired tray visible

Change-Id: I9cbcd484e90342b90feaa873a69a57aa55a1c9bc
This commit is contained in:
listenerri 2018-10-31 15:46:22 +08:00
parent 22119b989a
commit 5c042701e1
Notes: gerrit 2018-11-01 16:28:02 +08:00
Verified+1: <jenkins@deepin.com>
Verified+1: zhaofangfangdeepin <zhaofangfang@linuxdeepin.com>
Code-Review+2: listenerri <listenerri@gmail.com>
Submitted-by: listenerri <listenerri@gmail.com>
Submitted-at: Thu, 01 Nov 2018 16:28:01 +0800
Reviewed-on: https://cr.deepin.io/39345
Project: dde/dde-dock
Branch: refs/heads/master
6 changed files with 41 additions and 21 deletions

View File

@ -85,8 +85,11 @@ void DockPluginsController::itemRemoved(PluginsItemInterface * const itemInter,
m_pluginList[itemInter].remove(itemKey);
// QTimer::singleShot(1, this, [=] { delete item; });
item->deleteLater();
// do not delete the itemWidget object(specified in the plugin interface)
item->centralWidget()->setParent(nullptr);
// just delete our wrapper object(PluginsItem)
item->deleteLater();
}
//void DockPluginsController::requestRefershWindowVisible()

View File

@ -115,7 +115,7 @@ void PluginsItem::refershIcon()
m_pluginInter->refershIcon(m_itemKey);
}
QWidget *PluginsItem::centralWidget()
QWidget *PluginsItem::centralWidget() const
{
return m_centralWidget;
}

View File

@ -49,11 +49,12 @@ public:
inline ItemType itemType() const override {return Plugins;}
QSize sizeHint() const override;
QWidget *centralWidget() const;
public slots:
void refershIcon() override;
protected:
QWidget *centralWidget();
bool eventFilter(QObject *o, QEvent *e) override;
private:

View File

@ -32,11 +32,11 @@
FashionTrayItem::FashionTrayItem(Dock::Position pos, QWidget *parent)
: QWidget(parent),
m_mainBoxLayout(new QBoxLayout(QBoxLayout::Direction::LeftToRight, this)),
m_trayBoxLayout(new QBoxLayout(QBoxLayout::Direction::LeftToRight, this)),
m_leftSpliter(new QLabel(this)),
m_rightSpliter(new QLabel(this)),
m_controlWidget(new FashionTrayControlWidget(pos, this)),
m_mainBoxLayout(new QBoxLayout(QBoxLayout::Direction::LeftToRight)),
m_trayBoxLayout(new QBoxLayout(QBoxLayout::Direction::LeftToRight)),
m_leftSpliter(new QLabel),
m_rightSpliter(new QLabel),
m_controlWidget(new FashionTrayControlWidget(pos)),
m_currentAttentionTray(nullptr),
m_dockPosistion(pos)
{
@ -74,6 +74,8 @@ FashionTrayItem::FashionTrayItem(Dock::Position pos, QWidget *parent)
void FashionTrayItem::setTrayWidgets(const QList<AbstractTrayWidget *> &trayWidgetList)
{
clearTrayWidgets();
for (auto widget : trayWidgetList) {
trayWidgetAdded(widget);
}
@ -112,8 +114,9 @@ void FashionTrayItem::trayWidgetRemoved(AbstractTrayWidget *trayWidget)
auto it = m_trayWidgetWrapperMap.constBegin();
for (; it != m_trayWidgetWrapperMap.constEnd(); ++it) {
// found the removed tray
if (it.key() == trayWidget) {
// removing the attention tray
// the removed tray is a attention tray
if (m_currentAttentionTray == it.value()) {
if (m_controlWidget->expanded()) {
m_trayBoxLayout->removeWidget(m_currentAttentionTray);
@ -124,6 +127,9 @@ void FashionTrayItem::trayWidgetRemoved(AbstractTrayWidget *trayWidget)
} else {
m_trayBoxLayout->removeWidget(it.value());
}
// do not delete real tray object, just delete it's wrapper object
// the real tray object should be deleted in SystemTrayPlugin
trayWidget->setParent(nullptr);
it.value()->deleteLater();
m_trayWidgetWrapperMap.remove(it.key());
break;
@ -131,7 +137,8 @@ void FashionTrayItem::trayWidgetRemoved(AbstractTrayWidget *trayWidget)
}
if (it == m_trayWidgetWrapperMap.constEnd()) {
qDebug() << "can not find the tray widget in fashion tray list:" << trayWidget;
qDebug() << "can not find the tray widget in fashion tray list";
Q_UNREACHABLE();
return;
}
@ -140,14 +147,10 @@ void FashionTrayItem::trayWidgetRemoved(AbstractTrayWidget *trayWidget)
void FashionTrayItem::clearTrayWidgets()
{
if (m_currentAttentionTray) {
m_mainBoxLayout->removeWidget(m_currentAttentionTray);
m_currentAttentionTray = nullptr;
}
QMap<AbstractTrayWidget *, FashionTrayWidgetWrapper *> mMap = m_trayWidgetWrapperMap;
for (auto wrapper : m_trayWidgetWrapperMap.values()) {
m_trayBoxLayout->removeWidget(wrapper);
wrapper->deleteLater();
for (auto it = mMap.begin(); it != mMap.end(); ++it) {
trayWidgetRemoved(it.key());
}
m_trayWidgetWrapperMap.clear();

View File

@ -31,6 +31,8 @@ FashionTrayWidgetWrapper::FashionTrayWidgetWrapper(AbstractTrayWidget *absTrayWi
m_attention(false)
{
m_absTrayWidget->setVisible(true);
m_layout->setSpacing(0);
m_layout->setMargin(0);
m_layout->setContentsMargins(0, 0, 0, 0);

View File

@ -320,9 +320,20 @@ void SystemTrayPlugin::trayRemoved(const QString &itemKey)
}
AbstractTrayWidget *widget = m_trayMap.take(itemKey);
m_fashionItem->trayWidgetRemoved(widget);
m_proxyInter->itemRemoved(this, itemKey);
widget->deleteLater();
if (displayMode() == Dock::Efficient) {
m_proxyInter->itemRemoved(this, itemKey);
} else {
m_fashionItem->trayWidgetRemoved(widget);
}
// only delete tray object when it is a tray of applications
// set the parent of the tray object to avoid be deconstructed by parent(DockItem/PluginsItem/SystemTrayPluginsItem)
if (widget->trayTyep() == AbstractTrayWidget::TrayType::SystemTray) {
widget->setParent(nullptr);
} else {
widget->deleteLater();
}
if (m_trayApplet->isVisible()) {
updateTipsContent();