fix: 修复wayland环境下任务栏右键菜单带有标题栏的问题

原因:原来的QMenu类是在头文件中直接定义的,没有指定parent
解决方案:头文件中定义指针,在cpp文件中创建,并指定parent

Log: 修复wayland环境下任务栏菜单显示异常
Influence: wayland下查看任务栏图表的右键菜单
Bug: https://pms.uniontech.com/bug-view-140873.html
Change-Id: Ib2792a47877040eed1ad1bae611ebfd79e13b38f
This commit is contained in:
donghualin 2022-06-29 15:57:04 +00:00
parent 5f4429b3f8
commit d6df41f3be
8 changed files with 45 additions and 22 deletions

View File

@ -21,11 +21,13 @@
#include "dockitem.h" #include "dockitem.h"
#include "pluginsitem.h" #include "pluginsitem.h"
#include "utils.h"
#include <QMouseEvent> #include <QMouseEvent>
#include <QJsonObject> #include <QJsonObject>
#include <QCursor> #include <QCursor>
#include <QApplication> #include <QApplication>
#include <QMenu>
#define PLUGIN_MARGIN 10 #define PLUGIN_MARGIN 10
#define ITEM_MAXSIZE 100 #define ITEM_MAXSIZE 100
@ -40,6 +42,7 @@ DockItem::DockItem(QWidget *parent)
, m_popupShown(false) , m_popupShown(false)
, m_tapAndHold(false) , m_tapAndHold(false)
, m_draging(false) , m_draging(false)
, m_contextMenu(new QMenu(this))
, m_popupTipsDelayTimer(new QTimer(this)) , m_popupTipsDelayTimer(new QTimer(this))
, m_popupAdjustDelayTimer(new QTimer(this)) , m_popupAdjustDelayTimer(new QTimer(this))
{ {
@ -52,6 +55,10 @@ DockItem::DockItem(QWidget *parent)
arrowRectangle->setArrowWidth(18); arrowRectangle->setArrowWidth(18);
arrowRectangle->setArrowHeight(10); arrowRectangle->setArrowHeight(10);
arrowRectangle->setObjectName("apppopup"); arrowRectangle->setObjectName("apppopup");
if (Utils::IS_WAYLAND_DISPLAY) {
Qt::WindowFlags flags = arrowRectangle->windowFlags() | Qt::FramelessWindowHint;
arrowRectangle->setWindowFlags(flags);
}
PopupWindow = arrowRectangle; PopupWindow = arrowRectangle;
connect(qApp, &QApplication::aboutToQuit, PopupWindow, &DockPopupWindow::deleteLater); 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_popupTipsDelayTimer, &QTimer::timeout, this, &DockItem::showHoverTips);
connect(m_popupAdjustDelayTimer, &QTimer::timeout, this, &DockItem::updatePopupPosition, Qt::QueuedConnection); 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); grabGesture(Qt::TapAndHoldGesture);
@ -233,7 +240,7 @@ void DockItem::showContextMenu()
QJsonObject jsonMenu = jsonDocument.object(); QJsonObject jsonMenu = jsonDocument.object();
qDeleteAll(m_contextMenu.actions()); qDeleteAll(m_contextMenu->actions());
QJsonArray jsonMenuItems = jsonMenu.value("items").toArray(); QJsonArray jsonMenuItems = jsonMenu.value("items").toArray();
for (auto item : jsonMenuItems) { for (auto item : jsonMenuItems) {
@ -243,13 +250,13 @@ void DockItem::showContextMenu()
action->setChecked(itemObj.value("checked").toBool()); action->setChecked(itemObj.value("checked").toBool());
action->setData(itemObj.value("itemId").toString()); action->setData(itemObj.value("itemId").toString());
action->setEnabled(itemObj.value("isActive").toBool()); action->setEnabled(itemObj.value("isActive").toBool());
m_contextMenu.addAction(action); m_contextMenu->addAction(action);
} }
hidePopup(); hidePopup();
emit requestWindowAutoHide(false); emit requestWindowAutoHide(false);
m_contextMenu.exec(QCursor::pos()); m_contextMenu->exec(QCursor::pos());
onContextMenuAccepted(); onContextMenuAccepted();
} }

