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()); }