Skip to content

feat: recalculate dock window rect on screen geometry change#1591

Merged
wjyrich merged 1 commit intolinuxdeepin:masterfrom
wjyrich:fix-bug-389279
May 8, 2026
Merged

feat: recalculate dock window rect on screen geometry change#1591
wjyrich merged 1 commit intolinuxdeepin:masterfrom
wjyrich:fix-bug-389279

Conversation

@wjyrich
Copy link
Copy Markdown
Contributor

@wjyrich wjyrich commented May 8, 2026

Connect to screen geometry change signals to ensure the dock panel recalculates its window rectangle when the primary screen position changes. Previously, the dock window geometry would not update when the screen moved, causing display issues.

Log: Fixed dock panel not updating position when screen geometry changes

Influence:

  1. Test dock panel position after changing primary display settings
  2. Verify dock window updates when monitor arrangement is modified
  3. Test dock behavior with multi-monitor configurations

feat: 屏幕几何变化时重新计算停靠栏窗口区域

连接屏幕几何变化信号,确保当主屏位置发生变化时停靠栏能重新计算窗口矩形。
之前屏幕移动时停靠栏窗口几何不会更新,导致显示异常。

Log: 修复屏幕几何变化时停靠栏位置不更新的问题

Influence:

  1. 测试更改主显示器设置后停靠栏的位置更新
  2. 验证修改显示器排列时停靠栏窗口的响应
  3. 测试多显示器配置下停靠栏的行为表现

PMS: TASK-389279

Connect to screen geometry change signals to ensure the dock panel
recalculates its window rectangle when the primary screen position
changes. Previously, the dock window geometry would not update when the
screen moved, causing display issues.

Log: Fixed dock panel not updating position when screen geometry changes

Influence:
1. Test dock panel position after changing primary display settings
2. Verify dock window updates when monitor arrangement is modified
3. Test dock behavior with multi-monitor configurations

feat: 屏幕几何变化时重新计算停靠栏窗口区域

连接屏幕几何变化信号,确保当主屏位置发生变化时停靠栏能重新计算窗口矩形。
之前屏幕移动时停靠栏窗口几何不会更新,导致显示异常。

Log: 修复屏幕几何变化时停靠栏位置不更新的问题

Influence:
1. 测试更改主显示器设置后停靠栏的位置更新
2. 验证修改显示器排列时停靠栏窗口的响应
3. 测试多显示器配置下停靠栏的行为表现

PMS: TASK-389279
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 @wjyrich, 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

deepin pr auto review

这段代码主要是在 DockPanel::init() 函数中增加了对屏幕几何信息变化的监听,以便在主屏位置变化时重新计算 frontendWindowRect。以下是对这段代码的详细审查意见:

1. 语法逻辑审查

现状
代码逻辑上,当 window() 存在且 window()->screen() 存在时,连接了 QScreen::geometryChanged 信号到 DockPanel::onWindowGeometryChanged 槽函数。

潜在问题

  1. 对象生命周期与连接管理

    • window() 返回的 QWindow 指针在程序运行过程中可能会改变(例如窗口从一个屏幕移动到另一个屏幕)。
    • 当窗口切换屏幕时,旧的 QScreen 对象可能仍然存在,但不再与该窗口关联。此时,如果不断开旧的连接,可能会产生无效的信号调用,或者导致逻辑混乱。
    • 当前代码只在 init 中连接了一次,没有处理窗口切换屏幕的情况。
  2. 内存泄漏风险

    • 如果 DockPanel 对象的生命周期短于 QScreen 对象,且使用了 Qt::AutoConnection(默认),通常问题不大。但如果是跨线程或特定场景,需要确保连接在对象析构时被正确断开。

2. 代码质量审查

