Skip to content

fix: load pending tab when focus tab file is deleted - #710

Open
pengfeixx wants to merge 1 commit into
linuxdeepin:masterfrom
pengfeixx:agent/agent/e239d5659e54
Open

pengfeixx wants to merge 1 commit into
linuxdeepin:masterfrom
pengfeixx:agent/agent/e239d5659e54

Conversation

@pengfeixx

@pengfeixx pengfeixx commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Root Cause Analysis

When the editor restarts and recoverFile() restores tabs, if the focus tab's file has been deleted or moved, it is skipped via continue. The remaining non-focus tabs are added via addPendingTab(), which blocks signals and calls setCurrentIndex(0). When only one pending tab remains (the 2-file scenario), currentIndex is already 0, so the fallback activeTab(0) → setCurrentIndex(0) does not emit currentChanged. As a result, handleCurrentChanged() never fires, loadPendingTab() is never triggered, and the tab stays in pending state with no EditWrapper — the user cannot edit.

Key evidence: src/startmanager.cpp:509-512 (fallback branch), src/widgets/window.cpp:3328-3340 (addPendingTab blocks signals), src/widgets/window.cpp:677-682 (activeTab calls setCurrentIndex).

Fix

In the fallback branch of recoverFile(), after activeTab(0), explicitly check if the first tab is a pending tab and call loadPendingTab() to trigger loading. This ensures the EditWrapper is created even when currentChanged was not emitted.

Change Safety Assessment

Code Safety

  • Risk Level: Low
  • Target lines (509-511) originate from feature commit "wip: lazy tab restore for faster startup" (ee54acf), not a bug fix — this change does not revert any historical fix
  • The new code calls existing public methods isPendingTab() and loadPendingTab() which have internal existence checks and failure handling; no signature changes

Business Impact Scope

Affected module: tab recovery on editor startup. When the focus tab's file is deleted/moved externally, the remaining tabs now load correctly. No impact on normal tab recovery flow.

Verification Suggestion

Test the original bug scenario: open 2 files, delete/move focus file A, restart editor, verify file B is editable. Also verify normal multi-file restart has no regression.


根因分析

编辑器重启时 recoverFile() 恢复标签页,若焦点标签页文件已被删除或移动,则通过 continue 跳过。剩余非焦点标签页通过 addPendingTab() 添加,该方法阻塞信号并调用 setCurrentIndex(0)。当仅剩 1 个待加载标签页(2 文件场景)时,currentIndex 已为 0,兜底代码 activeTab(0) → setCurrentIndex(0) 不发射 currentChanged 信号,导致 handleCurrentChanged() 永不被调用,loadPendingTab() 永不触发,编辑区域无 EditWrapper,用户无法编辑。

关键证据:src/startmanager.cpp:509-512(兜底分支)、src/widgets/window.cpp:3328-3340(addPendingTab 阻塞信号)、src/widgets/window.cpp:677-682(activeTab 调用 setCurrentIndex)。

修复方案

在 recoverFile() 兜底分支 activeTab(0) 之后,显式检查首个标签页是否为待加载状态,若是则调用 loadPendingTab() 触发加载,确保即使 currentChanged 未发射也能创建 EditWrapper。

改动安全评估

代码安全评估

  • 风险等级: 低风险
  • 目标行(509-511)来自功能引入 commit "wip: lazy tab restore for faster startup"(ee54acfc),非 bug 修复产物——本次改动不撤销任何历史修复
  • 新增代码调用已有公开方法 isPendingTab() 和 loadPendingTab(),二者内部有文件存在性检查和失败处理;无签名变更

业务影响范围

受影响模块:编辑器启动时标签页恢复。当焦点标签页文件被外部删除/移动后,剩余标签页现在能正确加载。对正常标签页恢复流程无影响。

验证建议

测试原 bug 场景:打开 2 个文件,删除/移动焦点文件 A,重启编辑器,验证 B 文件可编辑。同时验证正常多文件重启无回归。

Summary by Sourcery

Bug Fixes:

  • Ensure the first recoverable tab is loaded when the focused tab is unavailable, including cases where no tab-change signal is emitted.

1. Root cause: recoverFile() skips deleted focus tab via continue,
   remaining tabs added via addPendingTab() which blocks signals and
   calls setCurrentIndex(0) without emitting currentChanged
2. Fix: in fallback branch after activeTab(0), explicitly check if
   first tab is pending and call loadPendingTab() to trigger loading
3. Impact: only affects fallback path when focus tab file is missing,
   no behavior change for normal tab recovery flow

Log: Fix unable to edit when focus tab file is deleted or moved

Influence:
1. Test opening 2 files, delete focus file A, restart editor, verify
   file B is editable
2. Test opening 3+ files, delete focus file, restart, verify all
   remaining files are editable
3. Test normal multi-file restart, verify all tabs recover correctly

fix: 焦点标签页文件被删除后加载待加载标签页

1. 根因:recoverFile() 通过 continue 跳过已删除的焦点标签页,
   剩余标签页经 addPendingTab() 添加时阻塞信号且调用
   setCurrentIndex(0) 不发射 currentChanged 信号
2. 方案:在兜底分支 activeTab(0) 之后,显式检查首个标签页是否
   为待加载状态,若是则调用 loadPendingTab() 触发加载
3. 影响:仅影响焦点标签页文件缺失时的兜底路径,对正常标签页
   恢复流程无行为变化

Log: 修复焦点标签页文件被删除或移动后无法编辑的问题

Influence:
1. 测试打开 2 个文件,删除焦点文件 A,重启编辑器,验证 B 文件可编辑
2. 测试打开 3+ 个文件,删除焦点文件,重启编辑器,验证所有剩余文件可编辑
3. 测试正常多文件重启,验证所有标签页正常恢复

PMS: BUG-376141
@pengfeixx
pengfeixx marked this pull request as draft November 2, 2026 16:26
@sourcery-ai

sourcery-ai Bot commented Nov 2, 2026

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Fixes startup tab recovery for the case where the focused file was deleted or moved by directly loading the first pending tab after fallback activation, avoiding reliance on a suppressed or unchanged currentChanged signal.

Sequence diagram for fallback tab recovery after focus file deletion

sequenceDiagram
    participant StartManager
    participant Window
    participant Tabbar
    participant PendingTab
    participant EditWrapper

    StartManager->>Window: activeTab(0)
    Window->>Tabbar: fileAt(0)
    Tabbar-->>Window: firstFile
    Window->>PendingTab: isPendingTab(firstFile)
    PendingTab-->>Window: true
    Window->>PendingTab: loadPendingTab(firstFile)
    PendingTab->>EditWrapper: create EditWrapper
    EditWrapper-->>PendingTab: loaded
Loading

File-Level Changes

Change Details Files
Explicitly loads the first recovered pending tab when fallback tab activation does not emit a current-tab change signal.
  • Activates the first tab in the no-focus recovery path.
  • Retrieves the first tab’s file and checks whether it is pending.
  • Calls pending-tab loading directly so the editor wrapper is created.
src/startmanager.cpp

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

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

@pengfeixx
pengfeixx marked this pull request as ready for review November 3, 2026 05:47
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

🤖 AI 代码审查报告

总体评分: 100 分 (通过阈值: 70分)

Pass


📊 总体评价

项目 结果
审查结论 代码审查通过
评分详情 本次变更为 deepin-editor 的 Bug 修复,在 recoverFile 函数中当焦点标签页文件被删除时, 对回退加载的第一个标签页增加 pending tab 检测与加载逻辑。变更仅新增 4 行代码, 语法正确、逻辑清晰、无性能影响、无安全漏洞。启发式扫描、OCR 审查与 AI 四维度分析 均未发现问题。

🔍 详细分析

1. 语法逻辑 ✅

评价: 语法正确,逻辑清晰 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: []


2. 代码质量 ✅

评价: 代码结构清晰,注释完整 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: []


3. 代码性能 ✅

评价: 性能良好,资源使用合理 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: []


4. 代码安全 🔒

评价: 存在0个安全漏洞 ✅ 通过

🔐 发现 0 个安全漏洞

安全漏洞详情:
✅ 未发现安全漏洞

建议: []


💡 改进建议代码示例


本报告由 AI 代码审查工具自动生成

@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

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