Skip to content
This repository was archived by the owner on Mar 23, 2026. It is now read-only.

feat: 在交互窗口后重新激活先前的窗口#924

Merged
IsHPDuwu merged 11 commits into
Class-Widgets:mainfrom
IsHPDuwu:feat/foreground.give_back
Sep 13, 2025
Merged

feat: 在交互窗口后重新激活先前的窗口#924
IsHPDuwu merged 11 commits into
Class-Widgets:mainfrom
IsHPDuwu:feat/foreground.give_back

Conversation

@IsHPDuwu

@IsHPDuwu IsHPDuwu commented Sep 6, 2025

Copy link
Copy Markdown
Member

close #923

@baiyao105 baiyao105 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

1.焦点竞争
2.windows only

@IsHPDuwu

IsHPDuwu commented Sep 6, 2025

Copy link
Copy Markdown
Member Author

1.焦点竞争 2.windows only

对于 1 ?

对于 2 确实 windows only

@baiyao105

Copy link
Copy Markdown
Member

1.焦点竞争 2.windows only

对于 1 ?

对于 2 确实 windows only

1.需要可被打断
2.那你心还这么大。

@IsHPDuwu

IsHPDuwu commented Sep 6, 2025

Copy link
Copy Markdown
Member Author

1.焦点竞争 2.windows only

对于 1 ?
对于 2 确实 windows only

1.需要可被打断 2.那你心还这么大。

你的意思是在调用 restore 的时候可能被其他程序打断也就是 e.g. 在同时手动把焦点转移到另一个程序上而 restore 又使其切回了原来的程序对吧

还有 windows only 心哪大了

@baiyao105

Copy link
Copy Markdown
Member

1.焦点竞争 2.windows only

对于 1 ?
对于 2 确实 windows only

1.需要可被打断 2.那你心还这么大。

你的意思是在调用 restore 的时候可能被其他程序打断也就是 e.g. 在同时手动把焦点转移到另一个程序上而 restore 又使其切回了原来的程序对吧

还有 windows only 心哪大了

那你if去哪了。

@ChimeYao-bot ChimeYao-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

PR Review

该 PR 的目标是:在与交互窗口(小组件/浮窗)交互后,恢复前一个活动窗口至前台。整体思路合理,但有几个问题需要优化和修复(按严重性排序):

1. 致命问题:focus_managerNone 导致崩溃

  • 问题main.py 中多处使用 QTimer.singleShot 调用时,focus_manager 可能尚未初始化,导致 AttributeError

  • 建议

    • lambda 内加 focus_manager 存在性检查:if focus_manager: focus_manager.ignore.emit(...)
    • 或者提前初始化 focus_manager

2. 资源泄漏:忽略集合无限增长

  • 问题PreviousWindowFocusManager.ignore_hwnds 使用 set 存储窗口句柄,但没有移除,导致句柄堆积。

  • 建议

    • 在窗口销毁时移除句柄,或使用定时器延时移除:QTimer.singleShot(2000, lambda h=hwnd: focus_manager.ignore_hwnds.discard(h))

3. 跨平台兼容性问题

  • 问题PreviousWindowFocusManager 在非 Windows 系统上也被定义,可能导致维护问题。

  • 建议

    • PreviousWindowFocusManager 的定义放入 Windows 平台判断内,或在初始化时抛出 PlatformNotSupported 错误。

4. 恢复焦点不稳定(Windows 限制)

  • 问题win32gui.SetForegroundWindow 在现代 Windows 系统中常受“前台窗口限制”影响,可能无法成功恢复焦点。

  • 建议

    • 使用附加手段如 AttachThreadInputShowWindow/SetWindowPos,或模拟 Alt+Tab 来提高成功率。

5. 逻辑及可读性问题

  • 问题_do_restore 中的判断 current_hwnd not in self.ignore_hwnds: return 可能导致误解。
  • 建议:添加注释,解释其意图:仅在当前前台窗口是需要忽略的窗口时,才尝试恢复焦点。

6. 性能问题:高频轮询

  • 问题PreviousWindowFocusManager 每 100ms 调用一次 win32gui.GetForegroundWindow,对性能有影响。

  • 建议

    • 使用 Windows 事件回调(如 SetWinEventHook)代替高频轮询,或仅在需要时启用定时器。

7. 信号一致性问题

  • 问题:在某些地方使用 if focus_manager: 检查,部分地方没有。
  • 建议:统一在所有 ignore.emitrestoreRequested.emit 前做存在性检查。

8. 代码风格及日志

  • 问题_do_restore 中的 print 应改为 logger.error,便于排查。
  • 建议:添加更多 logger.debug,记录 ignore_hwnd 的变化以及恢复焦点的成功与失败。

9. 其他

  • 程序退出时,调用 focus_manager.stop() 停止定时器,避免线程泄漏。

总结建议

  • 修复:修正 singleShot 中的 lambda,提前检查 focus_manager 是否存在,或调整创建顺序。
  • 优化:移除忽略集合中的无用句柄,并避免高频轮询,改用事件驱动。
  • 兼容性:限制 PreviousWindowFocusManager 仅在 Windows 平台使用,增加错误处理。

@ChimeYao-bot ChimeYao-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

当前代码兼容性良好,非 Windows 平台不会报错。

推荐的兼容性做法

  • 如需更保险,可在非 Windows 下赋值一个 Dummy 类(空类),即使误用也不会报错。

@baiyao105 baiyao105 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

如果可以其实可以加到update_timer(存疑?

if system == 'Windows':
    focus_manager = utils.PreviousWindowFocusManager()
    update_timer.add_callback(focus_manager.store)

@baiyao105 baiyao105 added the test/required/Linux 需要在Linux系统中进行测试 label Sep 13, 2025
@IsHPDuwu IsHPDuwu merged commit a24cf8c into Class-Widgets:main Sep 13, 2025
8 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

test/required/Linux 需要在Linux系统中进行测试

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE]: 在交互窗口后重新激活先前交互的窗口

3 participants