fix: 修复托盘图标显示异常的问题

1、新增托盘图标后,自动调整顺序
2、托盘在调整位置之前先调整尺寸
3、删除多余的函数调用

Log: 修复托盘图标显示异常
Influence: 观察输入法是否正常显示,将托盘图标从托盘拖动到任务栏,观察该图标是否在展开托盘图标和输入法中间
Task: https://pms.uniontech.com/task-view-213361.html
Change-Id: I6c87ba89c6fb44a33c32f9252cc2b00b1e828e76
This commit is contained in:
donghualin 2022-11-09 11:03:59 +00:00
parent 719fea0c64
commit 7c2f2b38ea
11 changed files with 158 additions and 104 deletions

View File

@ -28,6 +28,7 @@
#include "quicksettingcontroller.h"
#include "pluginsitem.h"
#include "quicksettingcontainer.h"
#include "expandiconwidget.h"
#include <DGuiApplicationHelper>
@ -80,6 +81,9 @@ void DockTrayWindow::setDisplayMode(const Dock::DisplayMode &displayMode)
{
m_displayMode = displayMode;
moveToolPlugin();
// 如果当前模式为高效模式则设置当前的trayView为其计算位置的参照
if (displayMode == Dock::DisplayMode::Efficient)
ExpandIconWidget::popupTrayView()->setReferGridView(m_trayView);
}
QSize DockTrayWindow::suitableSize(const Dock::Position &position, const int &, const double &) const
@ -311,18 +315,19 @@ void DockTrayWindow::initConnection()
connect(m_quickIconWidget, &QuickPluginWindow::itemCountChanged, this, &DockTrayWindow::onResetLayout);
connect(m_quickIconWidget, &QuickPluginWindow::requestDrop, this, &DockTrayWindow::onDropIcon);
connect(m_systemPuginWidget, &SystemPluginWindow::requestDrop, this, &DockTrayWindow::onDropIcon);
connect(m_trayView, &TrayGridView::requestRemove, m_model, &TrayModel::removeRow);
connect(m_trayView, &TrayGridView::requestRemove, this, &DockTrayWindow::onResetLayout);
connect(m_model, &TrayModel::rowCountChanged, this, &DockTrayWindow::onResetLayout);
connect(m_model, &TrayModel::rowCountChanged, m_trayView, &TrayGridView::onUpdateEditorView);
connect(m_model, &TrayModel::requestRefreshEditor, m_trayView, &TrayGridView::onUpdateEditorView);
connect(m_trayView, &TrayGridView::dragLeaved, m_delegate, [ this ]{
Q_EMIT m_delegate->requestDrag(true);
});
connect(m_trayView, &TrayGridView::dragEntered, m_delegate, [ this ]{
connect(m_trayView, &TrayGridView::requestRemove, m_model, &TrayModel::removeRow);
connect(m_trayView, &TrayGridView::requestRemove, this, &DockTrayWindow::onResetLayout);
connect(m_trayView, &TrayGridView::dragFinished, this, [ this ] {
// 如果拖拽结束,则隐藏托盘
Q_EMIT m_delegate->requestDrag(false);
});
connect(m_trayView, &TrayGridView::dragLeaved, m_delegate, [ this ] {
Q_EMIT m_delegate->requestDrag(true);
});
connect(QuickSettingController::instance(), &QuickSettingController::pluginInserted, this, [ this ] (PluginsItemInterface *itemInter, const QuickSettingController::PluginAttribute pluginAttr) {
switch (pluginAttr) {
case QuickSettingController::PluginAttribute::Tool:

View File

@ -205,9 +205,6 @@ void MainPanelControl::initConnection()
*/
void MainPanelControl::setDisplayMode(DisplayMode dislayMode)
{
if (dislayMode == m_displayMode)
return;
m_displayMode = dislayMode;
m_recentHelper->setDisplayMode(dislayMode);
m_tray->setDisplayMode(dislayMode);

View File

@ -125,19 +125,23 @@ void TrayDelegate::onUpdateExpand(bool on)
ExpandIconWidget *expandwidget = expandWidget();
if (on) {
if (!expandwidget) {
if (expandwidget) {
expandwidget->setTrayPanelVisible(true);
} else {
// 如果三角按钮不存在,那么就设置三角按钮可见,此时它会自动创建一个三角按钮
TrayModel *model = qobject_cast<TrayModel *>(m_listView->model());
if (model)
model->setExpandVisible(true, true);
} else {
expandwidget->setTrayPanelVisible(true);
}
} else if (expandwidget) {
// 如果释放鼠标,则判断当前鼠标的位置是否在托盘内部,如果在,则无需隐藏
QPoint currentPoint = QCursor::pos();
TrayGridWidget *view = ExpandIconWidget::popupTrayView();
expandwidget->setTrayPanelVisible(view->geometry().contains(currentPoint));
} else {
if (expandwidget) {
// 如果释放鼠标,则判断当前鼠标的位置是否在托盘内部,如果在,则无需隐藏
QPoint currentPoint = QCursor::pos();
TrayGridWidget *view = ExpandIconWidget::popupTrayView();
expandwidget->setTrayPanelVisible(view->geometry().contains(currentPoint));
} else {
ExpandIconWidget::popupTrayView()->hide();
}
}
}

View File

@ -467,8 +467,6 @@ bool TrayGridView::beginDrag(Qt::DropActions supportedActions)
pixLabel->setPixmap(pixmap);
pixLabel->setFixedSize(indexRect(modelIndex).size() / ratio);
QRect rectIcon(pixLabel->rect().topLeft(), pixLabel->size());
QDrag *drag = new QDrag(this);
pixmap.scaled(pixmap.size() * ratio, Qt::KeepAspectRatio, Qt::SmoothTransformation);
pixmap.setDevicePixelRatio(ratio);
@ -486,6 +484,8 @@ bool TrayGridView::beginDrag(Qt::DropActions supportedActions)
listModel->setDragKey(itemKey);
listModel->setDragingIndex(modelIndex);
// 删除当前的图标
WinInfo winInfo = listModel->takeIndex(modelIndex);
Qt::DropAction dropAct = drag->exec(supportedActions);
@ -493,18 +493,20 @@ bool TrayGridView::beginDrag(Qt::DropActions supportedActions)
m_aniStartTime->stop();
m_pressed = false;
Q_EMIT dragEntered();
if (dropAct == Qt::IgnoreAction) {
QPropertyAnimation *posAni = new QPropertyAnimation(pixLabel, "pos", pixLabel);
connect(posAni, &QPropertyAnimation::finished, [ &, listModel, pixLabel ] () {
connect(posAni, &QPropertyAnimation::finished, [ this, listModel, pixLabel, modelIndex, winInfo ] () {
pixLabel->hide();
pixLabel->deleteLater();
listModel->setDragKey(QString());
listModel->insertRow(modelIndex.row(), winInfo);
clearDragModelIndex();
listModel->setExpandVisible(!TrayModel::getIconModel()->isEmpty());
m_dropPos = QPoint();
m_dragPos = QPoint();
Q_EMIT dragFinished();
});
posAni->setEasingCurve(QEasingCurve::Linear);
posAni->setDuration(m_aniDuringTime);
@ -518,8 +520,6 @@ bool TrayGridView::beginDrag(Qt::DropActions supportedActions)
m_dropPos = QPoint();
m_dragPos = QPoint();
Q_EMIT requestRemove(itemKey);
}
return true;

View File

@ -54,6 +54,7 @@ Q_SIGNALS:
void requestRemove(const QString &);
void dragLeaved();
void dragEntered();
void dragFinished();
private Q_SLOTS:
void clearDragModelIndex();

View File

@ -340,6 +340,22 @@ void TrayModel::clear()
Q_EMIT rowCountChanged();
}
WinInfo TrayModel::takeIndex(const QModelIndex &index)
{
int row = index.row();
if (row < 0 || row >= m_winInfos.size())
return WinInfo();
WinInfo win = m_winInfos[row];
beginResetModel();
m_winInfos.removeAt(row);
endResetModel();
Q_EMIT rowCountChanged();
return win;
}
void TrayModel::onXEmbedTrayAdded(quint32 winId)
{
if (!xembedCanExport(winId))
@ -357,6 +373,7 @@ void TrayModel::onXEmbedTrayAdded(quint32 winId)
info.itemKey = xembedItemKey(winId);
info.winId = winId;
m_winInfos.append(info);
sortItems();
endInsertRows();
Q_EMIT rowCountChanged();
@ -471,6 +488,48 @@ bool TrayModel::systemItemCanExport(const QString &pluginName) const
return inTrayConfig(systemItemKey(pluginName));
}
void TrayModel::sortItems()
{
// 如果当前是展开托盘的内容,则无需排序
if (m_isTrayIcon)
return;
// 数据排列,展开按钮始终排在最前面,输入法始终排在最后面
WinInfos expandWin;
WinInfos inputMethodWin;
// 从列表中获取输入法和展开按钮
for (const WinInfo &winInfo : m_winInfos) {
switch (winInfo.type) {
case TrayIconType::ExpandIcon: {
expandWin << winInfo;
break;
}
case TrayIconType::Sni: {
if (winInfo.isTypeWriting)
inputMethodWin << winInfo;
break;
}
default:
break;
}
}
// 从列表中移除展开按钮
for (const WinInfo &winInfo : expandWin)
m_winInfos.removeOne(winInfo);
// 从列表中移除输入法
for (const WinInfo &winInfo : inputMethodWin)
m_winInfos.removeOne(winInfo);
// 将展开按钮添加到列表的最前面
for (int i = expandWin.size() - 1; i >= 0; i--)
m_winInfos.push_front(expandWin[i]);
// 将输入法添加到列表的最后面
for (int i = 0; i < inputMethodWin.size(); i++)
m_winInfos.push_back(inputMethodWin[i]);
}
void TrayModel::onSniTrayAdded(const QString &servicePath)
{
if (!sniCanExport(servicePath))
@ -478,16 +537,6 @@ void TrayModel::onSniTrayAdded(const QString &servicePath)
bool typeWriting = isTypeWriting(servicePath);
int citxIndex = -1;
for (int i = 0; i < m_winInfos.size(); i++) {
WinInfo info = m_winInfos[i];
if (info.servicePath == servicePath)
return;
if (typeWriting && info.isTypeWriting)
citxIndex = i;
}
beginInsertRows(QModelIndex(), rowCount(), rowCount());
WinInfo info;
info.type = Sni;
@ -495,23 +544,12 @@ void TrayModel::onSniTrayAdded(const QString &servicePath)
info.itemKey = sniItemKey(servicePath);
info.servicePath = servicePath;
info.isTypeWriting = typeWriting; // 是否为输入法
if (typeWriting) {
if (citxIndex < 0) {
m_winInfos.append(info);
} else {
// 如果输入法在指定位置,则将输入法移动到指定位置
m_winInfos[citxIndex] = info;
QTimer::singleShot(150, this, [ = ] {
// 对比需要变化的图标
emit requestUpdateWidget({ citxIndex });
});
}
} else {
m_winInfos.append(info);
m_winInfos.append(info);
Q_EMIT rowCountChanged();
}
sortItems();
endInsertRows();
Q_EMIT rowCountChanged();
}
void TrayModel::onSniTrayRemoved(const QString &servicePath)
@ -584,6 +622,8 @@ void TrayModel::onIndicatorAdded(const QString &indicatorName)
info.key = itemKey;
info.itemKey = IndicatorTrayItem::toIndicatorKey(indicatorName);
m_winInfos.append(info);
sortItems();
endInsertRows();
Q_EMIT rowCountChanged();
@ -613,6 +653,7 @@ void TrayModel::onSystemTrayAdded(PluginsItemInterface *itemInter)
info.itemKey = systemItemKey(itemInter->pluginName());
m_winInfos.append(info);
sortItems();
endInsertRows();
Q_EMIT rowCountChanged();
@ -699,6 +740,7 @@ void TrayModel::addRow(WinInfo info)
beginInsertRows(QModelIndex(), rowCount(), rowCount());
m_winInfos.append(info);
sortItems();
endInsertRows();
Q_EMIT requestRefreshEditor();
@ -718,6 +760,8 @@ void TrayModel::insertRow(int index, WinInfo info)
}
beginInsertRows(QModelIndex(), index, index);
m_winInfos.insert(index, info);
sortItems();
endInsertRows();
Q_EMIT requestRefreshEditor();

View File

@ -110,11 +110,11 @@ public:
bool isEmpty() const;
void clear();
WinInfo takeIndex(const QModelIndex &index);
void saveConfig(int index, const WinInfo &winInfo);
Q_SIGNALS:
void requestUpdateIcon(quint32);
void requestUpdateWidget(const QList<int> &);
void requestOpenEditor(const QModelIndex &index, bool isOpen = true) const;
void rowCountChanged();
void requestRefreshEditor();
@ -142,6 +142,14 @@ private Q_SLOTS:
void onSettingChanged(const QString &key, const QVariant &value);
protected:
QMimeData *mimeData(const QModelIndexList &indexes) const Q_DECL_OVERRIDE;
QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
bool removeRows(int row, int count, const QModelIndex &parent) Q_DECL_OVERRIDE;
bool canDropMimeData(const QMimeData *data, Qt::DropAction action,
int row, int column, const QModelIndex &parent) const Q_DECL_OVERRIDE;
Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;
private:
bool exist(const QString &itemKey);
QString fileNameByServiceName(const QString &serviceName) const;
@ -155,14 +163,7 @@ private:
bool indicatorCanExport(const QString &indicatorName) const;
QString systemItemKey(const QString &pluginName) const;
bool systemItemCanExport(const QString &pluginName) const;
protected:
QMimeData *mimeData(const QModelIndexList &indexes) const Q_DECL_OVERRIDE;
QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
bool removeRows(int row, int count, const QModelIndex &parent) Q_DECL_OVERRIDE;
bool canDropMimeData(const QMimeData *data, Qt::DropAction action,
int row, int column, const QModelIndex &parent) const Q_DECL_OVERRIDE;
Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;
void sortItems();
private:
WinInfos m_winInfos;

View File

@ -66,9 +66,6 @@ ExpandIconWidget::ExpandIconWidget(QWidget *parent, Qt::WindowFlags f)
ExpandIconWidget::~ExpandIconWidget()
{
TrayGridWidget *gridView = popupTrayView();
gridView->setOwnerWidget(nullptr);
setTrayPanelVisible(false);
}
void ExpandIconWidget::setPositon(Dock::Position position)
@ -84,10 +81,6 @@ void ExpandIconWidget::sendClick(uint8_t mouseButton, int x, int y)
Q_UNUSED(x);
Q_UNUSED(y);
// 如果当前图标不可见,则不让展开托盘列表
if (popupTrayView()->trayView()->model()->rowCount() == 0)
return;
if (mouseButton != XCB_BUTTON_INDEX_1)
return;
@ -115,10 +108,6 @@ QPixmap ExpandIconWidget::icon()
void ExpandIconWidget::paintEvent(QPaintEvent *event)
{
TrayGridWidget *gridView = popupTrayView();
if (gridView->trayView()->model()->rowCount() == 0)
return BaseTrayWidget::paintEvent(event);
QPainter painter(this);
QPixmap pixmap = ImageUtil::loadSvg(dropIconFile(), QSize(ICON_SIZE, ICON_SIZE));
QRect rectOfPixmap(rect().x() + (rect().width() - ICON_SIZE) / 2,
@ -126,8 +115,6 @@ void ExpandIconWidget::paintEvent(QPaintEvent *event)
ICON_SIZE, ICON_SIZE);
painter.drawPixmap(rectOfPixmap, pixmap);
gridView->setOwnerWidget(this);
}
const QString ExpandIconWidget::dropIconFile() const
@ -183,14 +170,17 @@ TrayGridWidget *ExpandIconWidget::popupTrayView()
layout->addWidget(trayView);
auto rowCountChanged = [ = ] {
int count = trayModel->rowCount();
if (count > 0)
gridParentView->resetPosition();
else if (gridParentView->isVisible())
gridParentView->hide();
if (gridParentView->isVisible()) {
int count = trayModel->rowCount();
if (count > 0)
gridParentView->resetPosition();
else
gridParentView->hide();
}
};
connect(trayModel, &TrayModel::rowCountChanged, gridParentView, rowCountChanged);
connect(trayModel, &TrayModel::requestRefreshEditor, trayView, &TrayGridView::onUpdateEditorView);
connect(trayDelegate, &TrayDelegate::removeRow, trayView, [ = ](const QModelIndex &index) {
trayView->model()->removeRow(index.row(),index.parent());
@ -216,7 +206,7 @@ TrayGridWidget::TrayGridWidget(QWidget *parent)
: QWidget (parent)
, m_dockInter(new DockInter(dockServiceName(), dockServicePath(), QDBusConnection::sessionBus(), this))
, m_trayGridView(nullptr)
, m_ownerWidget(nullptr)
, m_referGridView(nullptr)
{
setAttribute(Qt::WA_TranslucentBackground);
}
@ -231,10 +221,9 @@ void TrayGridWidget::setTrayGridView(TrayGridView *trayView)
m_trayGridView = trayView;
}
void TrayGridWidget::setOwnerWidget(QWidget *widget)
void TrayGridWidget::setReferGridView(TrayGridView *trayView)
{
// 设置所属的Widget目的是为了计算当前窗体的具体位置
m_ownerWidget = widget;
m_referGridView = trayView;
}
TrayGridView *TrayGridWidget::trayView() const
@ -245,20 +234,22 @@ TrayGridView *TrayGridWidget::trayView() const
void TrayGridWidget::resetPosition()
{
// 如果没有设置所属窗体,则无法计算位置
if (!m_ownerWidget || !m_ownerWidget->parentWidget())
ExpandIconWidget *expWidget = expandWidget();
if (!expWidget)
return;
QWidget *topWidget = m_ownerWidget->topLevelWidget();
QPoint ptPos = m_ownerWidget->parentWidget()->mapToGlobal(m_ownerWidget->pos());
m_trayGridView->setFixedSize(m_trayGridView->suitableSize());
setFixedSize(m_trayGridView->size() + QSize(ITEM_SPACING * 2, ITEM_SPACING * 2));
QWidget *topWidget = expWidget->topLevelWidget();
QPoint ptPos = expWidget->mapToGlobal(QPoint(0, 0));
switch (m_position) {
case Dock::Position::Bottom: {
ptPos.setX(ptPos.x() - width());
ptPos.setY(topWidget->y() - height());
break;
}
case Dock::Position::Top: {
ptPos.setY(topWidget->y() + topWidget->height());
ptPos.setX(ptPos.x() - width());
break;
}
case Dock::Position::Left: {
@ -270,8 +261,6 @@ void TrayGridWidget::resetPosition()
break;
}
}
m_trayGridView->setFixedSize(m_trayGridView->suitableSize());
setFixedSize(m_trayGridView->size() + QSize(ITEM_SPACING * 2, ITEM_SPACING * 2));
move(ptPos);
}
@ -296,3 +285,22 @@ QColor TrayGridWidget::maskColor() const
color.setAlpha(maskAlpha);
return color;
}
ExpandIconWidget *TrayGridWidget::expandWidget() const
{
if (!m_referGridView)
return nullptr;
QAbstractItemModel *dataModel = m_referGridView->model();
if (!dataModel)
return nullptr;
for (int i = 0; i < dataModel->rowCount() - 1; i++) {
QModelIndex index = dataModel->index(i, 0);
ExpandIconWidget *widget = qobject_cast<ExpandIconWidget *>(m_referGridView->indexWidget(index));
if (widget)
return widget;
}
return nullptr;
}

View File

@ -67,7 +67,7 @@ public:
static void setPosition(const Dock::Position &position);
void setTrayGridView(TrayGridView *trayView);
void setOwnerWidget(QWidget *widget);
void setReferGridView(TrayGridView *trayView);
TrayGridView *trayView() const;
void resetPosition();
@ -76,12 +76,13 @@ protected:
private:
QColor maskColor() const;
ExpandIconWidget *expandWidget() const;
private:
DockInter *m_dockInter;
TrayGridView *m_trayGridView;
TrayGridView *m_referGridView;
static Dock::Position m_position;
QWidget *m_ownerWidget;
};
#endif // EXPANDICONWIDGET_H

View File

@ -27,6 +27,7 @@
#include "quicksettingcontainer.h"
#include "systempluginwindow.h"
#include "datetimedisplayer.h"
#include "expandiconwidget.h"
#include <DGuiApplicationHelper>
#include <DRegionMonitor>
@ -141,6 +142,9 @@ void TrayManagerWindow::setDisplayMode(Dock::DisplayMode displayMode)
m_displayMode = displayMode;
// 从时尚模式切换到高效模式的时候,需要重新布局
onTrayCountChanged();
// 如果当前模式为高效模式则设置当前的trayView为其计算位置的参照
if (displayMode == Dock::DisplayMode::Fashion)
ExpandIconWidget::popupTrayView()->setReferGridView(m_trayView);
}
int TrayManagerWindow::appDatetimeSize(const Dock::Position &position) const
@ -223,18 +227,6 @@ void TrayManagerWindow::onTrayCountChanged()
Q_EMIT requestUpdate();
}
void TrayManagerWindow::onRequestUpdateWidget(const QList<int> &idxs)
{
for (int i = 0; i < idxs.size(); i++) {
int idx = idxs[i];
if (idx < m_model->rowCount()) {
QModelIndex index = m_model->index(idx);
m_trayView->closePersistentEditor(index);
m_trayView->openPersistentEditor(index);
}
}
}
void TrayManagerWindow::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event);
@ -303,10 +295,12 @@ void TrayManagerWindow::initConnection()
connect(m_trayView, &TrayGridView::dragLeaved, m_delegate, [ this ]{
Q_EMIT m_delegate->requestDrag(true);
});
connect(m_trayView, &TrayGridView::dragEntered, m_delegate, [ this ]{
connect(m_trayView, &TrayGridView::dragFinished, this, [ this ] {
// 如果拖拽结束,则隐藏托盘
Q_EMIT m_delegate->requestDrag(false);
});
connect(m_model, &TrayModel::requestUpdateWidget, this, &TrayManagerWindow::onRequestUpdateWidget);
connect(m_model, &TrayModel::rowCountChanged, m_trayView, &TrayGridView::onUpdateEditorView);
connect(m_dateTimeWidget, &DateTimeDisplayer::requestUpdate, this, &TrayManagerWindow::requestUpdate);
m_trayView->installEventFilter(this);

View File

@ -86,7 +86,6 @@ private:
private Q_SLOTS:
void onTrayCountChanged();
void onRequestUpdateWidget(const QList<int> &idxs);
private:
QWidget *m_appPluginDatetimeWidget;