Skip to content

fix: resolve flickering and position shift when switching panel popups#1576

Merged
deepin-bot[bot] merged 1 commit intolinuxdeepin:masterfrom
18202781743:master
Apr 29, 2026
Merged

fix: resolve flickering and position shift when switching panel popups#1576
deepin-bot[bot] merged 1 commit intolinuxdeepin:masterfrom
18202781743:master

Conversation

@18202781743
Copy link
Copy Markdown
Contributor

Refactor the open/close mechanism for PanelPopup, PanelMenu, and
PanelToolTip to eliminate visual flickering and incorrect positioning
that occurred when rapidly switching between popups. The previous
implementation used a timer-based delayed opening approach, which
could cause the old popup to close and the new one to appear at an
intermediate frame with incorrect geometry.

Changes:

  1. Replaced Timer-based delayed opening with a geometry update callback
    mechanism
  2. Added openPending property to track pending operations
  3. Added finalizeOpen() function to complete opening after geometry
    update
  4. Added onUpdateGeometryFinished signal handling to coordinate
    opening with geometry updates
  5. Removed delayed: true from x/y Binding properties for immediate
    position updates
  6. Added proper handling for reopening when popup is already visible
  7. Added geometryUpdatePending guard in PanelPopupWindow to prevent
    duplicate updates
  8. Added default initialization values for m_dragging and m_pressing
    in popupwindow.h
  9. Fixed trailing newline issue in PanelPopupWindow.qml

Log: Fixed popup flickering and position issues when switching panels

Influence:

  1. Test rapid switching between multiple popups/menus/tooltips
  2. Verify popup open/close animations are smooth without flickering
  3. Test popup positioning accuracy when opened from different screen
    locations
  4. Verify that popups close properly when clicking outside or switching
    focus
  5. Test the "reopen" scenario: close a popup and immediately open the
    same or a different one
  6. Verify that the X11 grab focus transition works correctly after this
    change
  7. Test on both X11 and Wayland sessions if applicable

fix: 解决面板弹窗切换时的闪烁和位置偏移问题

重构PanelPopup、PanelMenu和PanelToolTip的打开/关闭机制,消除快速切换弹窗
时出现的视觉闪烁和位置错误。之前的实现使用基于定时器的延迟打开方式,可能
导致旧弹窗关闭后新弹窗在中间帧显示错误的几何位置。

变更内容:

  1. 将基于Timer的延迟打开替换为几何更新回调机制
  2. 添加openPending属性跟踪待处理操作
  3. 添加finalizeOpen()函数在几何更新完成后完成打开操作
  4. 添加onUpdateGeometryFinished信号处理,协调打开与几何更新
  5. 从x/y绑定属性中移除delayed: true,实现即时位置更新
  6. 添加弹窗已可见时重新打开的正确处理
  7. 在PanelPopupWindow中添加geometryUpdatePending防护,防止重复更新
  8. 在popupwindow.h中为m_draggingm_pressing添加默认初始化值
  9. 修复PanelPopupWindow.qml中缺失的换行符

Log: 修复面板切换时弹窗闪烁和位置问题

Influence:

  1. 测试多个弹窗/菜单/提示框之间的快速切换
  2. 验证弹窗打开/关闭动画是否流畅无闪烁
  3. 测试从不同屏幕位置打开时弹窗定位的准确性
  4. 验证点击外部区域或切换焦点时弹窗是否正确关闭
  5. 测试"重新打开"场景:关闭弹窗后立即打开相同或不同的弹窗
  6. 验证此更改后X11抓取焦点过渡功能是否正常工作
  7. 如适用,在X11和Wayland会话上测试

Copy link
Copy Markdown

@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

@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

@deepin-bot
Copy link
Copy Markdown

deepin-bot Bot commented Apr 29, 2026

TAG Bot

New tag: 2.0.39
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #1580

Refactor the open/close mechanism for PanelPopup, PanelMenu, and
PanelToolTip to eliminate visual flickering and incorrect positioning
that occurred when rapidly switching between popups. The previous
implementation used a timer-based delayed opening approach, which
could cause the old popup to close and the new one to appear at an
intermediate frame with incorrect geometry.