改进建议

  1. 增加屏幕切换的处理

    • 应该监听 QWindow::screenChanged 信号。当窗口所属屏幕改变时,先断开旧屏幕的连接,再连接新屏幕的信号。
    • 这样可以确保始终监听的是当前窗口所在屏幕的几何变化。
  2. 空指针检查

    • 当前使用了 if (auto screen = window()->screen()),这很好,但建议在 connect 之前也确保 this 指针有效(虽然在 init 中通常有效)。

3. 代码性能审查

现状

  • 信号槽连接本身开销很小。
  • geometryChanged 信号可能在用户拖动显示器设置、改变分辨率或缩放比例时触发,频率不高。

改进建议

  • 无明显性能问题。但在 onWindowGeometryChanged 槽函数中,应避免执行耗时操作,因为界面变化可能需要快速响应。

4. 代码安全审查

潜在风险

  1. 多次连接风险

    • 如果 init() 被多次调用(虽然通常只调用一次),会导致同一个信号被连接多次,槽函数会被执行多次。建议使用 Qt::UniqueConnection 标志,或者在连接前先断开。
  2. 旧连接未断开

    • 如前所述,如果窗口切换屏幕,旧屏幕的 geometryChanged 信号仍然连接着 DockPanel,这可能导致在非当前屏幕变化时触发了计算逻辑,产生错误数据。

5. 改进后的代码建议

为了解决上述问题,建议将屏幕监听逻辑封装或完善,处理屏幕切换的情况。以下是改进后的代码示例:

// 在头文件 DockPanel.h 中声明槽函数
// private slots:
//     void handleScreenChanged(QScreen *screen);
//     void onWindowGeometryChanged();

// 在 DockPanel.cpp 中实现

bool DockPanel::init()
{
    // ... 其他初始化代码 ...

    if (window()) {
        // 1. 处理初始屏幕
        handleScreenChanged(window()->screen());

        // 2. 监听窗口屏幕变化信号
        // 注意:使用 UniqueConnection 防止重复连接(如果 init 可能被多次调用)
        connect(window(), &QWindow::screenChanged, this, &DockPanel::handleScreenChanged, Qt::UniqueConnection);
        
        rootObject()->installEventFilter(this);
        Q_EMIT devicePixelRatioChanged(window()->devicePixelRatio());
    }
    return true;
}

void DockPanel::handleScreenChanged(QScreen *screen)
{
    // 1. 断开旧屏幕的连接(如果有)
    // 我们需要存储旧的 QScreen 指针,或者通过某种方式找到它。
    // 这里假设我们无法直接获取旧指针,通常的做法是在类成员中保存当前 m_currentScreen。
    
    if (m_currentScreen) {
        disconnect(m_currentScreen, &QScreen::geometryChanged, this, &DockPanel::onWindowGeometryChanged);
    }

    // 2. 更新当前屏幕指针
    m_currentScreen = screen;

    // 3. 连接新屏幕的信号
    if (m_currentScreen) {
        connect(m_currentScreen, &QScreen::geometryChanged, this, &DockPanel::onWindowGeometryChanged);
        
        // 4. 屏幕切换后,立即触发一次几何更新,确保状态同步
        // 假设 onWindowGeometryChanged 会读取当前 geometry 并更新
        QMetaObject::invokeMethod(this, "onWindowGeometryChanged", Qt::QueuedConnection);
    }
}

6. 总结

原代码在简单的场景下可以工作,但在处理多显示器、热插拔显示器或窗口跨屏移动时存在逻辑缺陷(未断开旧连接)。
核心改进点

  1. 必须监听 QWindow::screenChanged 以处理窗口跨屏移动。
  2. 必须在切换屏幕时断开旧屏幕的 geometryChanged 信号,并连接新屏幕的信号。
  3. 引入成员变量 m_currentScreen 来管理当前连接的屏幕对象,便于断开连接。
  4. 使用 Qt::UniqueConnection 防止信号槽的重复连接。

@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: BLumia, wjyrich

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

@wjyrich wjyrich merged commit c0cddd1 into linuxdeepin:master May 8, 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.

3 participants