From d6df41f3bee3cd0c553199663afd56d54f88e446 Mon Sep 17 00:00:00 2001 From: donghualin Date: Wed, 29 Jun 2022 15:57:04 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dwayland=E7=8E=AF?= =?UTF-8?q?=E5=A2=83=E4=B8=8B=E4=BB=BB=E5=8A=A1=E6=A0=8F=E5=8F=B3=E9=94=AE?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E5=B8=A6=E6=9C=89=E6=A0=87=E9=A2=98=E6=A0=8F?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原因:原来的QMenu类是在头文件中直接定义的,没有指定parent 解决方案:头文件中定义指针,在cpp文件中创建,并指定parent Log: 修复wayland环境下任务栏菜单显示异常 Influence: wayland下查看任务栏图表的右键菜单 Bug: https://pms.uniontech.com/bug-view-140873.html Change-Id: Ib2792a47877040eed1ad1bae611ebfd79e13b38f --- frame/item/dockitem.cpp | 15 +++++++++++---- frame/item/dockitem.h | 5 +++-- frame/window/mainwindow.cpp | 1 + .../window/tray/widgets/systempluginitem.cpp | 15 ++++++++++----- frame/window/tray/widgets/systempluginitem.h | 5 ++--- plugins/trash/trashwidget.h | 1 - plugins/tray/system-trays/systemtrayitem.cpp | 19 +++++++++++++++---- plugins/tray/system-trays/systemtrayitem.h | 6 +++--- 8 files changed, 45 insertions(+), 22 deletions(-) diff --git a/frame/item/dockitem.cpp b/frame/item/dockitem.cpp index ca7894b80..01dcc8ae5 100644 --- a/frame/item/dockitem.cpp +++ b/frame/item/dockitem.cpp @@ -21,11 +21,13 @@ #include "dockitem.h" #include "pluginsitem.h" +#include "utils.h" #include #include #include #include +#include #define PLUGIN_MARGIN 10 #define ITEM_MAXSIZE 100 @@ -40,6 +42,7 @@ DockItem::DockItem(QWidget *parent) , m_popupShown(false) , m_tapAndHold(false) , m_draging(false) + , m_contextMenu(new QMenu(this)) , m_popupTipsDelayTimer(new QTimer(this)) , m_popupAdjustDelayTimer(new QTimer(this)) { @@ -52,6 +55,10 @@ DockItem::DockItem(QWidget *parent) arrowRectangle->setArrowWidth(18); arrowRectangle->setArrowHeight(10); arrowRectangle->setObjectName("apppopup"); + if (Utils::IS_WAYLAND_DISPLAY) { + Qt::WindowFlags flags = arrowRectangle->windowFlags() | Qt::FramelessWindowHint; + arrowRectangle->setWindowFlags(flags); + } PopupWindow = arrowRectangle; connect(qApp, &QApplication::aboutToQuit, PopupWindow, &DockPopupWindow::deleteLater); } @@ -64,7 +71,7 @@ DockItem::DockItem(QWidget *parent) connect(m_popupTipsDelayTimer, &QTimer::timeout, this, &DockItem::showHoverTips); connect(m_popupAdjustDelayTimer, &QTimer::timeout, this, &DockItem::updatePopupPosition, Qt::QueuedConnection); - connect(&m_contextMenu, &QMenu::triggered, this, &DockItem::menuActionClicked); + connect(m_contextMenu, &QMenu::triggered, this, &DockItem::menuActionClicked); grabGesture(Qt::TapAndHoldGesture); @@ -233,7 +240,7 @@ void DockItem::showContextMenu() QJsonObject jsonMenu = jsonDocument.object(); - qDeleteAll(m_contextMenu.actions()); + qDeleteAll(m_contextMenu->actions()); QJsonArray jsonMenuItems = jsonMenu.value("items").toArray(); for (auto item : jsonMenuItems) { @@ -243,13 +250,13 @@ void DockItem::showContextMenu() action->setChecked(itemObj.value("checked").toBool()); action->setData(itemObj.value("itemId").toString()); action->setEnabled(itemObj.value("isActive").toBool()); - m_contextMenu.addAction(action); + m_contextMenu->addAction(action); } hidePopup(); emit requestWindowAutoHide(false); - m_contextMenu.exec(QCursor::pos()); + m_contextMenu->exec(QCursor::pos()); onContextMenuAccepted(); } diff --git a/frame/item/dockitem.h b/frame/item/dockitem.h index b1b7728c8..f7bb5a0b0 100644 --- a/frame/item/dockitem.h +++ b/frame/item/dockitem.h @@ -28,12 +28,13 @@ #include #include #include -#include #include using namespace Dock; +class QMenu; + class DockItem : public QWidget { Q_OBJECT @@ -111,7 +112,7 @@ protected: bool m_popupShown; bool m_tapAndHold; bool m_draging; - QMenu m_contextMenu; + QMenu *m_contextMenu; QPointer m_lastPopupWidget; diff --git a/frame/window/mainwindow.cpp b/frame/window/mainwindow.cpp index cfbaf6301..8612418d2 100755 --- a/frame/window/mainwindow.cpp +++ b/frame/window/mainwindow.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include diff --git a/frame/window/tray/widgets/systempluginitem.cpp b/frame/window/tray/widgets/systempluginitem.cpp index de53d6f2b..bac7752bd 100644 --- a/frame/window/tray/widgets/systempluginitem.cpp +++ b/frame/window/tray/widgets/systempluginitem.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -36,6 +37,7 @@ SystemPluginItem::SystemPluginItem(PluginsItemInterface *const pluginInter, cons : BaseTrayWidget(parent) , m_popupShown(false) , m_tapAndHold(false) + , m_contextMenu(new QMenu(this)) , m_pluginInter(pluginInter) , m_centralWidget(m_pluginInter->itemWidget(itemKey)) , m_popupTipsDelayTimer(new QTimer(this)) @@ -67,6 +69,10 @@ SystemPluginItem::SystemPluginItem(PluginsItemInterface *const pluginInter, cons arrowRectangle->setArrowWidth(18); arrowRectangle->setArrowHeight(10); arrowRectangle->setObjectName("systemtraypopup"); + if (Utils::IS_WAYLAND_DISPLAY) { + Qt::WindowFlags flags = arrowRectangle->windowFlags() | Qt::FramelessWindowHint; + arrowRectangle->setWindowFlags(flags); + } PopupWindow = arrowRectangle; connect(qApp, &QApplication::aboutToQuit, PopupWindow, &DockPopupWindow::deleteLater); } @@ -85,7 +91,7 @@ SystemPluginItem::SystemPluginItem(PluginsItemInterface *const pluginInter, cons connect(m_popupTipsDelayTimer, &QTimer::timeout, this, &SystemPluginItem::showHoverTips); connect(m_popupAdjustDelayTimer, &QTimer::timeout, this, &SystemPluginItem::updatePopupPosition, Qt::QueuedConnection); - connect(&m_contextMenu, &QMenu::triggered, this, &SystemPluginItem::menuActionClicked); + connect(m_contextMenu, &QMenu::triggered, this, &SystemPluginItem::menuActionClicked); if (m_gsettings) connect(m_gsettings, &QGSettings::changed, this, &SystemPluginItem::onGSettingsChanged); @@ -430,14 +436,13 @@ void SystemPluginItem::showContextMenu() if (menuJson.isEmpty()) return; - QJsonDocument jsonDocument = QJsonDocument::fromJson(menuJson.toLocal8Bit().data()); if (jsonDocument.isNull()) return; QJsonObject jsonMenu = jsonDocument.object(); - qDeleteAll(m_contextMenu.actions()); + qDeleteAll(m_contextMenu->actions()); QJsonArray jsonMenuItems = jsonMenu.value("items").toArray(); for (auto item : jsonMenuItems) { @@ -447,13 +452,13 @@ void SystemPluginItem::showContextMenu() action->setChecked(itemObj.value("checked").toBool()); action->setData(itemObj.value("itemId").toString()); action->setEnabled(itemObj.value("isActive").toBool()); - m_contextMenu.addAction(action); + m_contextMenu->addAction(action); } hidePopup(); emit requestWindowAutoHide(false); - m_contextMenu.exec(QCursor::pos()); + m_contextMenu->exec(QCursor::pos()); onContextMenuAccepted(); } diff --git a/frame/window/tray/widgets/systempluginitem.h b/frame/window/tray/widgets/systempluginitem.h index f9a9ca148..7e1fa28ec 100644 --- a/frame/window/tray/widgets/systempluginitem.h +++ b/frame/window/tray/widgets/systempluginitem.h @@ -27,10 +27,9 @@ #include "pluginsiteminterface.h" #include -#include class QGSettings; -class Menu; +class QMenu; class DockPopupWindow; class SystemPluginItem : public BaseTrayWidget @@ -99,7 +98,7 @@ private: private: bool m_popupShown; bool m_tapAndHold; - QMenu m_contextMenu; + QMenu *m_contextMenu; PluginsItemInterface* m_pluginInter; QWidget *m_centralWidget; diff --git a/plugins/trash/trashwidget.h b/plugins/trash/trashwidget.h index f3acbcdfb..87a7c236f 100644 --- a/plugins/trash/trashwidget.h +++ b/plugins/trash/trashwidget.h @@ -31,7 +31,6 @@ #include #include -#include #include #include diff --git a/plugins/tray/system-trays/systemtrayitem.cpp b/plugins/tray/system-trays/systemtrayitem.cpp index 6dc8ff29b..0ed45632d 100644 --- a/plugins/tray/system-trays/systemtrayitem.cpp +++ b/plugins/tray/system-trays/systemtrayitem.cpp @@ -24,6 +24,7 @@ #include #include +#include #include @@ -34,6 +35,7 @@ SystemTrayItem::SystemTrayItem(PluginsItemInterface *const pluginInter, const QS : AbstractTrayWidget(parent) , m_popupShown(false) , m_tapAndHold(false) + , m_contextMenu(new QMenu) // 此处设置parent有问题,会导致当前菜单显示透明,因此设置parent为nullptr,在析构函数中释放 , m_pluginInter(pluginInter) , m_centralWidget(m_pluginInter->itemWidget(itemKey)) , m_popupTipsDelayTimer(new QTimer(this)) @@ -65,10 +67,18 @@ SystemTrayItem::SystemTrayItem(PluginsItemInterface *const pluginInter, const QS arrowRectangle->setArrowWidth(18); arrowRectangle->setArrowHeight(10); arrowRectangle->setObjectName("systemtraypopup"); + if (Utils::IS_WAYLAND_DISPLAY) { + Qt::WindowFlags flags = arrowRectangle->windowFlags() | Qt::FramelessWindowHint; + arrowRectangle->setWindowFlags(flags); + } PopupWindow = arrowRectangle; 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()); @@ -83,7 +93,7 @@ SystemTrayItem::SystemTrayItem(PluginsItemInterface *const pluginInter, const QS connect(m_popupTipsDelayTimer, &QTimer::timeout, this, &SystemTrayItem::showHoverTips); connect(m_popupAdjustDelayTimer, &QTimer::timeout, this, &SystemTrayItem::updatePopupPosition, Qt::QueuedConnection); - connect(&m_contextMenu, &QMenu::triggered, this, &SystemTrayItem::menuActionClicked); + connect(m_contextMenu, &QMenu::triggered, this, &SystemTrayItem::menuActionClicked); if (m_gsettings) connect(m_gsettings, &QGSettings::changed, this, &SystemTrayItem::onGSettingsChanged); @@ -93,6 +103,7 @@ SystemTrayItem::SystemTrayItem(PluginsItemInterface *const pluginInter, const QS SystemTrayItem::~SystemTrayItem() { + m_contextMenu->deleteLater(); if (m_popupShown) popupWindowAccept(); } @@ -435,7 +446,7 @@ void SystemTrayItem::showContextMenu() QJsonObject jsonMenu = jsonDocument.object(); - qDeleteAll(m_contextMenu.actions()); + qDeleteAll(m_contextMenu->actions()); QJsonArray jsonMenuItems = jsonMenu.value("items").toArray(); for (auto item : jsonMenuItems) { @@ -445,13 +456,13 @@ void SystemTrayItem::showContextMenu() action->setChecked(itemObj.value("checked").toBool()); action->setData(itemObj.value("itemId").toString()); action->setEnabled(itemObj.value("isActive").toBool()); - m_contextMenu.addAction(action); + m_contextMenu->addAction(action); } hidePopup(); emit requestWindowAutoHide(false); - m_contextMenu.exec(QCursor::pos()); + m_contextMenu->exec(QCursor::pos()); onContextMenuAccepted(); } diff --git a/plugins/tray/system-trays/systemtrayitem.h b/plugins/tray/system-trays/systemtrayitem.h index 67d54d727..a33504dbb 100644 --- a/plugins/tray/system-trays/systemtrayitem.h +++ b/plugins/tray/system-trays/systemtrayitem.h @@ -28,10 +28,10 @@ #include "pluginsiteminterface.h" #include -#include class QGSettings; -class Menu; +class QMenu; + class SystemTrayItem : public AbstractTrayWidget { Q_OBJECT @@ -97,7 +97,7 @@ private: private: bool m_popupShown; bool m_tapAndHold; - QMenu m_contextMenu; + QMenu *m_contextMenu; PluginsItemInterface* m_pluginInter; QWidget *m_centralWidget;