Changes:
1. Replaced Timer-based delayed opening with a geometry update callback
mechanism
2. Added `openPending` property to track pending operations
3. Added `finalizeOpen()` function to complete opening after geometry
update
4. Added `onUpdateGeometryFinished` signal handling to coordinate
opening with geometry updates
5. Removed `delayed: true` from x/y Binding properties for immediate
position updates
6. Added proper handling for reopening when popup is already visible
7. Added `geometryUpdatePending` guard in PanelPopupWindow to prevent
duplicate updates
8. Added default initialization values for `m_dragging` and `m_pressing`
in popupwindow.h
9. Fixed trailing newline issue in PanelPopupWindow.qml

Log: Fixed popup flickering and position issues when switching panels

Influence:
1. Test rapid switching between multiple popups/menus/tooltips
2. Verify popup open/close animations are smooth without flickering
3. Test popup positioning accuracy when opened from different screen
locations
4. Verify that popups close properly when clicking outside or switching
focus
5. Test the "reopen" scenario: close a popup and immediately open the
same or a different one
6. Verify that the X11 grab focus transition works correctly after this
change
7. Test on both X11 and Wayland sessions if applicable

fix: 解决面板弹窗切换时的闪烁和位置偏移问题

重构PanelPopup、PanelMenu和PanelToolTip的打开/关闭机制,消除快速切换弹窗
时出现的视觉闪烁和位置错误。之前的实现使用基于定时器的延迟打开方式,可能
导致旧弹窗关闭后新弹窗在中间帧显示错误的几何位置。

变更内容:
1. 将基于Timer的延迟打开替换为几何更新回调机制
2. 添加`openPending`属性跟踪待处理操作
3. 添加`finalizeOpen()`函数在几何更新完成后完成打开操作
4. 添加`onUpdateGeometryFinished`信号处理,协调打开与几何更新
5. 从x/y绑定属性中移除`delayed: true`,实现即时位置更新
6. 添加弹窗已可见时重新打开的正确处理
7. 在PanelPopupWindow中添加`geometryUpdatePending`防护,防止重复更新
8. 在popupwindow.h中为`m_dragging`和`m_pressing`添加默认初始化值
9. 修复PanelPopupWindow.qml中缺失的换行符

Log: 修复面板切换时弹窗闪烁和位置问题

Influence:
1. 测试多个弹窗/菜单/提示框之间的快速切换
2. 验证弹窗打开/关闭动画是否流畅无闪烁
3. 测试从不同屏幕位置打开时弹窗定位的准确性
4. 验证点击外部区域或切换焦点时弹窗是否正确关闭
5. 测试"重新打开"场景:关闭弹窗后立即打开相同或不同的弹窗
6. 验证此更改后X11抓取焦点过渡功能是否正常工作
7. 如适用,在X11和Wayland会话上测试
@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

这份代码修改主要涉及了 Qt/QML 中的窗口管理逻辑,特别是针对 PanelMenuPanelPopupPanelToolTip 组件的显示、隐藏和几何更新机制。以下是对代码的审查意见:

1. 语法逻辑

优点:

  • 初始化成员变量:在 popupwindow.h 中,m_draggingm_pressing 被显式初始化为 false。这是一个好的实践,避免了未定义行为。
  • 状态管理改进:引入了 openPending 标志位,用于跟踪窗口打开请求的状态,避免了在窗口未准备好时进行操作。
  • 异步操作优化:使用 Qt.callLater 替代了 Timer,使代码更加简洁,且避免了不必要的定时器开销。

潜在问题:

  • finalizeOpen 的重复逻辑PanelMenu.qmlPanelPopup.qmlPanelToolTip.qml 中都实现了类似的 finalizeOpen 函数。可以考虑将其提取为基类或共享组件,以减少代码重复。
  • readyBinding 的依赖readyBinding 是一个动态绑定的属性,依赖于 menuWindowcurrentItem。如果 menuWindow 被销毁或 currentItem 被意外修改,可能会导致 readyBinding 失效,进而影响窗口的显示逻辑。建议增加更多的边界检查。

2. 代码质量

优点:

  • 移除 delayed: true:在 PanelMenu.qmlPanelPopup.qml 中,移除了 Bindingdelayed: true 属性。这可能是为了优化性能,因为 delayed 会导致绑定值的更新延迟到下一个事件循环,可能会引入不必要的延迟。
  • 统一的几何更新机制:通过 requestUpdateGeometryupdateGeometryFinished 信号,统一了窗口几何更新的流程,使代码更加清晰。

改进建议:

  • 代码复用PanelMenu.qmlPanelPopup.qmlPanelToolTip.qml 中有大量重复的逻辑(如 openclosefinalizeOpen)。可以考虑将这些逻辑提取到一个基类或共享组件中。
  • 注释:部分逻辑(如 openPending 的作用)缺少注释,建议添加注释以提高代码的可读性。

3. 代码性能

优点:

  • 减少定时器使用:用 Qt.callLater 替代了 Timer,减少了定时器的开销。
  • 避免重复几何更新:在 PanelPopupWindow.qml 中,通过 geometryUpdatePending 标志位避免了重复的几何更新请求。

改进建议:

  • 绑定优化readyBinding 是一个动态绑定,每次 menuWindowcurrentItem 变化时都会重新计算。如果这些属性变化频繁,可能会影响性能。可以考虑使用更高效的状态管理机制(如 QtObjectStateGroup)。

4. 代码安全

优点:

  • 边界检查:在多个地方增加了对 menuWindowpopupWindowtoolTipWindow 的空指针检查,提高了代码的健壮性。
  • 状态一致性:通过 openPendingreadyBinding 确保了窗口状态的一致性,避免了在窗口未准备好时进行操作。

潜在问题:

  • 竞态条件Qt.callLater 是异步的,如果在异步操作完成前 menuWindowcurrentItem 被修改,可能会导致窗口状态不一致。建议在异步操作中增加更多的状态检查。
  • 内存泄漏风险:如果 menuWindowpopupWindowtoolTipWindow 被销毁,但 Connections 仍然存在,可能会导致内存泄漏。建议在 Connections 中增加对目标对象生命周期的检查。

5. 具体改进建议

5.1 提取共享逻辑

可以将 PanelMenu.qmlPanelPopup.qmlPanelToolTip.qml 中的共享逻辑提取到一个基类或共享组件中。例如:

// BasePopup.qml
QtObject {
    id: control
    property bool openPending: false
    property bool readyBinding: false
    property Item window

    function finalizeOpen() {
        if (!window || !openPending || !readyBinding || window.currentItem !== control)
            return

        openPending = false
        window.title = windowTitle
        window.show()
    }
}

然后在 PanelMenu.qmlPanelPopup.qmlPanelToolTip.qml 中继承或使用这个基类。

5.2 增加注释

在关键逻辑处增加注释,例如:

// Indicates whether a window open request is pending.
property bool openPending: false

5.3 优化绑定

可以考虑使用 QtObjectStateGroup 来管理窗口状态,减少动态绑定的开销。例如:

QtObject {
    id: stateManager
    property bool isReady: menuWindow && menuWindow.currentItem === control
}

然后在 Binding 中使用 stateManager.isReady 替代 readyBinding

总结

这份代码修改在语法逻辑、代码质量、性能和安全性方面都有所改进,但仍有一些可以优化的地方。主要的改进方向包括减少代码重复、优化绑定机制、增加注释和边界检查。通过这些改进,可以进一步提高代码的可维护性和健壮性。

@18202781743
Copy link
Copy Markdown
Contributor Author

/forcemerge

@deepin-bot
Copy link
Copy Markdown

deepin-bot Bot commented Apr 29, 2026

This pr force merged! (status: blocked)

@deepin-bot deepin-bot Bot merged commit 2155809 into linuxdeepin:master Apr 29, 2026
9 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