diff --git a/plugins/dde-dock/common/dockcontextmenu.cpp b/plugins/dde-dock/common/dockcontextmenu.cpp deleted file mode 100644 index 4f6d0ccfb..000000000 --- a/plugins/dde-dock/common/dockcontextmenu.cpp +++ /dev/null @@ -1,129 +0,0 @@ -// SPDX-FileCopyrightText: 2019 - 2023 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -#include "dockcontextmenu.h" -#include "constants.h" -#include "../util/utils.h" - -#include -#include -#include -#include -#include -#include - -DockContextMenu::DockContextMenu() -{ - // 解决键盘上下键不能操作右键菜单 - if (Utils::IS_WAYLAND_DISPLAY) { - setAttribute(Qt::WA_NativeWindow); - windowHandle()->setProperty("_d_dwayland_window-type", "focusmenu"); - } -} - -// action宽度的计算方法:文字宽度 + 小红点(如果有的话)+ 左右边距60 -// 菜单的宽度为action的最大宽度与160(设计的最小宽度)两者取较大值 -int DockContextMenu::suitableWidth() const -{ - int maxWidth = 0; - for (auto action : actions()) { - auto textWidth = fontMetrics().horizontalAdvance(action->text()); - textWidth += m_showReminderActions.contains(action) ? 26 : 0; - maxWidth = maxWidth < textWidth ? textWidth : maxWidth; - } - - return qMax(maxWidth + 60, 160); -} - -void DockContextMenu::paintEvent(QPaintEvent* e) -{ - QMenu::paintEvent(e); - - QPainter p(this); - p.setRenderHint(QPainter::Antialiasing, true); - for (auto action : m_showReminderActions) { - auto geo = actionGeometry(action); - QColor color("#FF3B30"); - p.setPen(color); - p.setBrush(color); - p.drawEllipse(geo.x() + geo.width() - 26, geo.y() + (geo.height() - 6) / 2, 6, 6); - } - - p.end(); -} - -DockContextMenuHelper::DockContextMenuHelper() - : QObject(nullptr) - , m_currentWidget(nullptr) -{ - qApp->setProperty(MENU_IS_VISIBLE_OR_JUST_HIDE, false); - connect(&m_contextMenu, &QMenu::triggered, this, [this] (QAction *action) { - if (m_currentWidget) { - Q_EMIT menuActionClicked(action, m_currentWidget.data()); - } - }); -} - -QPoint DockContextMenuHelper::correctMenuPos(QPoint pos, int menuHeight) -{ - if (qApp->property(PROP_POSITION).value() != Dock::Position::Bottom) - return pos; - const QPoint &mousePos = QCursor::pos(); - const bool snapToMouse = QRect(pos.x() - 3, pos.y() - 3, 6, 6).contains(mousePos); - if (!snapToMouse) { - pos.setY(pos.y() - menuHeight); - } - return pos; -} - -void DockContextMenuHelper::showContextMenu(QWidget* who, const QString& menuJson, const QPoint& pos) -{ - if (menuJson.isEmpty() || !who) - return; - - m_currentWidget = who; - QJsonDocument jsonDocument = QJsonDocument::fromJson(menuJson.toLocal8Bit().data()); - if (jsonDocument.isNull()) - return; - - QJsonObject jsonMenu = jsonDocument.object(); - QJsonArray jsonMenuItems = jsonMenu.value("items").toArray(); - if (jsonMenuItems.size() == 0) - return; - - m_contextMenu.clearShowReminderActions(); - qDeleteAll(m_contextMenu.actions()); - - for (auto item : jsonMenuItems) { - QJsonObject itemObj = item.toObject(); - auto* action = new QAction(itemObj.value("itemText").toString()); - action->setCheckable(itemObj.value("isCheckable").toBool()); - action->setChecked(itemObj.value("checked").toBool()); - action->setData(itemObj.value("itemId").toString()); - action->setEnabled(itemObj.value("isActive").toBool()); - if (itemObj.value("showReminder").toBool()) { - m_contextMenu.addShowReminderAction(action); - } - m_contextMenu.addAction(action); - } - - m_contextMenu.setFixedWidth(m_contextMenu.suitableWidth()); - - if (!m_contextMenu.parentWidget()) - m_contextMenu.setParent(who->topLevelWidget(), Qt::Popup); - - qApp->setProperty(MENU_IS_VISIBLE_OR_JUST_HIDE, true); - QPoint tpmPos = pos; - tpmPos = correctMenuPos(tpmPos, m_contextMenu.sizeHint().height()); - m_contextMenu.exec(tpmPos); - - QTimer::singleShot(100, [] { - qApp->setProperty(MENU_IS_VISIBLE_OR_JUST_HIDE, false); - }); -} - -bool DockContextMenuHelper::menuIsVisible() const -{ - return m_contextMenu.isVisible(); -} diff --git a/plugins/dde-dock/common/dockcontextmenu.h b/plugins/dde-dock/common/dockcontextmenu.h deleted file mode 100644 index a24f70701..000000000 --- a/plugins/dde-dock/common/dockcontextmenu.h +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-FileCopyrightText: 2019 - 2023 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -#ifndef DOCKITEMCONTEXTMENU_H -#define DOCKITEMCONTEXTMENU_H - -#include -#include -#include -#include -#include - -#include - -const static QByteArray MENU_IS_VISIBLE_OR_JUST_HIDE = "menuIsShownOrJustClicked"; - -class DockContextMenu : public QMenu -{ -public: - using QMenu::QMenu; - - DockContextMenu(); - - void clearShowReminderActions() { m_showReminderActions.clear(); } - - void addShowReminderAction(QAction* action) { m_showReminderActions.append(action); } - - int suitableWidth() const; - -protected: - void paintEvent(QPaintEvent* e) override; - -private: - QList> m_showReminderActions; -}; - -class DockContextMenuHelper : public QObject, public Dtk::Core::DSingleton -{ - friend class Dtk::Core::DSingleton; - - Q_OBJECT -public: - void showContextMenu(QWidget* who, const QString& menuJson, const QPoint& pos = QCursor::pos()); - bool menuIsVisible() const; - const QWidget* currentWidget() const { return m_currentWidget; } - - static QPoint correctMenuPos(QPoint pos, int menuHeight); - -signals: - void menuActionClicked(QAction *action, QObject *obj); - -private: - DockContextMenuHelper(); - ~DockContextMenuHelper() {} - -private: - DockContextMenu m_contextMenu; - QPointer m_currentWidget; -}; - -#endif diff --git a/src/loader/CMakeLists.txt b/src/loader/CMakeLists.txt index f0c29bd77..fd396f518 100644 --- a/src/loader/CMakeLists.txt +++ b/src/loader/CMakeLists.txt @@ -28,6 +28,8 @@ add_executable(trayplugin-loader loader.qrc dqwaylandplatform.h dqwaylandplatform.cpp + dockcontextmenu.h + dockcontextmenu.cpp ) target_include_directories(trayplugin-loader PUBLIC diff --git a/src/loader/dockcontextmenu.cpp b/src/loader/dockcontextmenu.cpp new file mode 100644 index 000000000..6654b9263 --- /dev/null +++ b/src/loader/dockcontextmenu.cpp @@ -0,0 +1,39 @@ +//SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. +// +//SPDX-License-Identifier: GPL-3.0-or-later + +#include "dockcontextmenu.h" + +#include +#include + +static const bool IS_WAYLAND_DISPLAY = !qgetenv("WAYLAND_DISPLAY").isEmpty(); + +DockContextMenu::DockContextMenu(QWidget *parent) + : QMenu(parent) +{ + // 解决键盘上下键不能操作右键菜单 + if (IS_WAYLAND_DISPLAY) { + setAttribute(Qt::WA_NativeWindow); + windowHandle()->setProperty("_d_dwayland_window-type", "focusmenu"); + } +} + +void DockContextMenu::paintEvent(QPaintEvent* e) +{ + QMenu::paintEvent(e); + + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing, true); + for (auto action : actions()) { + if (action->property("showReminder").toBool()) { + auto geo = actionGeometry(action); + QColor color("#FF3B30"); + p.setPen(color); + p.setBrush(color); + p.drawEllipse(geo.x() + geo.width() - 26, geo.y() + (geo.height() - 6) / 2, 6, 6); + } + } + + p.end(); +} diff --git a/src/loader/dockcontextmenu.h b/src/loader/dockcontextmenu.h new file mode 100644 index 000000000..3768447a4 --- /dev/null +++ b/src/loader/dockcontextmenu.h @@ -0,0 +1,14 @@ +//SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. +// +//SPDX-License-Identifier: GPL-3.0-or-later + +#include + +class DockContextMenu : public QMenu +{ +public: + explicit DockContextMenu(QWidget *parent = nullptr); + +protected: + void paintEvent(QPaintEvent* e) override; +}; diff --git a/src/loader/pluginitem.cpp b/src/loader/pluginitem.cpp index 9f6b27d81..16b567e96 100644 --- a/src/loader/pluginitem.cpp +++ b/src/loader/pluginitem.cpp @@ -6,6 +6,7 @@ #include "pluginitem.h" #include "plugin.h" #include "widgetplugin.h" +#include "dockcontextmenu.h" #include #include @@ -17,7 +18,7 @@ PluginItem::PluginItem(PluginsItemInterface *pluginItemInterface, const QString : QWidget(parent) , m_pluginsItemInterface(pluginItemInterface) , m_itemKey(itemKey) - , m_menu(new QMenu) + , m_menu(new DockContextMenu(this)) , m_tooltipTimer(new QTimer(this)) , m_tipsWidget(nullptr) { @@ -291,6 +292,8 @@ void PluginItem::initPluginMenu() action->setChecked(itemObj.value("checked").toBool()); action->setData(itemObj.value("itemId").toString()); action->setEnabled(itemObj.value("isActive").toBool()); + auto showReminder = itemObj.value("showReminder").toBool(); + action->setProperty("showReminder", showReminder); m_menu->addAction(action); } } diff --git a/src/loader/pluginitem.h b/src/loader/pluginitem.h index fc885006f..5960f7cde 100644 --- a/src/loader/pluginitem.h +++ b/src/loader/pluginitem.h @@ -12,7 +12,7 @@ const int Attribute_ForceUnDock = 0x800000; -class QMenu; +class DockContextMenu; class PluginItem : public QWidget { Q_OBJECT