From 46f01047a21fdf856c9bc6dbe6457bd29732c21c Mon Sep 17 00:00:00 2001 From: donghualin Date: Fri, 13 Jan 2023 15:40:20 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=B1=95=E5=BC=80?= =?UTF-8?q?=E6=89=98=E7=9B=98=E6=97=A0=E6=B3=95=E9=80=9A=E8=BF=87=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E7=A7=BB=E9=99=A4U=E7=9B=98=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原因:在鼠标点击托盘内右键菜单的时候,会隐藏托盘,导致菜单跟着隐藏,结果是菜单的相关功能不生效 解决方案:在点击托盘区域的时候,判断鼠标位置是否在托盘区域内,包括菜单区域,如果在托盘区域内,则不关闭托盘,等菜单点击完成后再关闭 Log: 修复托盘U盘图标右键不生效的问题 Influence: 插入U盘,打开托盘区,右键菜单,点击,观察功能是否生效 Bug: https://pms.uniontech.com/bug-view-182299.html Change-Id: I7ba5cc65e2509d4a9dab6e21d73906e8894df0b8 --- frame/window/tray/tray_delegate.cpp | 4 ++- frame/window/tray/tray_delegate.h | 1 + frame/window/tray/tray_gridview.h | 1 + .../window/tray/widgets/expandiconwidget.cpp | 13 ++++++++++ .../window/tray/widgets/systempluginitem.cpp | 26 +++++++++++++++++-- frame/window/tray/widgets/systempluginitem.h | 2 ++ .../pluginmanager/dockplugincontroller.cpp | 7 +++-- 7 files changed, 49 insertions(+), 5 deletions(-) diff --git a/frame/window/tray/tray_delegate.cpp b/frame/window/tray/tray_delegate.cpp index b81921bb3..c2bef3d1f 100644 --- a/frame/window/tray/tray_delegate.cpp +++ b/frame/window/tray/tray_delegate.cpp @@ -112,7 +112,9 @@ QWidget *TrayDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem PluginsItemInterface *pluginInter = (PluginsItemInterface *)(index.data(TrayModel::PluginInterfaceRole).toULongLong()); if (pluginInter) { const QString itemKey = QuickSettingController::instance()->itemKey(pluginInter); - trayWidget = new SystemPluginItem(pluginInter, itemKey, parent); + SystemPluginItem *trayItem = new SystemPluginItem(pluginInter, itemKey, parent); + connect(trayItem, &SystemPluginItem::execActionFinished, this, &TrayDelegate::requestHide); + trayWidget = trayItem; } } diff --git a/frame/window/tray/tray_delegate.h b/frame/window/tray/tray_delegate.h index 28d2dccf2..e501a4b01 100644 --- a/frame/window/tray/tray_delegate.h +++ b/frame/window/tray/tray_delegate.h @@ -45,6 +45,7 @@ public: Q_SIGNALS: void removeRow(const QModelIndex &) const; void requestDrag(bool) const; + void requestHide(); private Q_SLOTS: void onUpdateExpand(bool on); diff --git a/frame/window/tray/tray_gridview.h b/frame/window/tray/tray_gridview.h index 60dc54762..98a43c926 100644 --- a/frame/window/tray/tray_gridview.h +++ b/frame/window/tray/tray_gridview.h @@ -54,6 +54,7 @@ Q_SIGNALS: void dragLeaved(); void dragEntered(); void dragFinished(); + void requestHide(); private Q_SLOTS: void clearDragModelIndex(); diff --git a/frame/window/tray/widgets/expandiconwidget.cpp b/frame/window/tray/widgets/expandiconwidget.cpp index d6f4b1d36..cf50ed024 100644 --- a/frame/window/tray/widgets/expandiconwidget.cpp +++ b/frame/window/tray/widgets/expandiconwidget.cpp @@ -24,6 +24,7 @@ #include "tray_delegate.h" #include "dockpopupwindow.h" #include "imageutil.h" +#include "systempluginitem.h" #include #include @@ -170,6 +171,7 @@ TrayGridWidget *ExpandIconWidget::popupTrayView() connect(trayModel, &TrayModel::rowCountChanged, gridParentView, rowCountChanged); connect(trayModel, &TrayModel::requestRefreshEditor, trayView, &TrayGridView::onUpdateEditorView); + connect(trayDelegate, &TrayDelegate::requestHide, trayView, &TrayGridView::requestHide); connect(trayDelegate, &TrayDelegate::removeRow, trayView, [ = ](const QModelIndex &index) { trayView->model()->removeRow(index.row(),index.parent()); }); @@ -208,6 +210,7 @@ void TrayGridWidget::setPosition(const Dock::Position &position) void TrayGridWidget::setTrayGridView(TrayGridView *trayView) { m_trayGridView = trayView; + connect(m_trayGridView, &TrayGridView::requestHide, this, &TrayGridWidget::hide); } void TrayGridWidget::setReferGridView(TrayGridView *trayView) @@ -315,6 +318,16 @@ void TrayGridWidget::initMember() if (rctView.contains(mousePos)) return; + // 查看是否存在SystemPluginItem插件,在此处判断的原因是因为当弹出右键菜单的时候,如果鼠标在菜单上点击 + // 刚好把托盘区域给隐藏了,导致菜单也跟着隐藏,导致点击菜单的时候不生效 + QAbstractItemModel *dataModel = m_trayGridView->model(); + for (int i = 0; i < dataModel->rowCount(); i++) { + QModelIndex index = dataModel->index(i, 0); + SystemPluginItem *widget = qobject_cast(m_trayGridView->indexWidget(index)); + if (widget && widget->containsPoint(mousePos)) + return; + } + hide(); }); } diff --git a/frame/window/tray/widgets/systempluginitem.cpp b/frame/window/tray/widgets/systempluginitem.cpp index 1fc92e3ff..9a77ffc77 100644 --- a/frame/window/tray/widgets/systempluginitem.cpp +++ b/frame/window/tray/widgets/systempluginitem.cpp @@ -37,7 +37,7 @@ SystemPluginItem::SystemPluginItem(PluginsItemInterface *const pluginInter, cons : BaseTrayWidget(parent) , m_popupShown(false) , m_tapAndHold(false) - , m_contextMenu(new QMenu(this)) + , m_contextMenu(new QMenu) , m_pluginInter(pluginInter) , m_centralWidget(m_pluginInter->itemWidget(itemKey)) , m_popupTipsDelayTimer(new QTimer(this)) @@ -81,6 +81,11 @@ SystemPluginItem::SystemPluginItem(PluginsItemInterface *const pluginInter, cons connect(qApp, &QApplication::aboutToQuit, PopupWindow, &DockPopupWindow::deleteLater); } + if (Utils::IS_WAYLAND_DISPLAY) { + Qt::WindowFlags flags = m_contextMenu->windowFlags() | Qt::FramelessWindowHint; + m_contextMenu->setWindowFlags(flags); + } + // 必须初始化父窗口,否则当主题切换之后再设置父窗口的时候palette会更改为主题切换前的palette if (QWidget *w = m_pluginInter->itemPopupApplet(m_itemKey)) { w->setParent(PopupWindow.data()); @@ -109,6 +114,7 @@ SystemPluginItem::~SystemPluginItem() { if (m_popupShown) popupWindowAccept(); + m_contextMenu->deleteLater(); } QString SystemPluginItem::itemKeyForConfig() @@ -379,6 +385,21 @@ void SystemPluginItem::hidePopup() emit requestWindowAutoHide(true); } +bool SystemPluginItem::containsPoint(QPoint pos) +{ + QPoint ptGlobal = mapToGlobal(QPoint(0, 0)); + QRect rectGlobal(ptGlobal, this->size()); + if (rectGlobal.contains(pos)) + return true; + + // 如果菜单列表隐藏,则认为不在区域内 + if (!m_contextMenu->isVisible()) + return false; + + // 判断鼠标是否在菜单区域 + return m_contextMenu->geometry().contains(pos); +} + void SystemPluginItem::hideNonModel() { // auto hide if popup is not model window @@ -501,7 +522,7 @@ void SystemPluginItem::showContextMenu() QJsonArray jsonMenuItems = jsonMenu.value("items").toArray(); for (auto item : jsonMenuItems) { QJsonObject itemObj = item.toObject(); - QAction *action = new QAction(itemObj.value("itemText").toString()); + QAction *action = new QAction(itemObj.value("itemText").toString(), m_contextMenu); action->setCheckable(itemObj.value("isCheckable").toBool()); action->setChecked(itemObj.value("checked").toBool()); action->setData(itemObj.value("itemId").toString()); @@ -520,6 +541,7 @@ void SystemPluginItem::showContextMenu() void SystemPluginItem::menuActionClicked(QAction *action) { invokedMenuItem(action->data().toString(), true); + Q_EMIT execActionFinished(); } void SystemPluginItem::showCentralWidget() diff --git a/frame/window/tray/widgets/systempluginitem.h b/frame/window/tray/widgets/systempluginitem.h index 593a53d9b..3d7f15b4f 100644 --- a/frame/window/tray/widgets/systempluginitem.h +++ b/frame/window/tray/widgets/systempluginitem.h @@ -62,9 +62,11 @@ public: void showPopupApplet(QWidget * const applet); void hidePopup(); + bool containsPoint(QPoint pos); signals: void itemVisibleChanged(bool visible); + void execActionFinished(); protected: bool event(QEvent *event) override; diff --git a/plugins/pluginmanager/dockplugincontroller.cpp b/plugins/pluginmanager/dockplugincontroller.cpp index cdb0b5a94..24a51ca23 100644 --- a/plugins/pluginmanager/dockplugincontroller.cpp +++ b/plugins/pluginmanager/dockplugincontroller.cpp @@ -661,10 +661,13 @@ bool DockPluginController::eventFilter(QObject *object, QEvent *event) bool DockPluginController::pluginCanDock(PluginsItemInterface *plugin) const { - // 观察插件是否已经驻留在任务栏上,如果已经驻留在任务栏,则始终显示 - if (plugin->flags() & PluginFlag::Attribute_ForceDock) + // 1、如果插件是强制驻留任务栏,则始终显示 + // 2、如果插件是托盘插件,例如U盘插件,则始终显示 + if ((plugin->flags() & PluginFlag::Attribute_ForceDock) + || (plugin->flags() & PluginFlag::Type_Tray)) return true; + // 3、插件已经驻留在任务栏,则始终显示 const QStringList configPlugins = SETTINGCONFIG->value(DOCK_QUICK_PLUGINS).toStringList(); return configPlugins.contains(plugin->pluginName()); }