View File

@ -28,12 +28,13 @@
#include <QFrame> #include <QFrame>
#include <QPointer> #include <QPointer>
#include <QGestureEvent> #include <QGestureEvent>
#include <QMenu>
#include <memory> #include <memory>
using namespace Dock; using namespace Dock;
class QMenu;
class DockItem : public QWidget class DockItem : public QWidget
{ {
Q_OBJECT Q_OBJECT
@ -111,7 +112,7 @@ protected:
bool m_popupShown; bool m_popupShown;
bool m_tapAndHold; bool m_tapAndHold;
bool m_draging; bool m_draging;
QMenu m_contextMenu; QMenu *m_contextMenu;
QPointer<QWidget> m_lastPopupWidget; QPointer<QWidget> m_lastPopupWidget;

View File

@ -40,6 +40,7 @@
#include <QX11Info> #include <QX11Info>
#include <QtConcurrent> #include <QtConcurrent>
#include <qpa/qplatformwindow.h> #include <qpa/qplatformwindow.h>
#include <QMenu>
#include <X11/X.h> #include <X11/X.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>

View File

@ -26,6 +26,7 @@
#include <QProcess> #include <QProcess>
#include <QDebug> #include <QDebug>
#include <QPointer> #include <QPointer>
#include <QMenu>
#include <xcb/xproto.h> #include <xcb/xproto.h>
@ -36,6 +37,7 @@ SystemPluginItem::SystemPluginItem(PluginsItemInterface *const pluginInter, cons
: BaseTrayWidget(parent) : BaseTrayWidget(parent)
, m_popupShown(false) , m_popupShown(false)
, m_tapAndHold(false) , m_tapAndHold(false)
, m_contextMenu(new QMenu(this))
, m_pluginInter(pluginInter) , m_pluginInter(pluginInter)
, m_centralWidget(m_pluginInter->itemWidget(itemKey)) , m_centralWidget(m_pluginInter->itemWidget(itemKey))
, m_popupTipsDelayTimer(new QTimer(this)) , m_popupTipsDelayTimer(new QTimer(this))
@ -67,6 +69,10 @@ SystemPluginItem::SystemPluginItem(PluginsItemInterface *const pluginInter, cons
arrowRectangle->setArrowWidth(18); arrowRectangle->setArrowWidth(18);
arrowRectangle->setArrowHeight(10); arrowRectangle->setArrowHeight(10);
arrowRectangle->setObjectName("systemtraypopup"); arrowRectangle->setObjectName("systemtraypopup");
if (Utils::IS_WAYLAND_DISPLAY) {
Qt::WindowFlags flags = arrowRectangle->windowFlags() | Qt::FramelessWindowHint;
arrowRectangle->setWindowFlags(flags);
}
PopupWindow = arrowRectangle; PopupWindow = arrowRectangle;
connect(qApp, &QApplication::aboutToQuit, PopupWindow, &DockPopupWindow::deleteLater); 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_popupTipsDelayTimer, &QTimer::timeout, this, &SystemPluginItem::showHoverTips);
connect(m_popupAdjustDelayTimer, &QTimer::timeout, this, &SystemPluginItem::updatePopupPosition, Qt::QueuedConnection); 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) if (m_gsettings)
connect(m_gsettings, &QGSettings::changed, this, &SystemPluginItem::onGSettingsChanged); connect(m_gsettings, &QGSettings::changed, this, &SystemPluginItem::onGSettingsChanged);
@ -430,14 +436,13 @@ void SystemPluginItem::showContextMenu()
if (menuJson.isEmpty()) if (menuJson.isEmpty())
return; return;
QJsonDocument jsonDocument = QJsonDocument::fromJson(menuJson.toLocal8Bit().data()); QJsonDocument jsonDocument = QJsonDocument::fromJson(menuJson.toLocal8Bit().data());
if (jsonDocument.isNull()) if (jsonDocument.isNull())
return; return;
QJsonObject jsonMenu = jsonDocument.object(); QJsonObject jsonMenu = jsonDocument.object();
qDeleteAll(m_contextMenu.actions()); qDeleteAll(m_contextMenu->actions());
QJsonArray jsonMenuItems = jsonMenu.value("items").toArray(); QJsonArray jsonMenuItems = jsonMenu.value("items").toArray();
for (auto item : jsonMenuItems) { for (auto item : jsonMenuItems) {
@ -447,13 +452,13 @@ void SystemPluginItem::showContextMenu()
action->setChecked(itemObj.value("checked").toBool()); action->setChecked(itemObj.value("checked").toBool());
action->setData(itemObj.value("itemId").toString()); action->setData(itemObj.value("itemId").toString());
action->setEnabled(itemObj.value("isActive").toBool()); action->setEnabled(itemObj.value("isActive").toBool());
m_contextMenu.addAction(action); m_contextMenu->addAction(action);
} }
hidePopup(); hidePopup();
emit requestWindowAutoHide(false); emit requestWindowAutoHide(false);
m_contextMenu.exec(QCursor::pos()); m_contextMenu->exec(QCursor::pos());
onContextMenuAccepted(); onContextMenuAccepted();
} }

