Skip to content

fix: optimize window button display delay issue#584

Merged
18202781743 merged 1 commit intolinuxdeepin:masterfrom
18202781743:master
Mar 10, 2026
Merged

fix: optimize window button display delay issue#584
18202781743 merged 1 commit intolinuxdeepin:masterfrom
18202781743:master

Conversation

@18202781743
Copy link
Contributor

@18202781743 18202781743 commented Mar 10, 2026

  1. Replaced Loader components with direct WindowButton instances to
    eliminate loading delays
  2. Added cached properties for motifFunctions bitwise operations to
    avoid repeated calculations
  3. Simplified size resizable check by comparing width/height values
    directly instead of creating Size objects
  4. Changed visibility control from Loader.active to WindowButton.visible
    for smoother transitions
  5. Improved performance by reducing object creation and property
    recalculations

Log: Fixed window control buttons flashing/delayed appearance issue

Influence:

  1. Test window minimize/maximize/close buttons appear instantly without
    delay
  2. Verify button visibility changes correctly when entering/exiting
    fullscreen mode
  3. Test button states update properly when window flags change
  4. Verify all window buttons remain functional with correct enabled/
    disabled states
  5. Test performance impact during window resizing and state transitions
  6. Verify no visual glitches when toggling between windowed and
    fullscreen modes

fix: 优化标题栏窗口按钮延迟闪现问题

  1. 将 Loader 组件替换为直接的 WindowButton 实例,消除加载延迟
  2. 添加缓存的 motifFunctions 位运算属性,避免重复计算
  3. 简化可调整大小检查,直接比较宽高值而不是创建 Size 对象
  4. 将可见性控制从 Loader.active 改为 WindowButton.visible,实现更平滑的
    过渡
  5. 通过减少对象创建和属性重计算来提升性能

Log: 修复窗口控制按钮闪现/延迟显示问题

Influence:

  1. 测试窗口最小化/最大化/关闭按钮是否立即显示无延迟
  2. 验证进入/退出全屏模式时按钮可见性是否正确变化
  3. 测试窗口标志改变时按钮状态是否正确更新
  4. 验证所有窗口按钮功能正常,启用/禁用状态正确
  5. 测试窗口调整大小和状态转换时的性能影响
  6. 验证在窗口模式和全屏模式切换时无视觉闪烁

PMS: BUG-351921

Summary by Sourcery

Optimize window titlebar button rendering to remove display delays and reduce unnecessary recomputation.

Bug Fixes:

  • Fix delayed or flashing appearance of window control buttons when the window state changes.

Enhancements:

  • Replace Loader-based window control button creation with direct WindowButton instances for smoother visibility transitions and lower overhead.
  • Cache window motif function flags and simplify resize capability checks to avoid repeated bitwise operations and temporary object creation.

@18202781743 18202781743 requested review from BLumia and mhduiy March 10, 2026 07:03
@sourcery-ai
Copy link

sourcery-ai bot commented Mar 10, 2026

Reviewer's Guide

Refactors WindowButtonGroup to use direct WindowButton instances instead of Loaders, introduces cached motifFunctions-derived properties, and simplifies resizability logic to remove unnecessary object creation and visibility indirections, fixing delayed/flashy display of window control buttons and improving performance.

Flow diagram for WindowButton visibility and enablement logic

