Skip to content

fix: prevent visual ghosting and flashing during dock position change#1484

Merged
robertkill merged 1 commit intolinuxdeepin:masterfrom
robertkill:master
Mar 7, 2026
Merged

fix: prevent visual ghosting and flashing during dock position change#1484
robertkill merged 1 commit intolinuxdeepin:masterfrom
robertkill:master

Conversation

@robertkill
Copy link
Contributor

@robertkill robertkill commented Mar 7, 2026

Fixed the issue where changing dock position caused visual ghosting and flashing in both X11 and Wayland environments.

  1. Prevented size bindings from resetting to 0 during position animations in Wayland by ensuring proper from/to dimension values based on the layout's dockSize.
  2. Disabled D.DWindow.shadowColor and borderWidth not only during hideShowAnimation.running but also during dockAnimation.running. This cleanly removes the lingering shadow effects and borders while the window manager translates the native window.

fix: 修复任务栏停靠位置改变时的视觉残影和闪烁问题

修复了在X11和Wayland环境下更改任务栏位置时导致视觉残影和闪烁的问题。

  1. 通过确保正确返回基于布局当前厚度(dockSize)的from/to插值尺寸,防止了 部分环境下的尺寸插值在位置切换动画期间错误回落归零。
  2. 不仅在 hideShowAnimation.running 阶段,还在 dockAnimation.running 阶段同样 禁用了D.DWindow.shadowColor和borderWidth。这干净利落地移除了底层窗口管理器 平移或转换窗口位置时残留的阴影效果和黑色边框。

Log: 修复任务栏在切换位置时产生的残影和闪烁瑕疵

Influence:

  1. Test moving the dock position (Top, Bottom, Left, Right) to ensure smooth transitions without graphical artifacts or shadow ghosting.
  2. Verify normal dock hide/show toggle works correctly with its respective shadows and borders.
  3. Check the behavior under both X11 and Wayland display servers if possible.

Influence:

  1. 测试移动任务栏位置(上、下、左、右),确保平滑过渡,无图形缺陷或阴影残影。
  2. 验证正常的任务栏隐藏/显示切换依然拥有正常的阴影和边框表现。
  3. 检查在X11和Wayland双环境下的切换行为一致性。

PMS: BUG-352127

Summary by Sourcery

Fix visual artifacts when changing dock position by adjusting animation dimensions and window decorations during transitions.

Bug Fixes:

  • Prevent dock size animations from collapsing to zero during position changes when using transform-based animations.
  • Disable dock window shadows and borders while dock position animations are running to avoid ghosting and flashing artifacts.

Fixed the issue where changing dock position caused visual ghosting and flashing
in both X11 and Wayland environments.
1. Prevented size bindings from resetting to 0 during position animations in
Wayland by ensuring proper from/to dimension values based on the layout's dockSize.
2. Disabled D.DWindow.shadowColor and borderWidth not only during
hideShowAnimation.running but also during dockAnimation.running. This cleanly
removes the lingering shadow effects and borders while the window manager
translates the native window.

fix: 修复任务栏停靠位置改变时的视觉残影和闪烁问题

修复了在X11和Wayland环境下更改任务栏位置时导致视觉残影和闪烁的问题。
1. 通过确保正确返回基于布局当前厚度(dockSize)的from/to插值尺寸,防止了
部分环境下的尺寸插值在位置切换动画期间错误回落归零。
2. 不仅在 hideShowAnimation.running 阶段,还在 dockAnimation.running 阶段同样
禁用了D.DWindow.shadowColor和borderWidth。这干净利落地移除了底层窗口管理器
平移或转换窗口位置时残留的阴影效果和黑色边框。

Log: 修复任务栏在切换位置时产生的残影和闪烁瑕疵

Influence:
1. Test moving the dock position (Top, Bottom, Left, Right) to ensure smooth
transitions without graphical artifacts or shadow ghosting.
2. Verify normal dock hide/show toggle works correctly with its respective
shadows and borders.
3. Check the behavior under both X11 and Wayland display servers if possible.

Influence:
1. 测试移动任务栏位置(上、下、左、右),确保平滑过渡,无图形缺陷或阴影残影。
2. 验证正常的任务栏隐藏/显示切换依然拥有正常的阴影和边框表现。
3. 检查在X11和Wayland双环境下的切换行为一致性。

PMS: BUG-352127
@deepin-ci-robot
Copy link

deepin pr auto review

这段代码的修改主要涉及任务栏在显示/隐藏动画和停靠动画过程中的阴影、边框以及位置属性的控制。以下是对代码的详细审查和改进建议:

1. 语法逻辑审查

修改点分析:

  • 阴影和边框控制:在 D.DWindow.shadowColorD.DWindow.borderWidth 的绑定中,增加了对 dockAnimation.running 的判断。这意味着当任务栏正在进行停靠动画时,也会隐藏阴影和边框。
  • 位置属性控制:在动画的 fromto 属性中,根据 dockAnimation.useTransformBasedAnimation 的值来决定动画的起始和结束位置。

逻辑问题:

  • 条件判断的一致性:代码中 dockAnimation.useTransformBasedAnimation 被用于控制动画位置,但在阴影和边框的控制中没有考虑这个属性。这可能导致在某些情况下,动画类型和阴影/边框状态不一致。
  • 动画状态管理:直接使用 dockAnimation.running 来控制阴影和边框,但没有考虑动画完成后的状态恢复机制。

2. 代码质量审查

优点:

  • 代码注释清晰,解释了参数的来源和注意事项。
  • 使用了三元运算符简化条件表达式。

改进建议:

  • 提取魔法数字:如 0.1401 等应定义为常量,提高代码可读性和可维护性。
  • 条件表达式简化:可以定义一个辅助函数或属性来统一判断是否需要隐藏阴影和边框。
  • 动画状态管理:建议使用状态机或更明确的状态管理方式,避免多个动画状态相互干扰。

3. 代码性能审查

潜在问题:

  • 频繁属性绑定D.DWindow 的多个属性(如 shadowColorborderWidth)与动画状态绑定,可能导致频繁的属性更新和重绘。
  • 动画性能:如果 dockAnimationhideShowAnimation 同时运行,可能会增加性能开销。

改进建议:

  • 减少不必要的属性更新:可以使用 Bindingdelayed 属性或批量更新机制来减少重绘。
  • 动画优化:确保动画不会同时触发不必要的属性更新。

4. 代码安全审查

潜在问题:

  • 空值检查:代码中没有对 dockAnimation 进行空值检查,如果 dockAnimation 未初始化,可能导致运行时错误。
  • 属性依赖:多个属性依赖于 dockAnimation 的状态,如果 dockAnimation 的状态管理不当,可能导致界面显示异常。

改进建议:

  • 增加防御性编程:在访问 dockAnimation 的属性前,确保其已正确初始化。
  • 状态一致性检查:确保动画状态与界面状态(如阴影、边框)保持一致。

5. 改进后的代码示例

Window {
    // 定义常量
    readonly property real shadowOpacityHidden: 0
    readonly property real shadowOpacityVisible: 0.1
    readonly property int borderWidthHidden: 0
    readonly property int borderWidthVisible: 1
    readonly property int shadowRadiusValue: 40

    // 统一判断是否需要隐藏阴影和边框
    readonly property bool shouldHideEffects: hideShowAnimation.running || dockAnimation.running

    // 阴影和边框控制
    D.DWindow.shadowColor: shouldHideEffects ? Qt.rgba(0, 0, 0, shadowOpacityHidden) : Qt.rgba(0, 0, 0, shadowOpacityVisible)
    D.DWindow.shadowOffset: Qt.point(0, 0)
    D.DWindow.shadowRadius: shadowRadiusValue
    D.DWindow.borderWidth: shouldHideEffects ? borderWidthHidden : borderWidthVisible
    D.DWindow.enableBlurWindow: Qt.platform.pluginName !== "xcb"
    D.DWindow.themeType: Panel.colorTheme
    D.DWindow.borderColor: D.DTK.themeType === D.ApplicationHelper.DarkType ? Qt.rgba(0, 0, 0, dock.blendColorAlpha(0.6) + 20 / 255) : Qt.rgba(0, 0, 0, 0.15)

    // 动画位置控制
    PropertyAnimation {
        id: dockAnimation
        
        property bool useTransformBasedAnimation: false
        property bool isShowing: false
        property int positionForAnimation: Dock.Bottom
        
        from: {
            if (dockAnimation.isShowing) {
                return dockAnimation.useTransformBasedAnimation ? 0 : Panel.dockSize;
            } else {
                if (dockAnimation.useTransformBasedAnimation) {
                    return (dockAnimation.positionForAnimation === Dock.Left || dockAnimation.positionForAnimation === Dock.Top) ? -Panel.dockSize : Panel.dockSize;
                }
                return dockAnimation.useTransformBasedAnimation ? 0 : Panel.dockSize;
            }
        }
        to: {
            if (dockAnimation.isShowing) {
                return dockAnimation.useTransformBasedAnimation ? 0 : Panel.dockSize;
            } else {
                if (dockAnimation.useTransformBasedAnimation) {
                    return (dockAnimation.positionForAnimation === Dock.Left || dockAnimation.positionForAnimation === Dock.Top) ? -Panel.dockSize : Panel.dockSize;
                }
                return 0;
            }
        }
    }
}

6. 总结

这段代码的修改主要是为了优化任务栏动画过程中的视觉效果,但在逻辑一致性和状态管理方面还有改进空间。建议通过提取常量、统一条件判断和增加防御性编程来提高代码质量、性能和安全性。

@sourcery-ai
Copy link

sourcery-ai bot commented Mar 7, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adjusts dock window visual properties and animation size bindings to eliminate ghosting and flashing when changing dock position, especially under Wayland, while preserving normal hide/show behavior.

Sequence diagram for dock position change animations and visual cleanup

sequenceDiagram
  actor User
  participant DockUI
  participant DockAnimation
  participant HideShowAnimation
  participant Window
  participant DWindow

  User->>DockUI: changeDockPosition(newPosition)
  DockUI->>DockAnimation: start(newPosition)
  DockAnimation->>DockUI: updateProperties(positionForAnimation,useTransformBasedAnimation,isShowing)
  DockUI->>Window: requestLayoutUpdate(Panel.dockSize)
  DockUI->>DockUI: computeSizeFrom(useTransformBasedAnimation,isShowing,Panel.dockSize)
  DockUI->>DockUI: computeSizeTo(useTransformBasedAnimation,isShowing,Panel.dockSize)
  Note over DockUI,DWindow: from/to now use Panel.dockSize instead of 0 when not transform based

  DockAnimation->>Window: set running true
  Window->>DWindow: set shadowColor transparent
  Window->>DWindow: set borderWidth 0

  DockAnimation-->>DockUI: animationTick
  DockUI-->>Window: updateGeometryInterpolated

  DockAnimation-->>Window: set running false
  alt hideShowAnimation.running is false
    Window->>DWindow: restore shadowColor default
    Window->>DWindow: restore borderWidth 1
  else hideShowAnimation.running is true
    Window->>DWindow: keep shadowColor transparent
    Window->>DWindow: keep borderWidth 0
  end

  User-->>User: observes smooth transition without ghosting
Loading

Updated class diagram for dock window animations and visual properties

classDiagram
  class Window {
    +QtObject hideShowAnimation
    +QtObject dockAnimation
    +int Panel_dockSize
  }

  class DWindow {
    +color shadowColor
    +point shadowOffset
    +int shadowRadius
    +int borderWidth
    +bool enableBlurWindow
    +int themeType
    +color borderColor
  }

  class DockAnimation {
    +bool running
    +bool isShowing
    +bool useTransformBasedAnimation
    +int positionForAnimation
  }

  class HideShowAnimation {
    +bool running
  }

  class Panel {
    +int dockSize
  }

  Window --> DWindow : sets_properties
  Window --> DockAnimation : observes_running_isShowing
  Window --> HideShowAnimation : observes_running
  Window --> Panel : reads_dockSize

  class DockSizeBinding {
    +int from
    +int to
    +int computeFrom(bool isShowing,bool useTransformBasedAnimation,int Panel_dockSize)
    +int computeTo(bool isShowing,bool useTransformBasedAnimation,int Panel_dockSize)
  }

  Window --> DockSizeBinding : owns_binding
  DockSizeBinding --> DockAnimation : uses_state
  DockSizeBinding --> Panel : uses_dockSize

  DWindow : shadowColor = if hideShowAnimation.running or dockAnimation.running then transparent else rgba(0,0,0,0.1)
  DWindow : borderWidth = if hideShowAnimation.running or dockAnimation.running then 0 else 1

  DockSizeBinding : from = if isShowing then 1 else (if useTransformBasedAnimation then 0 else Panel.dockSize)
  DockSizeBinding : to = if isShowing then (if useTransformBasedAnimation then 0 else Panel.dockSize) else (if useTransformBasedAnimation then +/-Panel.dockSize else 0)
Loading

File-Level Changes

Change Details Files
Extend dock window shadow and border suppression to cover dock position animations, preventing ghost shadows and borders while the window is being moved.
  • Update D.DWindow.shadowColor binding to also disable shadows while dockAnimation.running is true
  • Update D.DWindow.borderWidth binding to also hide borders while dockAnimation.running is true
panels/dock/package/main.qml
Correct dock size animation bindings to use the panel thickness instead of falling back to zero during transform-based dock animations, avoiding visual glitches on position change.
  • Modify animation from value to return Panel.dockSize when transform-based animation is not used instead of always 0
  • Modify animation to value to return Panel.dockSize when showing and transform-based animation is not used instead of always 0
panels/dock/package/main.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:

  • The shadowColor and borderWidth bindings now duplicate the same (hideShowAnimation.running || dockAnimation.running) condition; consider extracting this into a single boolean property (e.g., isAnyDockAnimationRunning) to improve readability and reduce the chance of future divergence.
  • In the animation from/to values that use Panel.dockSize, double-check whether dockSize can change during the animation; if so, consider capturing the starting size or using a binding that reacts safely, to avoid mid-animation jumps or inconsistencies.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The shadowColor and borderWidth bindings now duplicate the same `(hideShowAnimation.running || dockAnimation.running)` condition; consider extracting this into a single boolean property (e.g., `isAnyDockAnimationRunning`) to improve readability and reduce the chance of future divergence.
- In the animation `from`/`to` values that use `Panel.dockSize`, double-check whether `dockSize` can change during the animation; if so, consider capturing the starting size or using a binding that reacts safely, to avoid mid-animation jumps or inconsistencies.

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.

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: BLumia, mhduiy, 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

@robertkill robertkill merged commit b50b1bb into linuxdeepin:master Mar 7, 2026
11 of 12 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.

4 participants