View File

@ -27,10 +27,9 @@
#include "pluginsiteminterface.h" #include "pluginsiteminterface.h"
#include <QGestureEvent> #include <QGestureEvent>
#include <QMenu>
class QGSettings; class QGSettings;
class Menu; class QMenu;
class DockPopupWindow; class DockPopupWindow;
class SystemPluginItem : public BaseTrayWidget class SystemPluginItem : public BaseTrayWidget
@ -99,7 +98,7 @@ private:
private: private:
bool m_popupShown; bool m_popupShown;
bool m_tapAndHold; bool m_tapAndHold;
QMenu m_contextMenu; QMenu *m_contextMenu;
PluginsItemInterface* m_pluginInter; PluginsItemInterface* m_pluginInter;
QWidget *m_centralWidget; QWidget *m_centralWidget;

View File

@ -31,7 +31,6 @@
#include <QWidget> #include <QWidget>
#include <QPixmap> #include <QPixmap>
#include <QMenu>
#include <QAction> #include <QAction>
#include <QIcon> #include <QIcon>

View File

@ -24,6 +24,7 @@
#include <QProcess> #include <QProcess>
#include <QDebug> #include <QDebug>
#include <QMenu>
#include <xcb/xproto.h> #include <xcb/xproto.h>
@ -34,6 +35,7 @@ SystemTrayItem::SystemTrayItem(PluginsItemInterface *const pluginInter, const QS
: AbstractTrayWidget(parent) : AbstractTrayWidget(parent)
, m_popupShown(false) , m_popupShown(false)
, m_tapAndHold(false) , m_tapAndHold(false)
, m_contextMenu(new QMenu) // 此处设置parent有问题会导致当前菜单显示透明因此设置parent为nullptr,在析构函数中释放
, m_pluginInter(pluginInter) , m_pluginInter(pluginInter)
, m_centralWidget(m_pluginInter->itemWidget(itemKey)) , m_centralWidget(m_pluginInter->itemWidget(itemKey))
, m_popupTipsDelayTimer(new QTimer(this)) , m_popupTipsDelayTimer(new QTimer(this))
@ -65,10 +67,18 @@ SystemTrayItem::SystemTrayItem(PluginsItemInterface *const pluginInter, const QS
arrowRectangle->setArrowWidth(18); arrowRectangle->setArrowWidth(18);
arrowRectangle->setArrowHeight(10); arrowRectangle->setArrowHeight(10);
arrowRectangle->setObjectName("systemtraypopup"); arrowRectangle->setObjectName("systemtraypopup");
if (Utils::IS_WAYLAND_DISPLAY) {
Qt::WindowFlags flags = arrowRectangle->windowFlags() | Qt::FramelessWindowHint;
arrowRectangle->setWindowFlags(flags);
}
PopupWindow = arrowRectangle; PopupWindow = arrowRectangle;
connect(qApp, &QApplication::aboutToQuit, PopupWindow, &DockPopupWindow::deleteLater); 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 // 必须初始化父窗口否则当主题切换之后再设置父窗口的时候palette会更改为主题切换前的palette
if (QWidget *w = m_pluginInter->itemPopupApplet(m_itemKey)) { if (QWidget *w = m_pluginInter->itemPopupApplet(m_itemKey)) {
w->setParent(PopupWindow.data()); 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_popupTipsDelayTimer, &QTimer::timeout, this, &SystemTrayItem::showHoverTips);
connect(m_popupAdjustDelayTimer, &QTimer::timeout, this, &SystemTrayItem::updatePopupPosition, Qt::QueuedConnection); 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) if (m_gsettings)
connect(m_gsettings, &QGSettings::changed, this, &SystemTrayItem::onGSettingsChanged); connect(m_gsettings, &QGSettings::changed, this, &SystemTrayItem::onGSettingsChanged);
@ -93,6 +103,7 @@ SystemTrayItem::SystemTrayItem(PluginsItemInterface *const pluginInter, const QS
SystemTrayItem::~SystemTrayItem() SystemTrayItem::~SystemTrayItem()
{ {
m_contextMenu->deleteLater();
if (m_popupShown) if (m_popupShown)
popupWindowAccept(); popupWindowAccept();
} }
@ -435,7 +446,7 @@ void SystemTrayItem::showContextMenu()
QJsonObject jsonMenu = jsonDocument.object(); QJsonObject jsonMenu = jsonDocument.object();
qDeleteAll(m_contextMenu.actions()); qDeleteAll(m_contextMenu->actions());
QJsonArray jsonMenuItems = jsonMenu.value("items").toArray(); QJsonArray jsonMenuItems = jsonMenu.value("items").toArray();
for (auto item : jsonMenuItems) { for (auto item : jsonMenuItems) {
@ -445,13 +456,13 @@ void SystemTrayItem::showContextMenu()
action->setChecked(itemObj.value("checked").toBool()); action->setChecked(itemObj.value("checked").toBool());
action->setData(itemObj.value("itemId").toString()); action->setData(itemObj.value("itemId").toString());
action->setEnabled(itemObj.value("isActive").toBool()); action->setEnabled(itemObj.value("isActive").toBool());
m_contextMenu.addAction(action); m_contextMenu->addAction(action);
} }
hidePopup(); hidePopup();
emit requestWindowAutoHide(false); emit requestWindowAutoHide(false);
m_contextMenu.exec(QCursor::pos()); m_contextMenu->exec(QCursor::pos());
onContextMenuAccepted(); onContextMenuAccepted();
} }

View File

@ -28,10 +28,10 @@
#include "pluginsiteminterface.h" #include "pluginsiteminterface.h"
#include <QGestureEvent> #include <QGestureEvent>
#include <QMenu>
class QGSettings; class QGSettings;
class Menu; class QMenu;
class SystemTrayItem : public AbstractTrayWidget class SystemTrayItem : public AbstractTrayWidget
{ {
Q_OBJECT Q_OBJECT
@ -97,7 +97,7 @@ private:
private: private:
bool m_popupShown; bool m_popupShown;
bool m_tapAndHold; bool m_tapAndHold;
QMenu m_contextMenu; QMenu *m_contextMenu;
PluginsItemInterface* m_pluginInter; PluginsItemInterface* m_pluginInter;
QWidget *m_centralWidget; QWidget *m_centralWidget;