fix: disable menu scroll indicator in application tray plugin#451
Conversation
Reviewer's guide (collapsed on small PRs)Reviewer's GuideDisables QMenu scroll indicators for application tray submenus using Qt private APIs and adjusts Wayland plugin popup positioning, including linking against Qt private libraries needed for the new behavior. Sequence diagram for menuUpdated handling and scroll indicator disablingsequenceDiagram
participant DBusMenu
participant DBusMenuImporter
participant QMenu
participant QObjectPrivate
participant QMenuPrivate
participant QMenuScroller
DBusMenuImporter->>DBusMenu: menuUpdated(menu : QMenu*)
activate DBusMenu
DBusMenu->>QMenu: sizeHint()
QMenu-->>DBusMenu: size : QSize
DBusMenu->>QMenu: setFixedSize(size)
DBusMenu->>QObjectPrivate: get(menu)
QObjectPrivate-->>DBusMenu: menuPrivate : QMenuPrivate*
DBusMenu->>QMenuPrivate: access scroll
QMenuPrivate->>QMenuScroller: set scrollFlags = ScrollNone
deactivate DBusMenu
Sequence diagram for Wayland sub-window popup positioningsequenceDiagram
actor User
participant TrayApplication
participant PluginManagerIntegration
participant ParentWindow as QWindow_parent
participant SubWindow as QWindow_sub
participant PluginPopup
User->>TrayApplication: open sub-menu or popup
TrayApplication->>PluginManagerIntegration: tryCreatePopupForSubWindow(SubWindow)
activate PluginManagerIntegration
PluginManagerIntegration->>ParentWindow: x(), width()
ParentWindow-->>PluginManagerIntegration: parentX, parentWidth
PluginManagerIntegration->>ParentWindow: y()
ParentWindow-->>PluginManagerIntegration: parentY
PluginManagerIntegration->>SubWindow: y()
SubWindow-->>PluginManagerIntegration: subY
PluginManagerIntegration->>PluginPopup: setX(parentX + parentWidth)
PluginManagerIntegration->>PluginPopup: setY(parentY + subY)
PluginManagerIntegration->>SubWindow: setY(parentY + subY)
PluginManagerIntegration-->>TrayApplication: true
deactivate PluginManagerIntegration
Class diagram for DBusMenu scroll disabling and popup positioningclassDiagram
class DBusMenuImporter {
<<QtClass>>
+signal menuUpdated(menu : QMenu*)
}
class DBusMenu {
+DBusMenu(parent : QObject*)
+createMenu(parent : QWidget*) QMenu*
}
class QMenu {
+sizeHint() QSize
+setFixedSize(size : QSize) void
}
class QObjectPrivate {
+static get(object : QObject*) QObjectPrivate*
}
class QMenuPrivate {
+scroll : QMenuScroller*
}
class QMenuScroller {
<<enum-like>>
+scrollFlags : int
+ScrollNone : int
}
class PluginManagerIntegration {
+tryCreatePopupForSubWindow(window : QWindow*) bool
}
class QWindow {
+x() int
+y() int
+setX(x : int) void
+setY(y : int) void
+width() int
}
class PluginPopup {
+setX(x : int) void
+setY(y : int) void
}
DBusMenuImporter <|-- DBusMenu
DBusMenu ..> QMenu : uses
DBusMenu ..> QObjectPrivate : uses
QObjectPrivate <|.. QMenuPrivate
QMenuPrivate o-- QMenuScroller
PluginManagerIntegration ..> QWindow : positions
PluginManagerIntegration ..> PluginPopup : positions
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 3 issues, and left some high level feedback:
- Using Qt private headers and
QMenuPrivateties this plugin to specific Qt internals; consider isolating this logic behind a small helper with clear comments about the Qt version assumptions and expected failure mode if the private API changes. - The change to the
menuUpdatedconnection removedQt::QueuedConnection, which may alter the timing and reentrancy of menu size/scroll updates; double-check whether a queued connection is still needed to avoid layout or signal recursion issues. - In
tryCreatePopupForSubWindow, bothpluginPopupandwindownow have their Y position adjusted usingparentPos.y() + window->y(); verify that updating the child window’s Y is actually required and doesn’t cause double application of the offset in some environments.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Using Qt private headers and `QMenuPrivate` ties this plugin to specific Qt internals; consider isolating this logic behind a small helper with clear comments about the Qt version assumptions and expected failure mode if the private API changes.
- The change to the `menuUpdated` connection removed `Qt::QueuedConnection`, which may alter the timing and reentrancy of menu size/scroll updates; double-check whether a queued connection is still needed to avoid layout or signal recursion issues.
- In `tryCreatePopupForSubWindow`, both `pluginPopup` and `window` now have their Y position adjusted using `parentPos.y() + window->y()`; verify that updating the child window’s Y is actually required and doesn’t cause double application of the offset in some environments.
## Individual Comments
### Comment 1
<location path="plugins/application-tray/sniprotocolhandler.cpp" line_range="38-39" />
<code_context>
menu->setFixedSize(menu->sizeHint());
- }, Qt::QueuedConnection);
+ // TODO 删除 QMenu 的滚动功能,修复首次子菜单显示滚动指示器问题
+ if (auto dp = static_cast<QMenuPrivate*>(QObjectPrivate::get(menu))) {
+ dp->scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone;
+ }
+ });
</code_context>
<issue_to_address>
**issue (bug_risk):** Potential null dereference when accessing `dp->scroll`.
`dp->scroll` may still be null even when `QObjectPrivate::get(menu)` succeeds, depending on how the menu is constructed/used. Please either guard this access (e.g. `if (dp->scroll)`) or confirm from Qt sources that `scroll` is guaranteed non-null here before dereferencing it.
</issue_to_address>
### Comment 2
<location path="plugins/application-tray/sniprotocolhandler.cpp" line_range="41" />
<code_context>
+ if (auto dp = static_cast<QMenuPrivate*>(QObjectPrivate::get(menu))) {
+ dp->scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone;
+ }
+ });
}
virtual QMenu *createMenu(QWidget *parent) override
</code_context>
<issue_to_address>
**question (bug_risk):** Changing from `Qt::QueuedConnection` to default connection might introduce reentrancy or threading issues.
If `menuUpdated` can be emitted from a non-GUI thread or in reentrancy-sensitive paths, this change may alter when and where `setFixedSize` and the new private API calls run. Consider keeping the queued connection unless there’s a concrete need for synchronous execution, and verify the signal’s threading and reentrancy constraints before changing it.
</issue_to_address>
### Comment 3
<location path="src/tray-wayland-integration/pluginmanagerintegration.cpp" line_range="141" />
<code_context>
// TODO move to parentWindow's right position.
pluginPopup->setX(parentPos.x() + parentWindow->width());
pluginPopup->setY(parentPos.y() + window->y());
+ window->setY(parentPos.y() + window->y());
return true;
}
</code_context>
<issue_to_address>
**issue (bug_risk):** Adjusting the subwindow’s Y coordinate like this may double-apply the parent offset or introduce unintended side effects.
For child windows, `window->y()` is usually parent-relative while `parentPos` is global. Adding `parentPos.y()` to `window->y()` and then writing it back to `window` likely applies the parent offset twice. Also, having `tryCreatePopupForSubWindow` mutate the window’s geometry may be unexpected to callers. Please double-check the coordinate spaces and whether only `pluginPopup` should be adjusted here, potentially using `mapToGlobal`/`mapFromGlobal` to avoid double offsets.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
1. Removed scroll indicator functionality in QMenu submenus to prevent display issues 2. Added private Qt headers to access QMenuPrivate and disable scrolling 3. Adjusted window positioning logic for popup sub-windows Log: Disabled menu scroll indicator in application tray to fix display issues Influence: 1. Test application tray menu display without scroll indicators 2. Verify sub-menu opening behavior and positioning 3. Test popup window positioning for wayland integration 4. Verify menu size and layout correctness 5. Test on different screen resolutions and scaling factors fix: 禁止托盘菜单滚动指示器功能 1. 移除 QMenu 子菜单的滚动指示器功能,解决显示问题 2. 添加 Qt 私有头文件以访问 QMenuPrivate 并禁用滚动 3. 调整弹出子窗口的定位逻辑 Log: 禁用托盘菜单滚动指示器以修复显示问题 Influence: 1. 测试托盘菜单显示,确认无滚动指示器 2. 验证子菜单打开行为和定位 3. 测试 wayland 集成下的弹出窗口定位 4. 验证菜单尺寸和布局正确性 5. 在不同屏幕分辨率和缩放比例下测试 PMS: BUG-333243
deepin pr auto review这段代码的修改主要是为了解决 1. 语法逻辑
2. 代码质量
3. 代码性能
4. 代码安全与维护性 (重点)
改进建议
总结这段代码在功能上是有效的,能够解决当前的问题。但是,由于它严重依赖 Qt 的私有 API,存在极高的维护风险和版本兼容性风险。 建议:仅在确认当前 Qt 版本长期稳定不变,且无法通过公共 API 实现需求时使用此方案。同时,务必添加版本宏保护,并密切关注 Qt 版本升级时的代码适配工作。 |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: 18202781743, mhduiy The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
display issues
Log: Disabled menu scroll indicator in application tray to fix display
issues
Influence:
fix: 禁止托盘菜单滚动指示器功能
Log: 禁用托盘菜单滚动指示器以修复显示问题
Influence:
PMS: BUG-333243
Summary by Sourcery
Disable scroll indicators in application tray menus and adjust popup positioning for Wayland tray integration.
Bug Fixes:
Build: