Skip to content

fix: delay discovery service init to prevent focus stealing#726

Merged
re2zero merged 1 commit intolinuxdeepin:masterfrom
re2zero:fix/pms-355969-discovery-focus
Apr 28, 2026
Merged

fix: delay discovery service init to prevent focus stealing#726
re2zero merged 1 commit intolinuxdeepin:masterfrom
re2zero:fix/pms-355969-discovery-focus

Conversation

@re2zero
Copy link
Copy Markdown
Contributor

@re2zero re2zero commented Apr 28, 2026

Summary

  • Fix PMS Bug #355969: password input box not editable by default when opening cooperation
  • Delay DiscoverController::init() to after main window show() via QTimer::singleShot(500ms)
  • Prevents main window from stealing focus from discovery/auth dialogs

Root Cause

CooperaionCorePlugin::start() called DiscoverController::init() before dMain->show(). When the discovery service dialog was shown (blocking exec()), after it closed the main window appeared and stole focus from subsequent input dialogs.

Test Plan

  • Open cooperation when Avahi service is NOT running
  • Verify main window appears first, then discovery service dialog
  • Verify password/input fields are focusable and editable
  • Verify discovery still works correctly after confirming the dialog

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 @re2zero, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@re2zero re2zero force-pushed the fix/pms-355969-discovery-focus branch from 207da17 to 3f36d14 Compare April 28, 2026 06:02
Move DiscoverController::init() call to after dMain->show() with
500ms delay via QTimer::singleShot, ensuring main window is visible
before any discovery/auth dialogs appear.

延迟发现服务初始化至主窗口显示之后,避免主窗口抢占授权框焦点。

Log: 延迟发现服务弹框,修复焦点抢占
PMS: BUG-355969
Influence: 打开跨端协同时密码输入框默认可输入,不再被主窗口抢焦点
@re2zero re2zero force-pushed the fix/pms-355969-discovery-focus branch from 3f36d14 to 694f58f Compare April 28, 2026 06:08
@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

代码审查报告

经过对提供的 git diff 输出进行审查,以下是关于语法逻辑、代码质量、代码性能和代码安全方面的详细分析和改进建议。

1. 语法逻辑

  • 版权年份更新

    • 变更SPDX-FileCopyrightText2023 - 2024 更新为 2023 - 2026
    • 分析:这是合法的,通常用于提前声明版权有效期。逻辑上没有问题。
  • 头文件包含

    • 变更:添加了 #include <QTimer>
    • 分析:因为代码中使用了 QTimer::singleShot,所以必须包含此头文件。逻辑正确。
  • 初始化逻辑重构(核心变更)

    • 变更:将 DiscoverController::instance()->init() 从函数前部的同步调用移到了函数末尾,并包裹在 QTimer::singleShot(500, ...) 中,且增加了 !onlyTransfer 的条件判断。
    • 分析
      • 逻辑意图:注释说明是为了“延迟发现初始化以确保主窗口先可见,防止发现/认证对话框抢夺焦点”。这是一个合理的 UI 交互优化逻辑。
      • 条件判断:增加了 if (!onlyTransfer) 判断。这意味着如果是“仅传输模式”(onlyTransfer 为真),则跳过发现服务的初始化。这对于纯文件传输场景是有意义的,可以节省资源并避免不必要的网络广播。
      • 时序问题:原代码在初始化网络监听器之前初始化发现控制器。新代码在网络监听器初始化之后、主窗口显示之后(或同时)延迟初始化发现控制器。这种顺序调整符合 UI 优先、后台服务随后加载的逻辑。

2. 代码质量

  • 可读性与注释
    • 新增的注释 // Delay discovery init to ensure main window is visible first... 非常清晰,解释了“为什么”要这样做,而不仅仅是“做了什么”。这提高了代码的可维护性。
  • 魔法数字
    • 问题QTimer::singleShot(500, ...) 中的 500 毫秒是一个“魔法数字”。
    • 建议:建议将其定义为一个具名常量,例如 const int kDiscoveryInitDelayMs = 500;,或者如果这是项目通用的延迟时间,应使用项目统一的常量定义。这样便于后续调整延迟时间,而无需在代码中查找替换。
  • Lambda 表达式
    • Lambda 表达式 []() { ... } 捕获了空列表。这意味着它不捕获局部变量。由于它调用的是单例 DiscoverController::instance() 和日志宏,这是安全且正确的。

3. 代码性能

  • 异步加载
    • 优点:通过 QTimer::singleShotDiscoverController 的初始化推迟到事件循环处理 500ms 后执行。这使得 CooperaionCorePlugin::start() 函数能更快返回,主窗口能更早地显示给用户,从而显著提升应用的“感知启动速度”。
    • 潜在开销:虽然 QTimer 的开销很小,但引入了额外的调度延迟。不过,对于发现服务这种非关键路径的初始化,这种权衡是值得的。
  • 资源利用
    • onlyTransfer 模式下跳过发现初始化,避免了 ZeroConf (mDNS/Bonjour) 服务的启动和网络广播,减少了 CPU 和网络带宽的消耗。

4. 代码安全

  • 对象生命周期
    • QTimer::singleShot 接收的接收者是 this(即 CooperaionCorePlugin 实例)。如果 CooperaionCorePlugin 在 500 毫秒内被销毁,定时器会自动取消,回调不会执行。这是 Qt 机制保证的安全行为。
  • 线程安全
    • QTimer::singleShot 默认在接收者所在的线程(此处为主线程)执行回调。DiscoverController 的初始化涉及 UI 和网络操作,必须在主线程执行。当前的实现保证了线程安全性。
  • 逻辑安全性
    • 潜在风险:如果 DiscoverController::instance()->init() 本身不是幂等的(即多次调用会导致副作用),而由于某种原因(如代码逻辑变更)导致这段代码被执行两次,可能会有问题。
    • 现状:通常 init() 函数设计为幂等或具有防重复调用标志(如 static bool initialized = false;)。假设 DiscoverController 的实现是标准的,这里没有直接的安全隐患。但建议确认 DiscoverController::init() 内部是否有防重入保护。

总结与改进建议

这段代码变更主要是为了优化用户体验(防止焦点抢夺)和性能(按需加载、异步初始化)。整体逻辑清晰,改动合理。

改进建议:

  1. 消除魔法数字
    500 提取为常量,增强可读性。

    // 在类定义或匿名命名空间中
    static constexpr int kDiscoveryInitDelayMs = 500;
    
    // 在使用处
    QTimer::singleShot(kDiscoveryInitDelayMs, this, []() { ... });
  2. 确认 init() 的幂等性
    虽然目前逻辑看起来只会在启动时调用一次,但为了代码的健壮性,建议检查 DiscoverController::init() 的实现,确保即使被多次调用也不会导致资源泄漏或逻辑错误(例如重复注册服务)。

  3. 日志级别
    DLOG 通常用于调试日志。在初始化完成时,如果这是一个关键路径,可以考虑使用 qInfo 或项目特定的 Info 级别日志,以便在发布版中也能追踪启动流程。如果仅用于调试,现状即可。

  4. 拼写检查
    类名 CooperaionCorePlugin 似乎存在拼写错误(少了一个 't',应为 CooperationCorePlugin)。虽然这不影响本次 diff 的逻辑,但建议检查整个项目中的类名拼写一致性。

@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: lzwind, pppanghu77, re2zero

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

@re2zero re2zero merged commit c50b5ca into linuxdeepin:master Apr 28, 2026
18 of 21 checks passed
@re2zero re2zero deleted the fix/pms-355969-discovery-focus branch April 28, 2026 07:25
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