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 "pluginsitem.h"
#include "utils.h"
#include <QMouseEvent>
#include <QJsonObject>
#include <QCursor>
#include <QApplication>
#include <QMenu>
#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();
}

View File

@ -28,12 +28,13 @@
#include <QFrame>
#include <QPointer>
#include <QGestureEvent>
#include <QMenu>
#include <memory>
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<QWidget> m_lastPopupWidget;

View File

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

View File

@ -26,6 +26,7 @@
#include <QProcess>
#include <QDebug>
#include <QPointer>
#include <QMenu>
#include <xcb/xproto.h>
@ -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();
}

View File

@ -27,10 +27,9 @@
#include "pluginsiteminterface.h"
#include <QGestureEvent>
#include <QMenu>
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;

View File

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

View File

@ -24,6 +24,7 @@
#include <QProcess>
#include <QDebug>
#include <QMenu>
#include <xcb/xproto.h>
@ -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();
}

View File

@ -28,10 +28,10 @@
#include "pluginsiteminterface.h"
#include <QGestureEvent>
#include <QMenu>
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;