Skip to content

fix(window): preserve maximized state when reactivating minimized window - #612

Merged
pengfeixx merged 1 commit into
linuxdeepin:masterfrom
pengfeixx:fix/window-state-maximized
Apr 28, 2026
Merged

fix(window): preserve maximized state when reactivating minimized window#612
pengfeixx merged 1 commit into
linuxdeepin:masterfrom
pengfeixx:fix/window-state-maximized

Conversation

@pengfeixx

Copy link
Copy Markdown
Contributor

Save window state before activation and skip saveWindowSize/moveToCenter for maximized windows, restore showMaximized in fallback path.

保存窗口状态再激活,最大化窗口跳过 saveWindowSize 和 moveToCenter,
fallback 分支恢复 showMaximized。

Log: 修复最小化后再次打开丢失最大化状态的问题
PMS: BUG-355967
Influence: 修复最大化后最小化再打开窗口状态变为普通窗口的问题。

Save window state before activation and skip saveWindowSize/moveToCenter
for maximized windows, restore showMaximized in fallback path.

保存窗口状态再激活,最大化窗口跳过 saveWindowSize 和 moveToCenter,
fallback 分支恢复 showMaximized。

Log: 修复最小化后再次打开丢失最大化状态的问题
PMS: BUG-355967
Influence: 修复最大化后最小化再打开窗口状态变为普通窗口的问题。
@pengfeixx
pengfeixx force-pushed the fix/window-state-maximized branch from ea8d131 to 590818e Compare April 28, 2026 07:22
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

这段代码主要对 WindowManager::activeOrInitWindow 函数进行了修改,目的是优化窗口激活时的状态处理,特别是针对窗口最大化状态的处理。以下是对该 diff 的详细审查和改进建议:

1. 语法逻辑审查

当前逻辑分析:
代码引入了 wasMaximized 变量来判断窗口在激活前是否处于最大化状态。

  • 路径 A (Utils::activeWindow 成功):
    • 如果窗口最大化 (!wasMaximized),则保存窗口大小并居中。
    • 如果窗口最大化,跳过保存和居中操作。
  • 路径 B (Utils::activeWindow 失败,使用备用方案):
    • 如果窗口最大化,调用 setWindow(window)
    • 调用 window->show()
    • 如果窗口最大化,额外调用 window->showMaximized()
    • 最后执行 raise()activateWindow()

潜在逻辑问题:
路径 B 中,window->show()window->showMaximized() 的调用顺序可能导致视觉上的闪烁。

  • wasMaximized 为真时,代码先调用 show()(此时窗口可能以普通大小显示一瞬间),紧接着调用 showMaximized()(窗口变为最大化)。这种快速切换在性能较差的机器上可能被肉眼捕捉到。

改进建议:
建议在路径 B 中,根据 wasMaximized 状态分流显示逻辑,避免先显示普通大小再显示最大化的冗余操作。

2. 代码质量审查

优点:

  • 使用了 Q_LIKELY 宏来提示编译器优化分支预测,这是很好的实践。
  • 引入了 wasMaximized 变量,使得代码意图比原来更加清晰,且避免了重复判断。
  • 日志输出 (qCDebug) 保留了关键信息,有助于调试。

改进建议:

  • 代码复用:路径 A 和路径 B 中对 wasMaximized 的判断逻辑虽然独立,但都是为了处理“最大化窗口不应被移动或重置大小”这一规则。目前的写法已经比较清晰,但可以考虑提取公共逻辑(不过在这个场景下,提取可能不会显著提高可读性)。
  • 注释:原有的注释 2020-01-15 kyz ... 比较旧且冗长,建议更新注释以解释当前引入 wasMaximized 的原因,即“防止最大化窗口在激活时被意外还原或移动”。

3. 代码性能审查

  • 性能影响:引入 wasMaximized 只是增加了一次位运算 (&) 和布尔判断,性能开销极小,可以忽略不计。
  • 位运算window->windowState() & Qt::WindowMaximized 是高效的判断方式。

4. 代码安全审查

  • 线程安全:代码开头有 QMutexLocker locker(&_mutex);,确保了对 window 对象操作的线程安全,这是非常正确的做法。
  • 空指针检查:虽然 diff 中未显示 window 的定义,但上下文 if (window != nullptr) 表明已经进行了空指针保护。

综合改进后的代码示例

针对上述提到的“闪烁”问题,建议对 路径 B 的逻辑做微调:

void WindowManager::activeOrInitWindow()
{
    QMutexLocker locker(&_mutex);
    if (window != nullptr) {
        // 记录窗口当前是否处于最大化状态
        bool wasMaximized = window->windowState() & Qt::WindowMaximized;

        // 优先尝试通过 Dock 接口激活
        if (Q_LIKELY(Utils::activeWindow(window->winId()))) {
            qCDebug(app) << "Window activated via Utils::activeWindow, winId:" << window->winId();
            if (!wasMaximized) {
                window->saveWindowSize();
                Dtk::Widget::moveToCenter(window);
            } else {
                qCDebug(app) << "Window was maximized, skipping saveWindowSize and moveToCenter";
            }
        } else {
            // 备用激活方案
            qCDebug(app) << "Fallback activation method for winId:" << window->winId();
            
            // 根据状态选择显示方式,避免 show() 和 showMaximized() 同时调用导致的闪烁
            if (wasMaximized) {
                window->showMaximized();
            } else {
                setWindow(window); // 假设 setWindow 仅在非最大化时需要设置特定属性
                window->show();
            }
            
            window->raise();
            window->activateWindow();
            qCDebug(app) << "Window shown and activated, wasMaximized:" << wasMaximized;
        }
        window->openjsPage(curr_app_name_, curr_title_name_);
        qCDebug(app) << "openjsPage end";
    }
}

总结

这段 diff 的修改方向是正确的,有效地解决了最大化窗口在激活时可能出现的布局问题。主要建议集中在优化备用激活路径中的显示逻辑,以消除潜在的界面闪烁,并更新相关注释以反映代码的最新意图。

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: lzwind, pengfeixx

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

@pengfeixx
pengfeixx merged commit 9a3c045 into linuxdeepin:master Apr 28, 2026
16 of 18 checks passed
@pengfeixx
pengfeixx deleted the fix/window-state-maximized branch April 28, 2026 07:44
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