Skip to content

Conversation

@18202781743
Copy link
Contributor

  1. Replaced separate AppItemWithTitle.qml with unified AppItem.qml that
    handles both split and merged window modes
  2. Introduced TextCalculator C++ class to handle dynamic text width
    calculation for better performance
  3. Created AppItemTitle.qml as a reusable component for displaying
    application titles with proper elision
  4. Removed complex QML-based text width calculations and dynamic
    character limit arrays
  5. Simplified TaskManager.qml by moving text calculation logic to C+
  • backend
  1. Improved window split mode handling with more accurate space
    allocation calculations

Log: Unified application split and merge display into single item view

Influence:

  1. Test application display in both split and merged window modes
  2. Verify text elision works correctly with long application titles
  3. Check performance when multiple applications are open with window
    split enabled
  4. Test drag and drop functionality between applications
  5. Verify application title visibility in different dock positions
  6. Test window preview and context menu functionality
  7. Check memory usage with many open applications

refactor: 统一应用拆分/合并显示并优化文本计算

  1. 将单独的 AppItemWithTitle.qml 替换为统一的 AppItem.qml,同时处理拆分
    和合并窗口模式
  2. 引入 TextCalculator C++ 类来处理动态文本宽度计算,提高性能
  3. 创建 AppItemTitle.qml 作为可重用组件,用于显示带正确省略的应用标题
  4. 移除复杂的基于 QML 的文本宽度计算和动态字符限制数组
  5. 通过将文本计算逻辑移至 C++ 后端简化 TaskManager.qml
  6. 改进窗口拆分模式处理,提供更准确的空间分配计算

Log: 将应用拆分和合并显示统一为单一项视图

Influence:

  1. 测试应用在拆分和合并窗口模式下的显示
  2. 验证长应用标题的文本省略功能是否正常工作
  3. 检查启用窗口拆分时多个应用打开的性能
  4. 测试应用之间的拖放功能
  5. 验证不同任务栏位置下应用标题的可见性
  6. 测试窗口预览和上下文菜单功能
  7. 检查打开多个应用时的内存使用情况

PMS: TASK-384101

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Sorry @18202781743, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors the task manager's application display system by unifying split and merged window modes into a single component architecture. The main achievement is moving complex text width calculations from QML to a new C++ TextCalculator class for better performance and maintainability.

Key Changes:

  • Introduced TextCalculator C++ class to handle dynamic text width calculations with caching
  • Unified AppItemWithTitle.qml into AppItem.qml to handle both split and merged modes
  • Created reusable AppItemTitle.qml component for text display with proper elision

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 29 comments.

Show a summary per file
File Description
panels/dock/taskmanager/textcalculator.h New C++ header defining TextCalculator and TextCalculatorAttached classes for text width computation
panels/dock/taskmanager/textcalculator.cpp Implementation of text calculation logic with caching and optimal width determination
panels/dock/taskmanager/taskmanager.cpp Registration of new TextCalculator QML types
panels/dock/taskmanager/package/TaskManager.qml Removed complex QML text calculation functions, integrated TextCalculator component
panels/dock/taskmanager/package/AppItemWithTitle.qml File removed - functionality merged into AppItem.qml
panels/dock/taskmanager/package/AppItemTitle.qml New reusable component for displaying application titles with elision
panels/dock/taskmanager/package/AppItem.qml Enhanced to support both modes, integrated title display, fixed hover handling with HoverHandler
panels/dock/taskmanager/CMakeLists.txt Added new textcalculator source files to build
panels/dock/package/main.qml Exposed dockPartSpacing property for spacing calculations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

// 非 windowSplit 模式,隐藏整个应用
return false
}
property bool visibility: itemId !== taskmanager.Applet.desktopIdToAppId(launcherDndDropArea.launcherDndDesktopId)
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The visibility logic for handling drag and drop has been significantly simplified. The old implementation had special handling for windowSplit mode that would show/hide individual windows vs. the docked icon. The new simplified logic only checks if 'itemId !== taskmanager.Applet.desktopIdToAppId(launcherDndDropArea.launcherDndDesktopId)'. This removes the windowSplit-specific behavior where individual windows could be dragged separately from the docked icon. Verify that this simplification doesn't break window split mode drag and drop functionality.

Suggested change
property bool visibility: itemId !== taskmanager.Applet.desktopIdToAppId(launcherDndDropArea.launcherDndDesktopId)
property bool visibility: {
// In window split mode, each delegate may represent a single window.
// Hide only the dragged window delegate itself.
if (taskmanager.Applet.windowSplit) {
return itemId !== launcherDndDropArea.launcherDndDesktopId
}
// In normal mode, delegates represent apps; hide items for the dragged app.
return itemId !== taskmanager.Applet.desktopIdToAppId(launcherDndDropArea.launcherDndDesktopId)
}

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 9 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

id: mouseArea
anchors.fill: parent
hoverEnabled: true
hoverEnabled: false
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The HoverHandler is used but MouseArea.hoverEnabled is disabled. This creates inconsistent hover behavior. If HoverHandler is handling hover events, the MouseArea should not be used for hover detection. Consider removing the MouseArea.hoverEnabled property entirely or ensuring both mechanisms work together properly.

Suggested change
hoverEnabled: false

Copilot uses AI. Check for mistakes.

QString TextCalculatorAttached::elidedText() const
{
const_cast<TextCalculatorAttached *>(this)->ensureInitialize();
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

Using const_cast to modify a const object violates const-correctness. The same issue as line 188 - consider making m_initialized mutable instead.

Copilot uses AI. Check for mistakes.
property int remainingSpacesForTaskManager: Panel.itemAlignment === Dock.LeftAlignment ? Panel.rootObject.dockLeftSpaceForCenter : Panel.rootObject.dockRemainingSpaceForCenter

property int remainingSpacesForSplitWindow: Panel.rootObject.dockLeftSpaceForCenter - (Panel.rootObject.dockCenterPartCount - 1) * Panel.rootObject.dockItemMaxSize * 9 / 14
property real remainingSpacesForTaskManager: Panel.itemAlignment === Dock.LeftAlignment ? Panel.rootObject.dockLeftSpaceForCenter : Panel.rootObject.dockRemainingSpaceForCenter
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The property type changed from int to real for spacing-related calculations. This is good for precision, but ensure all downstream calculations handle real values correctly, especially when used in QML layouts that might expect integer values.

Copilot uses AI. Check for mistakes.
Comment on lines +144 to +145
const auto titleRole = m_dataModel->roleNames().key("title");
if (roles.contains(titleRole) || roles.isEmpty()) {
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

There's a potential division by zero issue. If dataModel->roleNames() is empty, roleNames.key("title") will return an undefined/default value which might cause issues. Consider adding validation to ensure the "title" role exists before using it.

Suggested change
const auto titleRole = m_dataModel->roleNames().key("title");
if (roles.contains(titleRole) || roles.isEmpty()) {
const auto roleNames = m_dataModel->roleNames();
const int titleRole = roleNames.key("title", -1);
if ((titleRole != -1 && roles.contains(titleRole)) || roles.isEmpty()) {

Copilot uses AI. Check for mistakes.
}

// Update results
if (!qFuzzyCompare(m_optimalSingleTextWidth, newOptimalWidth)) {
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The comparison uses qFuzzyCompare which is appropriate for floating-point comparison, but it may fail when one of the values is 0.0 (as qFuzzyCompare doesn't handle zero well). Consider using a different comparison method or adding a special case for zero values.

Copilot uses AI. Check for mistakes.
, m_windowFullscreen(false)
{
qmlRegisterType<TextCalculator>("org.deepin.ds.dock.taskmanager", 1, 0, "TextCalculator");
qmlRegisterUncreatableType<TextCalculatorAttached>("org.deepin.ds.dock.taskmanager", 1, 0, "TextCalculatorAttached", "TextCalculator Attached");
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The qmlRegisterUncreatableType error message "TextCalculator Attached" is unclear and unprofessional. It should explain why the type cannot be created, such as "TextCalculatorAttached can only be used as an attached property".

Suggested change
qmlRegisterUncreatableType<TextCalculatorAttached>("org.deepin.ds.dock.taskmanager", 1, 0, "TextCalculatorAttached", "TextCalculator Attached");
qmlRegisterUncreatableType<TextCalculatorAttached>("org.deepin.ds.dock.taskmanager", 1, 0, "TextCalculatorAttached", "TextCalculatorAttached can only be used as an attached property");

Copilot uses AI. Check for mistakes.
onPressed: function (mouse) {
if (mouse.button === Qt.LeftButton) {
icon.grabToImage(function(result) {
appItem.grabToImage(function(result) {
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The drag image is now captured from appItem instead of just the icon. This changes the drag visual to include the title text, which may not be the desired behavior. Consider whether dragging should show only the icon (as before) or the entire item including text.

Copilot uses AI. Check for mistakes.
Comment on lines 69 to 70
anchors.fill: parent
id: appItem
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The anchors.fill relationship creates a potential layout issue. The titleLoader is anchored relative to iconContainer and parent, but if iconContainer's width changes based on titleActive state (line 78), this could cause layout calculation loops. Consider using explicit positioning instead of relying on anchors.fill for the parent Control.

Suggested change
anchors.fill: parent
id: appItem
id: appItem
anchors.centerIn: parent
width: parent.width
height: parent.height

Copilot uses AI. Check for mistakes.
Comment on lines +182 to +183
// Generate baseline text: repeat "字" × character count
QString baselineText = QString("").repeated(charCount);
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

Using literal string "字" for baseline text calculation assumes Chinese character width. This may not be appropriate for all languages or font configurations. Consider making this configurable or using a more universal baseline character that better represents average character width across different languages.

Suggested change
// Generate baseline text: repeat "字" × character count
QString baselineText = QString("").repeated(charCount);
// Generate baseline text using a neutral Latin character to avoid CJK-specific width assumptions
QString baselineText = QString(charCount, QLatin1Char('x'));

Copilot uses AI. Check for mistakes.
1. Replaced separate AppItemWithTitle.qml with unified AppItem.qml that
handles both split and merged window modes
2. Introduced TextCalculator C++ class to handle dynamic text width
calculation for better performance
3. Created AppItemTitle.qml as a reusable component for displaying
application titles with proper elision
4. Removed complex QML-based text width calculations and dynamic
character limit arrays
5. Simplified TaskManager.qml by moving text calculation logic to C+
+ backend
6. Improved window split mode handling with more accurate space
allocation calculations

Log: Unified application split and merge display into single item view

Influence:
1. Test application display in both split and merged window modes
2. Verify text elision works correctly with long application titles
3. Check performance when multiple applications are open with window
split enabled
4. Test drag and drop functionality between applications
5. Verify application title visibility in different dock positions
6. Test window preview and context menu functionality
7. Check memory usage with many open applications

refactor: 统一应用拆分/合并显示并优化文本计算

1. 将单独的 AppItemWithTitle.qml 替换为统一的 AppItem.qml,同时处理拆分
和合并窗口模式
2. 引入 TextCalculator C++ 类来处理动态文本宽度计算,提高性能
3. 创建 AppItemTitle.qml 作为可重用组件,用于显示带正确省略的应用标题
4. 移除复杂的基于 QML 的文本宽度计算和动态字符限制数组
5. 通过将文本计算逻辑移至 C++ 后端简化 TaskManager.qml
6. 改进窗口拆分模式处理,提供更准确的空间分配计算

Log: 将应用拆分和合并显示统一为单一项视图

Influence:
1. 测试应用在拆分和合并窗口模式下的显示
2. 验证长应用标题的文本省略功能是否正常工作
3. 检查启用窗口拆分时多个应用打开的性能
4. 测试应用之间的拖放功能
5. 验证不同任务栏位置下应用标题的可见性
6. 测试窗口预览和上下文菜单功能
7. 检查打开多个应用时的内存使用情况

PMS: TASK-384101
@deepin-ci-robot
Copy link

deepin pr auto review

我来对这个diff进行详细的代码审查:

  1. 代码结构和组织
  • 新增了TextCalculator类来处理文本计算逻辑,这是一个好的改进,将复杂的文本计算逻辑从QML中分离出来
  • 删除了AppItemWithTitle.qml,统一使用AppItem.qml,减少了代码重复
  • 添加了AppItemTitle.qml作为独立的标题组件,提高了代码复用性
  1. 性能优化
  • 使用了缓存机制(m_baselineWidthCache)来避免重复计算基线宽度
  • 将文本计算逻辑移到C++层,提高了性能
  • 使用QML的attached properties机制来管理文本计算,避免了重复创建对象
  1. 代码质量
  • TextCalculator类实现了QQmlParserStatus接口,确保组件初始化的正确顺序
  • 使用了适当的信号槽机制来处理数据变化
  • 添加了详细的日志记录,便于调试
  1. 安全性
  • 对空指针和无效数据进行了适当的检查
  • 使用了const正确性来防止意外修改
  • 对文本长度进行了合理的限制和验证
  1. 具体改进建议:

a) 在TextCalculator::calculateElidedTextWidth中:

qreal TextCalculator::calculateElidedTextWidth(const QString &text, qreal maxWidth) const
{
    if (text.isEmpty() || maxWidth <= 0) {  // 添加maxWidth检查
        return 0.0;
    }
    // ...
}

b) 在TextCalculatorAttached::ensureInitialize中:

void TextCalculatorAttached::ensureInitialize()
{
    if (m_initialized) {
        return;
    }

    m_initialized = true;
    if (!m_calculator) {
        auto calculator = findCalculatorForObject(parent());
        if (!calculator) {  // 添加空指针检查
            qCWarning(textCalculatorLog) << "Failed to find calculator for object";
            return;
        }
        setCalculator(calculator);
    }
}

c) 在TaskManager.qml中:

property real remainingSpacesForSplitWindow: Panel.rootObject.dockLeftSpaceForCenter - (
    (Panel.rootObject.dockCenterPartCount - 1) * (visualModel.cellWidth + appContainer.spacing) + 
    (Panel.rootObject.dockCenterPartCount) * Panel.rootObject.dockPartSpacing)

建议添加括号明确运算优先级,并添加注释说明计算逻辑。

d) 在textcalculator.cpp中:

void TextCalculator::scheduleCalculation()
{
    if (!complete || !m_enabled || !m_dataModel) {  // 合并条件检查
        return;
    }
    calculateOptimalTextWidth();
}
  1. 其他建议:
  • 考虑为TextCalculator添加单元测试
  • 在TextCalculator中添加更多的错误处理和边界条件检查
  • 考虑添加配置选项来调整文本计算的参数
  • 为复杂的计算逻辑添加更多注释说明

总的来说,这次改进提高了代码的可维护性和性能,但还可以在错误处理和文档方面进一步完善。

Copy link
Member

@BLumia BLumia left a comment

Choose a reason for hiding this comment

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

看一下 copilot 关于 complete 定义但未使用的问题?别的看上去 ok

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: 18202781743, BLumia, robertkill

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

@18202781743
Copy link
Contributor Author

看一下 copilot 关于 complete 定义但未使用的问题?别的看上去 ok

是那个Textcalculator.h里的成员变量complete 么?那个应该用到了呀,在componentComplete的里面用了,

@BLumia
Copy link
Member

BLumia commented Dec 22, 2025

那个应该用到了呀,在componentComplete的里面用了

喔,看到了。刚才应该 .cpp 加载失败了,ctrl f 没搜到结果。没问题

@18202781743
Copy link
Contributor Author

那个应该用到了呀,在componentComplete的里面用了

喔,看到了。刚才应该 .cpp 加载失败了,ctrl f 没搜到结果。没问题

哦哦,

@18202781743 18202781743 merged commit 417ea20 into linuxdeepin:master Dec 22, 2025
9 of 10 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.

5 participants