flowchart TD
    subgraph Inputs
        flags["Window.window.flags"]
        visibility["Window.window.visibility"]
        dwindowEnabled["__dwindow.enabled"]
        embedMode["embedMode"]
        fullScreenBtnVisible["control.fullScreenButtonVisible"]
        motifFunctions["__dwindow.motifFunctions"]
        maxWidth["Window.window.maximumWidth"]
        minWidth["Window.window.minimumWidth"]
        maxHeight["Window.window.maximumHeight"]
        minHeight["Window.window.minimumHeight"]
    end

    subgraph Cached_bitwise_properties
        canMinimize["__canMinimize = motifFunctions & FUNC_MINIMIZE"]
        canMaximize["__canMaximize = motifFunctions & FUNC_MAXIMIZE"]
        canResize["__canResize = motifFunctions & FUNC_RESIZE"]
        canClose["__canClose = motifFunctions & FUNC_CLOSE"]
    end

    subgraph Common_state
        forceHind["__forceHind = !__dwindow.enabled || embedMode || visibility == FullScreen"]
        sizeResizable["__sizeResizable = (maxWidth != minWidth) || (maxHeight != minHeight)"]
    end

    subgraph Minimize_button
        minHasFlag["hasWindowFlag = flags & WindowMinimizeButtonHint"]
        minVisible["minimizeBtn.visible = hasWindowFlag && !forceHind"]
        minEnabled["minimizeBtn.enabled = canMinimize"]
    end

    subgraph Quit_fullscreen_button
        quitVisible["quitFullBtn.visible = fullScreenBtnVisible && __dwindow.enabled && visibility == FullScreen"]
    end

    subgraph Maximize_restore_button
        maxHasFlag["hasWindowFlag = flags & WindowMaximizeButtonHint"]
        maxVisible["maxOrWindedBtn.visible = hasWindowFlag && !forceHind && canResize && sizeResizable"]
        maxEnabled["maxOrWindedBtn.enabled = canMaximize && canResize"]
    end

    subgraph Close_button
        closeHasFlag["hasWindowFlag = flags & WindowCloseButtonHint"]
        closeVisible["closeBtn.visible = hasWindowFlag && __dwindow.enabled"]
        closeEnabled["closeBtn.enabled = canClose"]
    end

    flags --> minHasFlag
    flags --> maxHasFlag
    flags --> closeHasFlag

    dwindowEnabled --> forceHind
    embedMode --> forceHind
    visibility --> forceHind
    visibility --> quitVisible

    fullScreenBtnVisible --> quitVisible
    dwindowEnabled --> quitVisible

    motifFunctions --> canMinimize
    motifFunctions --> canMaximize
    motifFunctions --> canResize
    motifFunctions --> canClose

    canMinimize --> minEnabled
    canMaximize --> maxEnabled
    canResize --> maxVisible
    canResize --> maxEnabled
    canClose --> closeEnabled

    forceHind --> minVisible
    forceHind --> maxVisible

    maxWidth --> sizeResizable
    minWidth --> sizeResizable
    maxHeight --> sizeResizable
    minHeight --> sizeResizable

    minHasFlag --> minVisible
    maxHasFlag --> maxVisible
    closeHasFlag --> closeVisible
Loading

File-Level Changes

Change Details Files
Replace Loader-based lazy button instantiation with always-present WindowButton instances controlled via visible/enabled properties to remove creation delays and flashing.
  • Convert minimize, quit-fullscreen, maximize/restore, and close controls from Loader to direct WindowButton elements.
  • Move icon, textColor, and click handlers from Loader.sourceComponent into the WindowButton definitions themselves.
  • Replace Loader.active usage with WindowButton.visible conditions based on window flags, embed/fullscreen state, and __dwindow.enabled.
qt6/src/qml/WindowButtonGroup.qml
Cache motifFunctions-derived capabilities and reuse them across bindings to avoid repeated bitwise computations.
  • Add readonly properties __canMinimize, __canMaximize, __canResize, and __canClose computed from __dwindow.motifFunctions and D.WindowManagerHelper constants.
  • Update enabled/visibility expressions for buttons to reference the cached capability properties instead of inlining bitwise operations every time.
qt6/src/qml/WindowButtonGroup.qml
Simplify window resizability logic and button state conditions to reduce object creation and clarify behavior.
  • Replace maxSize/minSize Qt.size objects with a boolean __sizeResizable that compares maximum/minimum width and height directly.
  • Update maxOrWindedBtn visibility to depend on hasWindowFlag, !__forceHind, __canResize, and __sizeResizable.
  • Update maxOrWindedBtn enabled state to combine __canMaximize and __canResize and inline isMaximized, icon, and click behavior directly on the button.
qt6/src/qml/WindowButtonGroup.qml

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

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.

Hey - I've left some high level feedback:

  • For the cached motifFunctions flags (e.g., __canMinimize, __canMaximize), consider making the bitwise checks explicitly boolean (e.g., (__dwindow.motifFunctions & D.WindowManagerHelper.FUNC_MINIMIZE) !== 0) to avoid relying on implicit int-to-bool coercion and make the intent clearer.
  • Now that Loader has been removed, several visible expressions directly embed relatively complex conditions; consider extracting shared pieces (like the fullscreen visibility logic) into small helper properties to keep the button definitions easier to read and maintain.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- For the cached motifFunctions flags (e.g., `__canMinimize`, `__canMaximize`), consider making the bitwise checks explicitly boolean (e.g., `(__dwindow.motifFunctions & D.WindowManagerHelper.FUNC_MINIMIZE) !== 0`) to avoid relying on implicit int-to-bool coercion and make the intent clearer.
- Now that `Loader` has been removed, several `visible` expressions directly embed relatively complex conditions; consider extracting shared pieces (like the fullscreen visibility logic) into small helper properties to keep the button definitions easier to read and maintain.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

1. Replaced Loader components with direct WindowButton instances to
eliminate loading delays
2. Added cached properties for motifFunctions bitwise operations to
avoid repeated calculations
3. Simplified size resizable check by comparing width/height values
directly instead of creating Size objects
4. Changed visibility control from Loader.active to WindowButton.visible
for smoother transitions
5. Improved performance by reducing object creation and property
recalculations

Log: Fixed window control buttons flashing/delayed appearance issue

Influence:
1. Test window minimize/maximize/close buttons appear instantly without
delay
2. Verify button visibility changes correctly when entering/exiting
fullscreen mode
3. Test button states update properly when window flags change
4. Verify all window buttons remain functional with correct enabled/
disabled states
5. Test performance impact during window resizing and state transitions
6. Verify no visual glitches when toggling between windowed and
fullscreen modes

fix: 优化标题栏窗口按钮延迟闪现问题

1. 将 Loader 组件替换为直接的 WindowButton 实例,消除加载延迟
2. 添加缓存的 motifFunctions 位运算属性,避免重复计算
3. 简化可调整大小检查,直接比较宽高值而不是创建 Size 对象
4. 将可见性控制从 Loader.active 改为 WindowButton.visible,实现更平滑的
过渡
5. 通过减少对象创建和属性重计算来提升性能

Log: 修复窗口控制按钮闪现/延迟显示问题

Influence:
1. 测试窗口最小化/最大化/关闭按钮是否立即显示无延迟
2. 验证进入/退出全屏模式时按钮可见性是否正确变化
3. 测试窗口标志改变时按钮状态是否正确更新
4. 验证所有窗口按钮功能正常,启用/禁用状态正确
5. 测试窗口调整大小和状态转换时的性能影响
6. 验证在窗口模式和全屏模式切换时无视觉闪烁

PMS: BUG-351921
@deepin-ci-robot
Copy link
Contributor

deepin pr auto review

Git Diff 代码审查报告

概述

这段代码是对 WindowButtonGroup.qml 文件的修改,主要进行了以下优化:

  1. 更新了版权年份范围
  2. Loader 组件替换为直接的 WindowButton 组件
  3. 添加了 motifFunctions 位运算结果的缓存
  4. 优化了窗口大小可调整性的判断逻辑

详细审查

1. 版权信息更新

// SPDX-FileCopyrightText: 2021 - 2026 UnionTech Software Technology Co., Ltd.
  • 评价:将版权年份范围从 2021-2022 扩展到 2021-2026,这是合理的更新,确保了版权信息的时效性。

2. motifFunctions 位运算结果缓存

// 缓存 motifFunctions 位运算结果,避免重复计算
readonly property bool __canMinimize: __dwindow.motifFunctions & D.WindowManagerHelper.FUNC_MINIMIZE
readonly property bool __canMaximize: __dwindow.motifFunctions & D.WindowManagerHelper.FUNC_MAXIMIZE
readonly property bool __canResize: __dwindow.motifFunctions & D.WindowManagerHelper.FUNC_RESIZE
readonly property bool __canClose: __dwindow.motifFunctions & D.WindowManagerHelper.FUNC_CLOSE
  • 评价:这是一个很好的优化,将重复使用的位运算结果缓存为只读属性,避免了每次评估时的重复计算,提高了代码性能。
  • 建议:确保这些属性在 __dwindow 或其 motifFunctions 属性变化时能够正确更新。如果 __dwindow.motifFunctions 可能动态变化,考虑添加绑定监听。

3. Loader 组件替换

// 之前使用 Loader
Loader {
    active: hasWindowFlag &&  !__forceHind
    visible: active
    enabled: (__dwindow.motifFunctions & D.WindowManagerHelper.FUNC_MINIMIZE)
    sourceComponent: WindowButton {
        // ...
    }
}

// 现在直接使用 WindowButton
WindowButton {
    visible: hasWindowFlag && !__forceHind
    enabled: __canMinimize
    // ...
}
  • 评价:将 Loader 组件替换为直接的 WindowButton 组件简化了代码结构,减少了组件嵌套层次,提高了可读性。
  • 性能考虑Loader 的优势在于可以延迟加载组件,当 activefalse 时不会创建组件实例。直接使用 WindowButton 意味着即使 visiblefalse,组件也会被创建。如果这些按钮在大多数情况下都是可见的,这种改变是合理的;但如果按钮经常不可见,可能会增加不必要的内存开销。

4. 窗口大小可调整性判断优化

// 之前使用对象创建
readonly property size maxSize: Qt.size(Window.window.maximumWidth, Window.window.maximumHeight)
readonly property size minSize: Qt.size(Window.window.minimumWidth, Window.window.minimumHeight)
active: (hasWindowFlag && !__forceHind &&
         (__dwindow.motifFunctions & D.WindowManagerHelper.FUNC_RESIZE) &&
         maxSize != minSize)

// 现在使用简单值比较
readonly property bool __sizeResizable: (Window.window.maximumWidth !== Window.window.minimumWidth ||
                                          Window.window.maximumHeight !== Window.window.minimumHeight)
visible: (hasWindowFlag && !__forceHind && __canResize && __sizeResizable)
  • 评价:使用简单的布尔值比较代替对象创建和比较,避免了不必要的对象创建和比较操作,提高了性能。
  • 逻辑正确性:新逻辑使用 || 运算符,只要宽度或高度中有一个可调整就认为窗口可调整大小,这与之前的对象比较逻辑一致,是正确的。

5. 其他改进

  • maxOrWindedBtn.active 改为 maxOrWindedBtn.visibleonMaxOrWinded 函数中,这是一个合理的修改,因为现在不再使用 Loaderactive 属性。
  • 代码格式更加统一,缩进和空格使用更加一致。

潜在问题和建议

  1. 属性更新机制

    • 如果 __dwindow.motifFunctions 可能动态变化,需要确保缓存的位运算结果能够正确更新。当前实现中,这些是 readonly property,如果 __dwindow.motifFunctions 变化,这些属性不会自动更新。
  2. 性能考虑

    • 如前所述,直接使用 WindowButton 而不是 Loader 可能会增加内存使用,特别是在按钮经常不可见的情况下。建议根据实际使用场景评估这种改变的影响。
  3. 错误处理

    • 代码中没有明显的错误处理机制。如果 __dwindownullWindow.windownull,可能会导致运行时错误。建议添加适当的空值检查。
  4. 代码复用

    • 每个按钮都重复设置了 textColor: control.textColor,可以考虑将其提取到父组件或使用样式继承。

总结

总体而言,这次代码修改提高了代码的可读性和性能,通过缓存位运算结果和简化组件结构,使代码更加高效。主要的改进包括:

  1. 缓存重复使用的位运算结果
  2. 简化组件结构,减少嵌套层次
  3. 优化窗口大小可调整性的判断逻辑

建议在实际部署前考虑上述潜在问题,特别是关于属性更新和内存使用的考虑。

@deepin-ci-robot
Copy link
Contributor

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

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 18202781743 merged commit af52d4c into linuxdeepin:master Mar 10, 2026
20 of 21 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.

3 participants