Skip to content

chore: merge master into v25-flowstyle - #727

Merged
BLumia merged 20 commits into
linuxdeepin:v25-flowstylefrom
18202781743:sync/master-into-v25-flowstyle
Oct 20, 2026
Merged

BLumia merged 20 commits into
linuxdeepin:v25-flowstylefrom
18202781743:sync/master-into-v25-flowstyle

Conversation

@18202781743

@18202781743 18202781743 commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

将官方 master(43251192,6.7.51)合并到 v25-flowstyle(71d92b38),使功能分支获得最新修复,并保留 master 的提交祖先关系,便于后续持续同步和回合。

冲突处理:发布记录与版本信息采用 master;ArrowListView 采用 master 的弹窗预测量与固定箭头高度修复;MenuItem 保留 flowstyle 的独立箭头尺寸和 arrow_ordinary_right 图标,同时保留 smooth 绑定。ComboBox 的 flowstyle 背景与配色继续保留。提交时,本机版权 hook 自动将 PasswordEdit.qml 的版权年份更新到 2026。

验证

  • Qt 5、Qt 6 Debug 全量构建通过,均使用 -j6。
  • Qt 5、Qt 6 各 99 项 QML 加载测试通过;Qt 6 CTest 1/1 通过。
  • Qt 6 offscreen 专项检查通过:ComboBox 的 0、1、10、30 项模型在打开前后高度一致,滚动阈值正确;子菜单箭头保持 16×16 的 flowstyle 图标。
  • 全量单测未通过:offscreen 下出现 ColorSelector 断言失败及 AppLoader 崩溃;在未合并的 v25-flowstyle(71d92b38)重新构建并运行,复现相同问题。ThemeMenu 单测失败也在该基线复现。QML 加载测试仍有运行时告警;上述验证不替代真实桌面下的视觉验收与平台分屏菜单验证。

合并方式

此 PR 包含真正的双亲 merge commit,第二父提交为 master 4325119。请保留该提交历史,勿使用 Squash and merge 或 Rebase and merge。

当前仓库设置 mergeCommitAllowed=false。维护者需要启用 Create a merge commit,或在审查通过后将该 merge commit 以普通快进推送方式纳入 v25-flowstyle;如目标分支有新提交,应先合并最新目标分支再推送,避免覆盖他人修改。仅 squash 此 PR 无法达到本次保留 master 祖先关系的目的。

Summary by Sourcery

Merge the latest master fixes and release updates into v25-flowstyle while preserving the master ancestor and flowstyle-specific behavior.

New Features:

  • Add platform-integrated split-screen menus to title-bar maximize buttons, supporting hover and long-press activation.
  • Add Mongolian translations for common declarative UI actions, dialogs, text-edit commands, and theme settings.

Bug Fixes:

  • Fix popup sizing before mapping and stabilize ArrowListView measurements, including consistent navigation-arrow heights.
  • Correct ThemeMenu signal handling and update release metadata to version 6.7.51.

Enhancements:

  • Synchronize the branch with the 6.7.50 and 6.7.51 master release changes while preserving the master history.

Tests:

  • Verify Qt 5 and Qt 6 debug builds and QML loading tests; document known offscreen unit-test failures reproduced on the pre-merge baseline.

Chores:

  • Update package metadata and copyright years to the 2026 release period.

kt286 and others added 20 commits August 21, 2026 15:37
Separate install destinations for LIBRARY, ARCHIVE and RUNTIME to ensure
DLL files are installed to the bin directory on Windows instead of lib.

fix: Windows 平台 DLL 安装到 bin 目录

分离 LIBRARY、ARCHIVE 和 RUNTIME 的安装路径,确保 Windows 平台的 DLL
文件安装到 bin 目录而非 lib 目录。
…in#669)

* i18n: Translate dtkdeclarative.ts in pt

71% of minimum 10% translated source file: 'dtkdeclarative.ts'
on 'pt'.

Sync of partially translated files: 
untranslated content is included with an empty translation 
or source language content depending on file format

* i18n: Translate dtkdeclarative.ts in ar

100% translated source file: 'dtkdeclarative.ts'
on 'ar'.

---------

Log:
1. Cancel the highlight panel's horizontal padding with a negative label
   margin so tick text stays anchored to its tick line
2. Resolve the first and last tick in TipsSlider and derive
   textHorizontalAlignment from them, so end labels align inward by default
3. Reach the owning TipsSlider through a single property instead of
   indexing parent.parent.children, which depended on declaration order
4. Drop the now-redundant explicit alignment from the example and docs

Log: Tick labels no longer overflow either end of a horizontal slider
Influence: Edge tick labels stay inside the slider bounds

fix(slider): 修正刻度标签超出滑块范围的问题

1. 用负 margin 抵消高亮面板的水平内边距,使刻度文本紧贴其刻度线
2. 由 TipsSlider 解析首/末刻度并据此推导 textHorizontalAlignment,
   两端标签默认向内对齐,使用方无需逐个显式设置
3. 通过单个属性获取所属的 TipsSlider,不再按 parent.parent.children
   下标取值,摆脱对声明顺序的依赖
4. 移除示例和文档中因此变得冗余的显式对齐写法

Log: 水平滑块两端的刻度标签不再越出滑块范围
PMS: BUG-305223
Influence: 两端刻度标签保持在滑块范围内
Change-Id: I53dd9644c718df841e8ca0527f92abafc735f168
…pping

1. Show arrow buttons constantly when interactive, grey them out via
   internal enabled instead of hiding them, so layout height stays fixed
2. Size the viewport by real item height (contentHeight / count) rather
   than the static style itemHeight, so the last visible item is not clipped
3. Simplify the interactive condition to model.count vs maxVisibleItems
4. Use implicitHeight for the button layout preferred height

Log: Fix ArrowListView height fluctuating while scrolling and the
last item being clipped when actual item height differs from itemHeight
Influence: Lists in menus and ComboBoxes no longer resize during scroll

fix(arrowlistview): 修复 ArrowListView 滚动时高度振荡与末项被裁剪

1. 箭头按钮改为占用布局后通过内部 enabled 置灰,避免隐藏按钮改变高度
2. 视口改用真实项高(contentHeight/count)计算,替换静态 itemHeight,
   使最后一个可见项不被裁剪
3. interactive 改用 count 与 maxVisibleItems 比较
4. 按钮布局期望高度改用 implicitHeight

Log: 修复列表滚动时高度抖动以及实际项高与 itemHeight 不一致时末项被裁剪
PMS: BUG-375249
Influence: 菜单/下拉列表滚动时不再跳动,末项完整显示
Change-Id: I09a7ef250f82eebf20784336301d24789cad99e6
1. Add NoArrowType case to getIconNameByType in SliderHandle.qml (qt6)
2. NoArrowType falls through to default returning empty string
3. Default branch covers future enum values with empty-string return
4. Empty name avoids undefined being assigned to DciIcon.name (QString)
5. Empty name matches C++ name.isEmpty() sentinel to skip DCI drawing
6. Only the Qt6 path is changed; Qt5 Slider.qml has no NoArrowType enum
7. Update SPDX-FileCopyrightText year range to 2022 - 2026

Influence:
1. Open control-center Sound page; no undefined-to-QString warning
2. Verify microphone input-level slider renders with no residual icon
3. Confirm existing handleTypes (Arrow/NoArrowH/NoArrowV) unchanged

fix(slider): 在 SliderHandle 中补充 NoArrowType 分支

1. 在 qt6 SliderHandle.qml 的 getIconNameByType 中补充 NoArrowType 分支
2. NoArrowType fall-through 到 default 分支,共享一个空串返回
3. default 分支返回空串,覆盖未来新增枚举值
4. 空串避免 undefined 赋给 DciIcon.name 的 QString
5. 空串与 C++ 侧 name.isEmpty() 跳过 DCI 绘制的哨兵判定保持一致
6. 仅改动 Qt6 路径;Qt5 的 Slider.qml 不存在 NoArrowType 枚举
7. 更新 SPDX-FileCopyrightText 年份范围为 2022 - 2026

Influence:
1. 打开控制中心-声音页,确认不再出现 undefined-to-QString 告警
2. 验证麦克风输入等级反馈滑块渲染正常、无残留图标
3. 确认其他 handleType(Arrow/NoArrowHorizontal/NoArrowVertical)行为不变

PMS: Task-392413
The slot receives winId as quint32 (eventFilter and the DWindowManagerHelper
windowMotifWMHintsChanged signal both deliver it truncated to 32 bits), but the
identity guard compared it against the full-width WId from QWindow::winId().
On X11 WId is a 32-bit XID so it worked; on Wayland/Qt6.11 WId is a 64-bit
pointer (>4GiB), so the guard is always true and the slot returns before
fetching Motif functions, leaving motifFunctions at 0 and disabling the
minimize/close buttons on DTK client titlebars (e.g. dde-control-center).
Remove the scale-based setSmooth(false) overrides in DQuickDciIconImage
so icons fall back to the default smooth=true filtering, eliminating
jaggies when the scene is downsampled to lower-DPI outputs. Forward
IconLabel's smooth to its internal image.

移除DQuickDciIconImage中基于scale的smooth强制覆盖,恢复默认平滑过滤,
修复混合DPI下场景降采样导致的图标锯齿。IconLabel的smooth转发到内部图像。

Log: 修复混合DPI下图标锯齿,恢复DciIcon平滑渲染
Influence: 所有使用DciIcon/IconLabel的控件在混合DPI下图标平滑渲染;外部可通过smooth属性控制图标过滤。
Bind smooth: control.smooth on every direct DciIcon used by controls,
covering indicator/arrow/handle icons (CheckDelegate, ItemDelegate,
MenuItem, CheckBox, RadioButton, Switch, ComboBox, ButtonIndicator,
SpinBoxIndicator, SliderHandle, ActionButton, IconButton, WindowButton,
DialogTitleBar, TitleBar, SearchEdit) so controls consistently honor
their public smooth property. IconLabel.smooth already forwards to the
internal image.

在所有控件直接使用的DciIcon(指示器/箭头/手柄图标)上绑定
smooth: control.smooth,使控件一致响应公开的smooth属性,修复
control.smooth为false时指示器/箭头仍保持平滑过滤的问题。

Log: 补全控件直接DciIcon的smooth绑定,修复smooth属性不一致
Influence: 所有使用DciIcon指示器/箭头的控件现在能通过control.smooth一致控制图标过滤;混合DPI下图标平滑渲染行为不变。
100% translated source file: 'dtkdeclarative.ts'
on 'sv'.

Log:
After commit cba9773 removed the background Item's implicitWidth binding
to break a binding loop, Popup's implicitWidth started tracking
contentImplicitWidth directly. When popupType is Popup.Window,
QQuickPopupWindow::implicitWidthChanged() unconditionally adopts
popup->implicitWidth(), so search filtering that shrinks the content
causes the popup window to jump to a smaller width.

Instead of overriding implicitWidth/Height directly or using a ratchet
mechanism, give StyledBehindWindowBlur (the Window popupType background)
a fixed default implicit size — DS.Style.popup.width/height — matching
the approach already used by FloatingPanel for the non-Window popupType.
This provides a size floor so content shrinking no longer jumps the
popup window smaller, while still allowing growth when content is
larger. No binding loop because the values are constants.

修复 Popup 在 Window popupType 下宽度跳变问题

commit cba9773 移除 background Item 的 implicitWidth 绑定以消除绑定环后,
Popup 的 implicitWidth 直接随 contentImplicitWidth 变化。当 popupType 为
Popup.Window 时,QQuickPopupWindow::implicitWidthChanged() 无条件采用
popup->implicitWidth(),搜索过滤导致内容减少时窗口宽度跳变。

不再直接覆盖 implicitWidth/Height 或使用棘轮机制,而是给
StyledBehindWindowBlur(Window popupType 的 background)设置固定默认隐式尺寸
—— DS.Style.popup.width/height —— 与 FloatingPanel(非 Window popupType)的
做法一致。这提供了尺寸下限,内容缩减时 popup 不再跳变到极小,内容更大时仍可
增长。值为常量,无绑定环。

PMS: BUG-373823、BUG-373843
Bind implicitWidth/implicitHeight to
DS.Style.control.implicitWidth/implicitHeight(control), sizing the
popup to the maximum of the background implicit size and the content
size (plus padding and insets), consistent with the qt5 Popup.

commit cba9773 removed the background Item that carried these bindings
to break a binding loop, after which Popup tracked contentImplicitWidth
only; commit db82f88 then gave the background a fixed default implicit
size (DS.Style.popup.width/height). Since the background implicit size
is now a constant, binding the popup's implicit size to
DS.Style.control.implicitWidth/Height no longer forms a loop: the
background default acts as a size floor, so with popupType Window,
content shrinking no longer makes the popup window jump to a smaller
size, while content larger than the default still grows it.

fix(popup): 恢复 qt6 下 Popup 的隐式尺寸绑定

将 implicitWidth/implicitHeight 绑定到
DS.Style.control.implicitWidth/implicitHeight(control),取 background
隐式尺寸与内容尺寸(加上 padding/insets)的最大值作为 Popup 的隐式尺寸,
与 qt5 版 Popup 保持一致。

commit cba9773 为消除绑定环移除了承载该绑定的 background Item,此后
Popup 仅随 contentImplicitWidth 变化;commit db82f88 随后为 background
设置了固定默认隐式尺寸(DS.Style.popup.width/height)。由于 background
隐式尺寸已是常量,将 Popup 隐式尺寸绑定到
DS.Style.control.implicitWidth/Height 不再形成绑定环:background 默认
值充当尺寸下限,popupType 为 Window 时内容缩减不再使 popup 窗口跳变
变小,内容更大时仍可增长。

PMS: BUG-373823、BUG-373843
1. Change interactive property binding from model.count to
itemsView.count
2. The ListView is assigned id itemsView, so model is not a valid
reference
3. This fixes the interactive property to correctly enable scrolling
when items exceed maxVisibleItems
4. Without this fix, the interactive property would fail to bind
correctly, potentially disabling scroll interaction

Influence:
1. Test ArrowListView with item count exceeding maxVisibleItems to
verify scrolling works
2. Test ArrowListView with item count equal to or less than
maxVisibleItems to verify scrolling is disabled
3. Verify the list view displays and scrolls correctly with various
item counts
4. Test keyboard and mouse wheel navigation within the list

fix: 修正 ArrowListView 中的模型引用

1. 将 interactive 属性绑定从 model.count 改为 itemsView.count
2. ListView 的 id 为 itemsView,因此 model 不是有效的引用
3. 修复了 interactive 属性,使其在项目数超过 maxVisibleItems 时正确启用
滚动
4. 如果不修复,interactive 属性将无法正确绑定,可能导致滚动交互被禁用

Influence:
1. 测试项目数超过 maxVisibleItems 时的 ArrowListView 滚动功能
2. 测试项目数等于或少于 maxVisibleItems 时滚动是否被禁用
3. 验证列表视图在不同项目数量下的显示和滚动是否正常
4. 测试列表中的键盘和鼠标滚轮导航

PMS: BUG-388693
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
1. Change onTriggered to function(action) syntax in qt6/src/qml/ThemeMenu.qml
2. Fix Qt6 deprecation warning about implicit signal parameter injection
3. Keep consistent with other signal handlers in the repository
4. Update SPDX copyright year to 2026

Influence:
1. Test theme switching (Light/Dark/System) in dde-control-center
2. Verify no deprecation warning in console output
3. Confirm Qt5 build is unaffected by the change

fix: 修复 ThemeMenu 信号处理器参数注入弃用警告

1. 修改 qt6/src/qml/ThemeMenu.qml 中 onTriggered 为 function(action) 语法
2. 修复 Qt6 关于信号参数隐式注入的弃用警告
3. 与仓库中其他信号处理器保持风格一致
4. 更新 SPDX 版权年份至 2026

Influence:
1. 在控制中心测试主题切换(浅色/深色/跟随系统)
2. 验证控制台不再输出弃用警告
3. 确认 Qt5 构建不受此改动影响

PMS: TASK-392413
Log:

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1. Size the window popup from the model and the measured delegate height, instead of
   the content item, which has not been laid out yet when the window is created.
2. Measure the delegate height in ArrowListView by realizing one item while the popup
   is still closed, and pin the scroll-arrow height so the layout settles in one pass.
3. Keep the style item height only as the viewport that makes that first measurement
   possible.

Log: ComboBox popups appear at their final size instead of being resized after being mapped.
Influence: Removes the popup size jump with Window popup type.

fix(ComboBox): 弹窗按最终尺寸显示

1. 窗口弹窗改用模型与实测行高计算尺寸,不再使用尚未布局的内容项。
2. ArrowListView 在弹窗关闭时提前实例化一项以量出行高,并固定箭头条高度,使布局一次到位。
3. 样式行高仅作为首次测量所需的引导视口。

Log: 下拉弹窗显示时即为其最终尺寸,不再在显示后改变尺寸。
PMS: BUG-370839
Influence: 修复 Window 类型弹窗的尺寸跳动。
100% translated source file: 'dtkdeclarative.ts'
on 'mn'.

Multica: DDE-437
Log:
1. Add split screen menu to title bar window buttons: hovering or long-
pressing the maximize button after a delay requests a platform-provided
split menu
2. Implement DQuickWindowAttached::showSplitMenu and hideSplitMenu
using platform functions (_d_supportSplitMenu, _d_showSplitMenu,
_d_hideSplitMenu) and track splitMenuWindowId
3. Add splitScreenEnabled property to TitleBar and WindowButtonGroup and
propagate it
4. Add sizedHeight readonly property to ArrowListView to compute full
list height before mapping
5. Size ComboBox popup via implicitHeight before it is mapped so the
list can realize a row and be measured
6. Fix step button heights to use stepButtonIconSize.height and force
layout when height changes with empty content
7. Fix ThemeMenu signal handler to use formal parameter
8. Add Mongolian translation file dtkdeclarative_mn.ts
9. Bump version to 6.7.51 and update CHANGELOG, PKGBUILD, and debian
changelog

Log: Added split screen menu on the window maximize button; fixed popup
sizing for ComboBox and ArrowListView; added Mongolian translations

Influence:
1. Verify hovering the maximize button shows the split menu after the
delay and hides it when the mouse leaves
2. Test long-press on the maximize button opens the split menu and
single click still maximizes/restores the window
3. Confirm split menu is hidden when splitScreenEnabled is false or the
button is disabled/hidden
4. Test on platforms without split menu support that no menu appears and
behavior degrades gracefully
5. Verify ComboBox popup sizes correctly before mapping, including with
few and many items
6. Test ArrowListView scrolling, step buttons, and popup height with
varying item counts
7. Check the Theme menu applies palette changes correctly when triggered
8. Verify Mongolian translations display correctly in the UI

feat: 添加分屏菜单并修复弹窗尺寸

1. 在标题栏窗口按钮添加分屏菜单:悬停或长按最大化按钮延时后请求平台提供
的分屏菜单
2. 实现 DQuickWindowAttached::showSplitMenu 和 hideSplitMenu,使用平
台函数(_d_supportSplitMenu、_d_showSplitMenu、_d_hideSplitMenu)并记
录 splitMenuWindowId
3. 为 TitleBar 和 WindowButtonGroup 添加 splitScreenEnabled 属性并向下
传递
4. 为 ArrowListView 添加 sizedHeight 只读属性,在映射前计算列表完整高度
5. 通过 implicitHeight 在映射前设置 ComboBox 弹窗尺寸,使列表能实例化一
行并进行测量
6. 修复步进按钮高度改用 stepButtonIconSize.height,并在高度变化且内容为
空时强制布局
7. 修复 ThemeMenu 信号处理函数使用形参
8. 添加蒙古语翻译文件 dtkdeclarative_mn.ts
9. 版本升级至 6.7.51 并更新 CHANGELOG、PKGBUILD 和 debian changelog

Log: 新增窗口最大化按钮的分屏菜单;修复 ComboBox 和 ArrowListView 的弹窗
尺寸;新增蒙古语翻译

Influence:
1. 验证悬停最大化按钮在延时后显示分屏菜单,移出后隐藏
2. 测试长按最大化按钮打开分屏菜单,单击仍可最大化/还原窗口
3. 确认 splitScreenEnabled 为 false 或按钮被禁用/隐藏时分屏菜单隐藏
4. 在不支持分屏菜单的平台上测试不显示菜单且行为优雅降级
5. 验证 ComboBox 弹窗在映射前尺寸正确,包括少量和大量条目
6. 测试 ArrowListView 滚动、步进按钮以及不同条目数量下的弹窗高度
7. 检查主题菜单触发后能正确应用调色板变更
8. 验证蒙古语翻译在界面中正确显示
@18202781743
18202781743 requested review from BLumia and mhduiy October 20, 2026 03:54
@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

TAG Bot

TAG: 6.7.51
EXISTED: yes
DISTRIBUTION: unstable

@sourcery-ai

sourcery-ai Bot commented Oct 20, 2026

Copy link
Copy Markdown

Reviewer's Guide

This PR merges master 6.7.51 into v25-flowstyle, carrying forward release metadata, translations, ArrowListView popup sizing fixes, and flowstyle-specific visual behavior, while adding platform-backed split-screen menus to the title-bar maximize button. Review should focus on popup measurement and interaction edge cases, platform-function integration, and preserving the required merge ancestry; the stated build and QML-load validations pass, while several unit-test failures are reproduced from the baseline.

Sequence diagram for the title-bar split-screen menu interaction

sequenceDiagram
    actor User
    participant WindowButtonGroup
    participant DQuickWindowAttached
    participant Platform

    User->>WindowButtonGroup: hover or press maxOrWindedBtn
    WindowButtonGroup->>WindowButtonGroup: showSplitMenu()
    WindowButtonGroup->>DQuickWindowAttached: showSplitMenu(button)
    DQuickWindowAttached->>Platform: _d_supportSplitMenu(wid)
    Platform-->>DQuickWindowAttached: supported
    DQuickWindowAttached->>Platform: _d_showSplitMenu(wid, rect)
    Platform-->>WindowButtonGroup: split menu shown
    User->>WindowButtonGroup: release or leave button
    WindowButtonGroup->>DQuickWindowAttached: hideSplitMenu(delay)
    DQuickWindowAttached->>Platform: _d_hideSplitMenu(wid, delay)
Loading

Flow diagram for popup height measurement

flowchart TD
    ComboBox --> ArrowListView
    ArrowListView --> sizedHeight[sizedHeight]
    sizedHeight --> contentHeight[Measure realized item and arrow strips]
    contentHeight --> PopupHeight[ComboBox popup implicitHeight]
    PopupHeight --> MappedPopup[Popup mapped at measured height]
Loading

File-Level Changes

Change Details Files
Merges the official 6.7.51 master history and release metadata into the flowstyle branch while preserving the flowstyle-specific styling behavior.
  • Updates version, changelog, and packaging metadata to 6.7.51.
  • Adds the Mongolian translation catalog and updates the ThemeMenu signal handler for explicit Qt 6 parameters.
  • Keeps flowstyle ComboBox appearance and MenuItem arrow behavior while incorporating master’s ArrowListView sizing and fixed arrow-strip heights.
  • Refreshes affected QML copyright years.
CHANGELOG.md
VERSION
archlinux/PKGBUILD
debian/changelog
src/translations/dtkdeclarative_mn.ts
qt6/src/qml/ThemeMenu.qml
qt6/src/qml/PasswordEdit.qml
qt6/src/qml/ArrowListView.qml
qt6/src/qml/ComboBox.qml
Adds split-screen menu support to the title-bar maximize control through QML interaction state and platform hooks.
  • Propagates a splitScreenEnabled option from TitleBar to WindowButtonGroup.
  • Shows the platform split menu after hover or long press, and preserves normal maximize behavior for ordinary clicks.
  • Cleans up timers and menu state on release, cancellation, visibility, enablement, and feature disablement.
  • Exposes native show/hide methods that validate the window and button, resolve global button geometry, call platform functions, and track the menu window ID.
qt6/src/qml/TitleBar.qml
qt6/src/qml/WindowButtonGroup.qml
src/dquickwindow.cpp
src/dquickwindow.h
src/private/dquickwindow_p.h
Documents validation results and merge-history requirements for integrating the two branches.
  • Records successful Qt 5/Qt 6 builds and QML loading checks, plus targeted offscreen ComboBox and submenu-arrow checks.
  • Identifies pre-existing offscreen unit-test failures and remaining desktop visual/platform-menu validation needs.
  • Requires retaining the two-parent merge commit rather than squashing or rebasing, with care when incorporating newer target-branch commits.
Pull request metadata

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 3 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="qt6/src/qml/ComboBox.qml" line_range="198-199" />
<code_context>
         palette: control.palette
         implicitWidth: control.flat ? Math.max(contentItem.implicitWidth, control.width) : control.width
+        // 60 is a temporary viewport so the list can realize one row and be measured.
+        implicitHeight: (contentItem.sizedHeight > 0 ? contentItem.sizedHeight : 2 * DS.Style.arrowListView.itemHeight)
+                        + topPadding + bottomPadding
         onClosed: control.isInteractingWithContent = false
         Connections {
</code_context>
<issue_to_address>
**Empty models show blank popups**

When the ComboBox model is empty and its popup is opened, including while the model is loading, `contentItem.sizedHeight` is zero, so the two-row fallback gives the popup a nonzero height and it displays a blank panel.

Return zero popup content height for an empty model rather than applying the two-row fallback.
</issue_to_address>

### Comment 2
<location path="qt6/src/qml/ArrowListView.qml" line_range="23" />
<code_context>
+        if (itemsView.count === 0)
+            return 0
+        const item = itemsView.itemAtIndex(0)
+        const measured = itemsView.contentHeight > 0 && item ? (item.height || item.implicitHeight) : 0
+        const arrowStrips = itemsView.count > maxVisibleItems
+                ? 2 * (DS.Style.arrowListView.stepButtonIconSize.height + contentLayout.spacing) : 0
</code_context>
<issue_to_address>
**Variable-height rows mis-size popups**

When a ComboBox uses delegates with different heights, or index 0 is not realized while custom-height delegates are in use, `sizedHeight` uses one realized row's height for every visible row and falls back to `itemHeight` when index 0 is not realized, so the popup height is inaccurate and clips rows or leaves excess space.

Calculate the total height of the visible rows, or otherwise account for each delegate's height and unrealized rows.

Also at `qt6/src/qml/ArrowListView.qml:26-27`.
</issue_to_address>

### Comment 3
<location path="qt6/src/qml/ArrowListView.qml" line_range="28" />
<code_context>
             visible: itemsView.interactive
             Layout.alignment: Qt.AlignHCenter
             Layout.fillWidth: true
-            Layout.preferredHeight: implicitHeight
+            Layout.preferredHeight: DS.Style.arrowListView.stepButtonIconSize.height
             view: itemsView
</code_context>
<issue_to_address>
**Long-list popup clips arrow buttons**

When a list has more items than `maxVisibleItems` and both arrow buttons are shown, the layout and `sizedHeight` reserve 12 px per arrow, but the loaded `ActionButton` remains 16 px tall; the popup is 8 px too short when both arrows are shown, so the buttons overlap or are clipped.

Use the button’s actual `stepButtonSize.height` consistently for the layout reservation and popup-height calculation, or size the loaded button to the reserved height.

Also at `qt6/src/qml/ArrowListView.qml:26`.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread qt6/src/qml/ComboBox.qml
Comment on lines +198 to +199
implicitHeight: (contentItem.sizedHeight > 0 ? contentItem.sizedHeight : 2 * DS.Style.arrowListView.itemHeight)
+ topPadding + bottomPadding

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium · Empty models show blank popups

When the ComboBox model is empty and its popup is opened, including while the model is loading, contentItem.sizedHeight is zero, so the two-row fallback gives the popup a nonzero height and it displays a blank panel.

Return zero popup content height for an empty model rather than applying the two-row fallback.

Prompt for AI agents
In `qt6/src/qml/ComboBox.qml` at lines 198-199:

**Empty models show blank popups**

When the ComboBox model is empty and its popup is opened, including while the model is loading, `contentItem.sizedHeight` is zero, so the two-row fallback gives the popup a nonzero height and it displays a blank panel.

Return zero popup content height for an empty model rather than applying the two-row fallback.

if (itemsView.count === 0)
return 0
const item = itemsView.itemAtIndex(0)
const measured = itemsView.contentHeight > 0 && item ? (item.height || item.implicitHeight) : 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium · Variable-height rows mis-size popups

When a ComboBox uses delegates with different heights, or index 0 is not realized while custom-height delegates are in use, sizedHeight uses one realized row's height for every visible row and falls back to itemHeight when index 0 is not realized, so the popup height is inaccurate and clips rows or leaves excess space.

Calculate the total height of the visible rows, or otherwise account for each delegate's height and unrealized rows.

Also at qt6/src/qml/ArrowListView.qml:26-27.

Prompt for AI agents
In `qt6/src/qml/ArrowListView.qml` at line 23:

**Variable-height rows mis-size popups**

When a ComboBox uses delegates with different heights, or index 0 is not realized while custom-height delegates are in use, `sizedHeight` uses one realized row's height for every visible row and falls back to `itemHeight` when index 0 is not realized, so the popup height is inaccurate and clips rows or leaves excess space.

Calculate the total height of the visible rows, or otherwise account for each delegate's height and unrealized rows.

Also at `qt6/src/qml/ArrowListView.qml:26-27`.

visible: itemsView.interactive
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
Layout.preferredHeight: implicitHeight

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium · Long-list popup clips arrow buttons

When a list has more items than maxVisibleItems and both arrow buttons are shown, the layout and sizedHeight reserve 12 px per arrow, but the loaded ActionButton remains 16 px tall; the popup is 8 px too short when both arrows are shown, so the buttons overlap or are clipped.

Use the button’s actual stepButtonSize.height consistently for the layout reservation and popup-height calculation, or size the loaded button to the reserved height.

Also at qt6/src/qml/ArrowListView.qml:26.

Prompt for AI agents
In `qt6/src/qml/ArrowListView.qml` at line 28:

**Long-list popup clips arrow buttons**

When a list has more items than `maxVisibleItems` and both arrow buttons are shown, the layout and `sizedHeight` reserve 12 px per arrow, but the loaded `ActionButton` remains 16 px tall; the popup is 8 px too short when both arrows are shown, so the buttons overlap or are clipped.

Use the button’s actual `stepButtonSize.height` consistently for the layout reservation and popup-height calculation, or size the loaded button to the reserved height.

Also at `qt6/src/qml/ArrowListView.qml:26`.

@deepin-ci-robot

Copy link
Copy Markdown
Contributor

deepin pr auto review

AI 代码审查报告

项目: linuxdeepin/dtkdeclarative
PR: #727
标题: chore: merge master into v25-flowstyle
分支: sync/master-into-v25-flowstyle → v25-flowstyle
分析模式: 全量分析(GitHub PR)
审查时间: 2026-10-20


总体评价

维度 得分 状态
语法逻辑 25/25 ✓
代码质量 23/25 ✓
代码性能 20/20 ✓
代码安全 30/30 ✓
总分 98/100 优秀

总体评价: 代码审查通过。本次 PR 是将 master 分支合并到 v25-flowstyle,包含分屏菜单功能、ComboBox 弹窗尺寸修复、ArrowListView 模型引用修正、ThemeMenu 信号处理器修复以及蒙古语翻译等多项变更。代码逻辑清晰,安全无漏洞,仅有一处注释与代码不匹配的小问题。


漏洞统计

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个

漏洞等级 数量
严重 (Critical) 0
高危 (High) 0
中危 (Medium) 0
低危 (Low) 0
总计 0

维度1:语法逻辑(25/25)✓

评价词: 语法正确,逻辑清晰

代码变更分析

  1. src/dquickwindow.cpp - showSplitMenu() (行1015-1038)

    • 空指针检查完善:!w || !w->isVisible() || !w->handle() || !button || button->window() != w || !button->isVisible() || !button->isEnabled(),覆盖了所有可能的无效状态
    • 平台函数指针检查:!support || !show || !hide || !support(wid),确保三个函数均存在且平台支持
    • rect.isValid() 检查在显示菜单前验证几何矩形有效性
    • mapRectToScene + toAlignedRect + mapToGlobal 坐标转换链正确
  2. src/dquickwindow.cpp - hideSplitMenu() (行1041-1052)

    • if (!d->splitMenuWindowId) return 守卫防止在未显示菜单时调用隐藏
    • 函数指针正确转换为 void (*)(WId, bool) 签名
    • if (!delay) d->splitMenuWindowId = 0; 仅在非延迟模式下清除 ID,延迟模式下保留 ID 以便后续隐藏
  3. qt6/src/qml/WindowButtonGroup.qml - 分屏菜单交互逻辑 (行94-166)

    • 双触发机制:hoverTimer(700ms 悬停触发)和 holdTimer(300ms 长按触发)
    • 状态管理使用 __longPressed 和 __menuRequested 标志,逻辑覆盖所有交互状态
    • onHoveredChanged:悬停启动定时器,离开时根据按下状态决定是否隐藏菜单
    • onPressed:停止悬停定时器,启动长按定时器,重置 __longPressed
    • onReleased:停止长按定时器,根据 __longPressed 决定隐藏菜单或重置请求标志
    • onCanceled:隐藏菜单并重置长按标志
    • onClicked:仅非长按时触发 maxOrWinded(),长按后重置标志
    • onVisibleChanged/onEnabledChanged:正确清理定时器和菜单状态
  4. qt6/src/qml/ArrowListView.qml - sizedHeight 属性 (行18-27)

    • itemsView.count === 0 返回 0 的边界处理正确
    • itemsView.contentHeight > 0 && item 双重条件检查防止空引用
    • item.height || item.implicitHeight 使用 OR 运算符提供回退值
    • arrowStrips 计算考虑了滚动箭头高度,当项目数超过 maxVisibleItems 时增加箭头条高度
  5. qt6/src/qml/ComboBox.qml - implicitHeight 绑定 (行197-199)

    • contentItem.sizedHeight > 0 ? contentItem.sizedHeight : 2 * DS.Style.arrowListView.itemHeight 三元运算提供合理回退
    • + topPadding + bottomPadding 正确加上弹出窗口的上下内边距
  6. qt6/src/qml/ThemeMenu.qml - 信号处理器修复 (行17)

    • onTriggered: function(action) 修复了 Qt6 中信号参数隐式注入的弃用警告,使用显式参数声明
  7. qt6/src/qml/ArrowListView.qml - onHeightChanged (行50)

    • if (height > 0 && contentHeight === 0) forceLayout() 条件调用 forceLayout(),仅在视图有高度但无内容高度时触发布局

维度2:代码质量(23/25)✓

评价词: 代码结构清晰,注释完整

问题列表

  1. qt6/src/qml/ComboBox.qml 行197: 注释与代码不匹配
    • 注释内容:// 60 is a temporary viewport so the list can realize one row and be measured.
    • 实际代码:implicitHeight: (contentItem.sizedHeight > 0 ? contentItem.sizedHeight : 2 * DS.Style.arrowListView.itemHeight) + topPadding + bottomPadding
    • 问题说明:注释中提到的"60"在代码中并不存在,实际回退值使用的是 2 * DS.Style.arrowListView.itemHeight。注释可能来自早期开发版本的残留,未能及时更新。
    • 建议修复:将注释更新为 // Fallback viewport so the list can realize one row and be measured.

质量评估

检查项 评分 说明
注释完整性 3/5 ComboBox.qml 注释与代码不匹配;ArrowListView.qml 和 dquickwindow.cpp 注释完善
代码重复 5/5 无重复代码,QML 和 C++ 层为互补关系
结构合理性 5/5 WindowButtonGroup.qml 虽新增约90行代码,但内聚性高,全部围绕分屏菜单功能
调试信息清理 5/5 无残留调试代码,无敏感注释
需求匹配度 5/5 代码实现与 commit message 描述的功能完全一致

维度3:代码性能(20/20)✓

评价词: 性能良好,资源使用合理

性能分析

  1. src/dquickwindow.cpp - showSplitMenu():

    • 三次 QGuiApplication::platformFunction() 调用通过字符串查找哈希表,存在轻微开销
    • 但该函数仅在用户悬停/长按最大化按钮时触发,非热路径,性能影响可忽略
  2. qt6/src/qml/ArrowListView.qml - sizedHeight 绑定:

    • itemsView.itemAtIndex(0) 仅获取第一项进行测量,开销极小
    • 作为 readonly 属性绑定,仅在依赖项变化时重新计算
  3. qt6/src/qml/ArrowListView.qml - forceLayout() 调用:

    • forceLayout() 可能触发完整布局计算,但通过 if (height > 0 && contentHeight === 0) 条件限制,仅在必要时调用
  4. qt6/src/qml/WindowButtonGroup.qml - 定时器:

    • 700ms 悬停定时器和 300ms 长按定时器间隔合理,符合 UI 交互习惯
    • 定时器在不使用时正确停止,避免不必要的定时器回调
  5. qt6/src/qml/ComboBox.qml - implicitHeight 绑定:

    • 依赖链 contentItem.sizedHeight → ArrowListView.sizedHeight 是标准 QML 属性绑定,无性能隐患

维度4:代码安全(30/30)✓

存在0个安全漏洞

评价词: 无安全风险,安全合规

安全分析

  1. reinterpret_cast 平台函数指针转换:

    • reinterpret_cast<bool (*)(WId)>(QGuiApplication::platformFunction("_d_supportSplitMenu")) 是 Qt 平台插件的标准模式
    • 平台函数由平台插件注册,函数名均为硬编码字符串字面量,非用户输入
    • 不构成安全风险
  2. 窗口 ID (WId) 来源:

    • w->winId() 是 Qt 内部方法获取窗口标识符,不涉及用户输入
    • splitMenuWindowId 仅在类内部使用,无外部暴露
  3. 坐标计算:

    • button->mapRectToScene(button->boundingRect()).toAlignedRect() 和 w->mapToGlobal(rect.topLeft()) 均为 Qt 内部坐标转换,无路径遍历或注入风险
  4. QML 代码:

    • 无 eval()、无动态属性创建、无网络请求、无文件操作
    • 定时器和事件处理均为标准 QML 交互模式
  5. 翻译文件 (dtkdeclarative_mn.ts):

    • XML 格式的翻译资源文件,仅包含字符串映射,无安全风险
  6. 无硬编码密钥、无敏感信息泄露、无命令注入风险


改进建议

建议1:修复 ComboBox.qml 注释(低优先级)

文件: qt6/src/qml/ComboBox.qml 行197

当前代码:

// 60 is a temporary viewport so the list can realize one row and be measured.
implicitHeight: (contentItem.sizedHeight > 0 ? contentItem.sizedHeight : 2 * DS.Style.arrowListView.itemHeight)
                + topPadding + bottomPadding

建议修改:

// Fallback viewport so the list can realize one row and be measured.
implicitHeight: (contentItem.sizedHeight > 0 ? contentItem.sizedHeight : 2 * DS.Style.arrowListView.itemHeight)
                + topPadding + bottomPadding

原因: 注释中的"60"与实际代码不符,可能误导维护者


审查结论

本次 PR 是将 master 分支合并到 v25-flowstyle 的合并提交,包含以下主要变更:

  1. 分屏菜单功能(feat: add split screen menu to title bar)- 通过悬停或长按最大化按钮触发平台提供的分屏菜单,C++ 层使用平台函数实现,QML 层管理交互状态和定时器
  2. ComboBox 弹窗尺寸修复(fix: size popup before it is mapped)- 在弹窗映射前通过 sizedHeight 计算正确尺寸,避免显示后跳变
  3. ArrowListView 修复 - 修正模型引用、添加 sizedHeight 属性、固定箭头按钮高度
  4. ThemeMenu 信号修复 - 使用显式参数声明修复 Qt6 弃用警告
  5. 蒙古语翻译 - 新增 dtkdeclarative_mn.ts 翻译文件
  6. 版本升级 - 升级至 6.7.51

代码实现与 commit message 描述的功能完全一致,逻辑清晰,安全无漏洞。唯一问题是 ComboBox.qml 中一处注释与代码不匹配,建议修复但不影响合并。

@deepin-ci-robot

Copy link
Copy Markdown
Contributor

[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.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@BLumia
BLumia merged commit a2d3060 into linuxdeepin:v25-flowstyle Oct 20, 2026
20 of 22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants