Repository navigation
feat: support KWin split menus in QML title bars - #688
Conversation
Reviewer's GuideAdds configurable KWin split-menu support to QML title bars by combining maximize-button hover/long-press interaction with direct platform-function calls, while retaining existing maximize/restore behavior on unsupported platforms and ordinary clicks. Sequence diagram for QML split-menu interactionsequenceDiagram
participant User
participant MaximizeButton
participant DQuickWindowAttached
participant Platform
alt Hover for 700ms or hold for 300ms
User->>MaximizeButton: hover or press
MaximizeButton->>DQuickWindowAttached: showSplitMenu(maxOrWindedBtn)
DQuickWindowAttached->>Platform: _d_supportSplitMenu(wid)
alt Platform supports split menu
DQuickWindowAttached->>Platform: _d_showSplitMenu(wid, rect)
Platform-->>DQuickWindowAttached: menu shown
else Unsupported or invalid window/button
DQuickWindowAttached-->>MaximizeButton: false
end
else Ordinary click
User->>MaximizeButton: click
MaximizeButton->>MaximizeButton: maxOrWinded()
end
alt Menu requested
User->>MaximizeButton: release or leave button
MaximizeButton->>DQuickWindowAttached: hideSplitMenu(delay)
DQuickWindowAttached->>Platform: _d_hideSplitMenu(wid, delay)
end
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="qt6/src/qml/WindowButtonGroup.qml" line_range="131-136" />
<code_context>
+ control.maxOrWinded()
+ __longPressed = false
+ }
+ onVisibleChanged: {
+ if (!visible) {
+ hoverTimer.stop()
+ holdTimer.stop()
+ __menuRequested = false
+ }
+ }
+ onEnabledChanged: if (!enabled) hideSplitMenu(false)
</code_context>
<issue_to_address>
**issue (bug_risk):** When the maximize button becomes invisible while a split menu is open, this handler stops the timers and clears `__menuRequested` without calling `hideSplitMenu`, so the platform menu remains visible and the client loses the state needed to hide it.
**Triggers:** When the window enters fullscreen or another state that makes `maxOrWindedBtn.visible` false after the split menu has been shown.
**Suggested fix:** Call `hideSplitMenu(false)` (or an appropriate delayed hide) before clearing the request state when the button becomes invisible, and handle window visibility changes explicitly if they do not change the button's `visible` property.
</issue_to_address>| onVisibleChanged: { | ||
| if (!visible) { | ||
| hoverTimer.stop() | ||
| holdTimer.stop() | ||
| __menuRequested = false | ||
| } |
There was a problem hiding this comment.
issue (bug_risk): When the maximize button becomes invisible while a split menu is open, this handler stops the timers and clears __menuRequested without calling hideSplitMenu, so the platform menu remains visible and the client loses the state needed to hide it.
Triggers: When the window enters fullscreen or another state that makes maxOrWindedBtn.visible false after the split menu has been shown.
Suggested fix: Call hideSplitMenu(false) (or an appropriate delayed hide) before clearing the request state when the button becomes invisible, and handle window visibility changes explicitly if they do not change the button's visible property.
f17e312 to
4dbe183
Compare
1. Add splitScreenEnabled property to TitleBar and WindowButtonGroup components 2. Implement showSplitMenu and hideSplitMenu methods in DQuickWindowAttached 3. Add platform function bindings for _d_supportSplitMenu, _d_showSplitMenu, and _d_hideSplitMenu 4. Add hover timer (700ms) and hold timer (300ms) to trigger split menu on maximize button 5. Track splitMenuWindowId in DQuickWindowPrivate to manage menu state 6. Handle menu lifecycle on hover, press, release, cancel, visibility and enabled changes 7. Map button geometry to global coordinates for menu positioning Log: Added split screen menu triggered by hovering or long-pressing the maximize button Influence: 1. Test hovering over maximize button for 700ms to show split screen menu 2. Test long-pressing maximize button for 300ms to trigger split menu 3. Verify normal click behavior on maximize button still works when not long-pressed 4. Test menu hides on mouse leave and when splitScreenEnabled is set to false 5. Verify split menu only appears when platform supports _d_supportSplitMenu 6. Test split menu positioning aligns with the maximize button location 7. Verify menu interaction works correctly in embed mode and fullscreen scenarios 8. Test behavior when window is not visible or button is disabled feat: 为标题栏添加分屏菜单 1. 在 TitleBar 和 WindowButtonGroup 组件中添加 splitScreenEnabled 属性 2. 在 DQuickWindowAttached 中实现 showSplitMenu 和 hideSplitMenu 方法 3. 添加 _d_supportSplitMenu、_d_showSplitMenu 和 _d_hideSplitMenu 平台函 数绑定 4. 为最大化按钮添加悬停定时器(700ms)和长按定时器(300ms)以触发分屏 菜单 5. 在 DQuickWindowPrivate 中跟踪 splitMenuWindowId 以管理菜单状态 6. 在悬停、按下、释放、取消、可见性和启用状态变化时处理菜单生命周期 7. 将按钮几何位置映射到全局坐标以定位菜单 Log: 新增通过悬停或长按最大化按钮触发的分屏菜单 Influence: 1. 测试悬停最大化按钮 700ms 后显示分屏菜单 2. 测试长按最大化按钮 300ms 触发分屏菜单 3. 验证非长按时最大化按钮的正常点击行为仍然有效 4. 测试鼠标离开和 splitScreenEnabled 设为 false 时菜单隐藏 5. 验证仅在平台支持 _d_supportSplitMenu 时才显示分屏菜单 6. 测试分屏菜单位置是否与最大化按钮位置对齐 7. 验证嵌入模式和全屏场景下菜单交互正常 8. 测试窗口不可见或按钮禁用时的行为 PMS: BUG-370181
4dbe183 to
f0b0885
Compare
deepin pr auto review🤖 AI 代码审查报告📊 总体评价
🔍 详细分析1. 语法逻辑 ✅评价: 优秀 ✅ 通过 潜在问题: 建议: 代码语法正确,逻辑清晰。状态管理(__longPressed、__menuRequested)设计合理,定时器交互协调良好,边界条件处理完善(按钮不可见、不可用、平台不支持等情况均有处理)。showSplitMenu 中 __menuRequested 标志有效防止重复调用平台函数,hideSplitMenu 在延迟模式下保留 splitMenuWindowId 以支持后续关闭操作。 2. 代码质量 ✅评价: 优秀 ✅ 通过 潜在问题:
建议: 建议为 QML 新增函数添加文档注释,说明函数用途和参数含义。定时器间隔可提取为属性常量以提高可维护性。C++ 代码注释良好,命名规范符合 Qt 风格。 3. 代码性能 ✅评价: 优秀 ✅ 通过 潜在问题: 建议: 性能良好,基于定时器的方案高效无轮询。__menuRequested 标志有效防止重复平台函数调用,各函数中提前返回减少了不必要的计算。平台函数通过局部变量缓存避免重复查询。 4. 代码安全 🔒评价: 优秀 ✅ 通过
安全漏洞详情: 建议: 代码安全合规,无安全漏洞。reinterpret_cast 平台函数模式是 Qt 标准用法,平台函数由平台插件注册而非用户输入控制。所有输入来自 Qt 内部事件系统,无注入攻击面。splitMenuWindowId 为内部标识符,非用户可控。 💡 改进建议代码示例// 建议为 QML 函数添加文档注释
/**
* 显示分屏菜单
* 当 splitScreenEnabled 为 true 且按钮可见、可用时,
* 通过平台函数显示分屏菜单
* @returns {bool} 菜单是否成功显示
*/
function showSplitMenu() {
if (!control.splitScreenEnabled || !visible || !enabled)
return false
if (!__menuRequested)
__menuRequested = control.__dwindow.showSplitMenu(maxOrWindedBtn)
return __menuRequested
}
// 建议提取定时器间隔为常量
property int hoverDelay: 700 // 悬停触发延迟(ms)
property int holdDelay: 300 // 长按触发延迟(ms)本报告由 AI 代码审查工具自动生成 |
|
[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 |
为 QML TitleBar/WindowButtonGroup 增加 splitScreenEnabled,并在最大化按钮悬停或长按时请求 KWin 分屏菜单。普通点击保持最大化/还原行为;长按成功后释放不触发最大化;不支持平台接口时正常点击行为不受影响。
DQuickWindowAttached 直接封装平台函数调用,不经过 dtkgui。客户端处理按钮交互和功能禁用时的收起请求,窗口关闭/消失后的菜单清理由窗管负责。
关联平台接口:linuxdeepin/dde-qtplatform-plugins#345
验证:实现工作目录中 Qt5/Qt6 构建通过(最多 6 个核心);QML 无界面测试 8 项通过(包含初始化/清理,覆盖普通点击、长按、悬停离开、功能禁用及不支持的平台)。PR 基于最新 master,差异检查通过;真实 KWin 桌面显示效果尚未实测。
Summary by Sourcery
Enable KWin split-screen menus from QML title-bar maximize buttons without disrupting existing window-state controls.
New Features:
Bug Fixes:
Enhancements: