Repository navigation
feat: support KWin split menus with legacy fallback - #781
Conversation
Reviewer's GuideThe titlebar now integrates with KWin split menus through optional Qt platform hooks, with native-menu state and lifecycle handling, while retaining the legacy DSplitScreenWidget fallback and preventing long-press interactions from triggering maximize. Sequence diagram for titlebar split-menu selectionsequenceDiagram
participant User
participant DTitlebar
participant PlatformHooks
participant DSplitScreenWidget
User->>DTitlebar: MouseButtonPress
DTitlebar->>DTitlebar: start(300)
DTitlebar->>DTitlebar: showSplitScreenWidget()
alt KWin hooks supported
DTitlebar->>PlatformHooks: showSplitMenu(wid, buttonRect)
PlatformHooks-->>DTitlebar: native menu shown
else legacy window manager
DTitlebar->>DSplitScreenWidget: supportSplitScreenByWM(window)
DTitlebar->>DSplitScreenWidget: show(position)
end
User->>DTitlebar: MouseButtonRelease
alt long press used native menu
DTitlebar->>DTitlebar: suppress maximize
else menu opened on release path
DTitlebar->>PlatformHooks: hideSplitMenu(wid, false)
end
Sequence diagram for split-menu dismissal and lifecycle handlingsequenceDiagram
participant User
participant DTitlebar
participant PlatformHooks
User->>DTitlebar: Mouse leaves maximize button
DTitlebar->>DTitlebar: stop()
DTitlebar->>PlatformHooks: hideSplitMenu(wid, true)
User->>DTitlebar: Disable split screen
DTitlebar->>DTitlebar: stop()
DTitlebar->>PlatformHooks: hideSplitMenu(wid, false)
DTitlebar->>DTitlebar: reset native-menu state
User->>DTitlebar: Window hidden
DTitlebar->>DTitlebar: reset local native-menu state
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 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="src/widgets/dtitlebar.cpp" line_range="1257-1261" />
<code_context>
d->hideSplitScreenWidget();
break;
}
+ case QEvent::Hide:
+ d->maxButtonPressAndHoldTimer->stop();
+ d->splitMenuByWM = false;
+ d->splitMenuWindowId = 0;
+ break;
case QEvent::MouseButtonPress: {
- d->maxButtonPressAndHoldTimer->start(300);
</code_context>
<issue_to_address>
**issue (bug_risk):** When the maximize button is hidden while the legacy `DSplitScreenWidget` is visible, the Hide handler stops the timer and clears only WM-menu state; it never calls `hideSplitScreenWidget()`, so the client-side split menu remains visible with a hidden title-bar button.
**Triggers:** When the maximize button or title bar is hidden while the legacy fallback menu is open.
**Suggested fix:** Hide the client-side split widget in the Hide handler, while retaining the WM-specific local-state reset behavior.
```suggestion
case QEvent::Hide:
d->maxButtonPressAndHoldTimer->stop();
d->hideSplitScreenWidget();
d->splitMenuByWM = false;
d->splitMenuWindowId = 0;
break;
```
</issue_to_address>| case QEvent::Hide: | ||
| d->maxButtonPressAndHoldTimer->stop(); | ||
| d->splitMenuByWM = false; | ||
| d->splitMenuWindowId = 0; | ||
| break; |
There was a problem hiding this comment.
issue (bug_risk): When the maximize button is hidden while the legacy DSplitScreenWidget is visible, the Hide handler stops the timer and clears only WM-menu state; it never calls hideSplitScreenWidget(), so the client-side split menu remains visible with a hidden title-bar button.
Triggers: When the maximize button or title bar is hidden while the legacy fallback menu is open.
Suggested fix: Hide the client-side split widget in the Hide handler, while retaining the WM-specific local-state reset behavior.
| case QEvent::Hide: | |
| d->maxButtonPressAndHoldTimer->stop(); | |
| d->splitMenuByWM = false; | |
| d->splitMenuWindowId = 0; | |
| break; | |
| case QEvent::Hide: | |
| d->maxButtonPressAndHoldTimer->stop(); | |
| d->hideSplitScreenWidget(); | |
| d->splitMenuByWM = false; | |
| d->splitMenuWindowId = 0; | |
| break; |
deepin pr auto review🤖 AI 代码审查报告📊 总体评价
🔍 详细分析1. 语法逻辑 ✅评价: 优秀 ✅ 通过 潜在问题: 建议: hideSplitScreenWidget(delay=true)时splitMenuWindowId不重置,建议添加注释说明设计意图:延迟隐藏后可能需要通过splitMenuWindowId关联后续隐藏操作 2. 代码质量 ✅评价: 良好 ✅ 通过 潜在问题: 建议: 1.为nativeWindowId()添加注释:// 获取QWidget关联的原生窗口ID,无效时返回0 3. 代码性能 ✅评价: 优秀 ✅ 通过 潜在问题: 建议: 无性能优化建议 4. 代码安全 🔒评价: 优秀 ✅ 通过
安全漏洞详情: 建议: 无安全加固建议 💡 改进建议代码示例// 建议为新增辅助函数添加注释
// 获取 QWidget 关联的原生窗口 ID,无效时返回 0
static WId nativeWindowId(const QWidget *widget)
{
if (!widget || !widget->windowHandle() || !widget->windowHandle()->handle())
return 0;
return widget->windowHandle()->winId();
}
// 通过窗管平台接口显示分屏菜单,成功返回 true
static bool showSplitMenuByWM(WId wid, const QRect &buttonRect)
{
...
}
// 通过窗管平台接口隐藏分屏菜单,delay 控制是否延迟隐藏
static void hideSplitMenuByWM(WId wid, bool delay)
{
...
}本报告由 AI 代码审查工具自动生成 |
1. Remove direct QPlatformWindow include and add platformFunction-based WM split menu integration 2. Add SUPPORTSPLITMENU, SHOWSPLITMENU, HIDESPLITMENU platform function variables 3. Introduce nativeWindowId and show/hideSplitMenuByWM helper functions 4. Track splitMenuByWM, splitMenuWindowId, and splitMenuByWMPressAndHold states in DTitlebarPrivate 5. Prioritize WM-provided split menu over client-side DSplitScreenWidget when supported 6. Fall back to legacy client-side split menu only for older window managers without support 7. Add immediate hide mode (hideImmediately) for split screen widget when delay is false 8. Guard showSplitScreenWidget against invisible/disabled max button and active WM menu 9. Handle QEvent::Hide and QEvent::Leave by stopping the press-and-hold timer and resetting WM menu state 10. Only start press-and-hold timer on left mouse button press and suppress toggle on release if WM menu was triggered 11. Stop timer and hide split menu immediately when split screen is disabled via setSplitScreenEnabled 12. Fix minor trailing whitespace formatting issues Log: Split screen menu now uses the window manager's native menu when supported, with graceful fallback for older window managers Influence: 1. Verify split menu appears via window manager on systems that support it 2. Test fallback to client-side split menu on older window managers 3. Test press-and-hold on the maximize button to trigger the menu and verify release does not toggle window state 4. Verify left-click on maximize button still toggles maximize/restore normally 5. Test QEvent::Leave and QEvent::Hide behaviors to confirm menu hides and timer stops 6. Test disabling split screen via setSplitScreenEnabled hides the menu immediately 7. Verify behavior when max button is hidden or disabled (menu should not show) 8. Confirm no regression in compositing-disabled or maximize-hint- disabled scenarios fix: 将分屏菜单委托给窗管处理 1. 移除直接包含 QPlatformWindow 头文件,改用 platformFunction 机制集成窗 管分屏菜单 2. 新增 SUPPORTSPLITMENU、SHOWSPLITMENU、HIDESPLITMENU 平台函数变量 3. 引入 nativeWindowId 及 show/hideSplitMenuByWM 辅助函数 4. 在 DTitlebarPrivate 中跟踪 splitMenuByWM、splitMenuWindowId 和 splitMenuByWMPressAndHold 状态 5. 当窗管支持时优先使用窗管提供的分屏菜单而非客户端 DSplitScreenWidget 6. 仅在不支持的老版本窗管下回退到客户端分屏菜单 7. 为分屏控件新增立即隐藏模式(hideImmediately),用于 delay 为 false 的 场景 8. 在最大按钮不可见/禁用或窗管菜单激活时跳过显示分屏控件 9. 处理 QEvent::Hide 和 QEvent::Leave,停止长按定时器并重置窗管菜单状态 10. 仅左键按下时启动长按定时器,若窗管菜单已触发则在释放时抑制窗口状态 切换 11. 通过 setSplitScreenEnabled 禁用分屏时立即停止定时器并隐藏分屏菜单 12. 修复少量行尾空白格式问题 Log: 分屏菜单在支持时改用窗管原生菜单,对老版本窗管提供优雅回退 Influence: 1. 验证在支持窗管分屏菜单的系统上菜单通过窗管弹出 2. 测试在老版本窗管上回退到客户端分屏菜单 3. 测试长按最大化按钮触发菜单,并确认释放时不会切换窗口状态 4. 验证左键单击最大化按钮仍能正常切换最大化/还原 5. 测试 QEvent::Leave 和 QEvent::Hide 行为,确认菜单隐藏且定时器停止 6. 测试通过 setSplitScreenEnabled 禁用分屏时菜单立即隐藏 7. 验证最大化按钮隐藏或禁用时菜单不显示 8. 确认在合成关闭或最大化提示禁用场景下无回归问题 PMS: BUG-370181
a96fbf6 to
a24ab62
Compare
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: 18202781743, BLumia 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 |
|
/forcemerge |
|
This pr force merged! (status: blocked) |
最大化按钮通过原有 ToolTip/300ms 长按时机请求分屏菜单;平台接口与窗管支持时使用 KWin 菜单,否则保留 DSplitScreenWidget 回退。长按后释放不触发最大化,也不主动关闭菜单;鼠标离开和功能禁用仍发送对应隐藏请求。窗口隐藏时仅重置本地状态,窗口生命周期清理由窗管负责。
平台接口直接在 dtkwidget 内调用,无需修改 dtkgui。
关联平台接口:linuxdeepin/dde-qtplatform-plugins#345
验证:实现工作目录中 Qt5/Qt6 构建通过(最多 6 个核心);使用本地构建库及模拟平台函数验证窗管菜单、离开、长按、旧窗管回退和缺失显示接口。PR 基于最新 master,差异检查通过;真实 KWin 桌面显示效果尚未实测。
Summary by Sourcery
Add native KWin split-menu support while preserving legacy split-menu behavior and improving long-press interaction handling.
New Features:
Bug Fixes:
Enhancements: