Repository navigation
ICC-CE_MainWindow_结构重构提案 #683
Description
检查清单 | Checklist
- 您确认此功能不存在于最新版本 | You confirm that this feature does not exist in the latest version.
- 您确认此功能有开发的必要 | You confirm that this feature is worth developing.
- 您确认此功能无法通过开发插件/自动化实现 | You confirm that this feature cannot be implemented through a plugin or automation.
- 您没有为软件提交 Pull Request 或开发插件的能力 | You are unable to submit a Pull Request or develop a plugin for this software.
- 您了解开发者无法及时回复和及时开发 | You understand that developers may not respond or implement features promptly.
- 我已经仔细阅读过选项里的内容,并且知道这个选项不用勾选。 | I have carefully read the options and know that this option does not need to be checked.
功能描述 | Description
> 声明:本 issue 由 AI 协助测绘与撰写,全部数据已由本人人工复核,PR 由本人提交并对内容负责。
> - [x] 您没有为软件提交 Pull Request 或开发插件的能力(我能提交 PR,此项按表单要求勾选,特此说明)
一句话功能描述
希望能把挤在 MainWindow 里的计时、截图、热键这些功能逐步拆成独立的小模块,让代码更好维护、bug 更容易排查,全程不改变大家用起来的任何感受。
总原则
- 纯结构重构,零行为变化。不改 UI、不改用户可感知的任何流程、不修 bug。过程中若发现疑似 bug,单独开 issue 记录,绝不顺手改——否则 diff 无法审查,回归无法归因。
- 小步快走:拆成可能约 12 个工作阶段,每阶段一个独立分支、一个独立 PR、可单独 revert,不与任何其他改动混在一起。
- 每阶段有明确门禁:构建零错误 + 受影响功能人工冒烟通过,才进入下一阶段;某阶段出问题,只回退该阶段。
需求动机 | Motivation
背景与动机
对 net10 主线做了一次较完整的代码测绘(以当前 1.8.0.9 为准,数字动工前会再复核):
MainWindow是一个巨型 partial 类:本体约 3,700 行,Ink Canvas/MainWindow_cs/下还有 58 个 partial 文件,合计约 5.8 万行。计时、截图、热键、托盘、通知、设置读写、PPT 集成都寄生在主窗体上;- 全库有 323 处空
catch(分布在 86 个文件),异常被静默吞掉——issue 区不少"玄学无法复现"的反馈(如 选择并拖拽墨迹后有概率导致墨迹始终处于可拖动状态 #662、在白板中选择并尝试缩放墨迹时墨迹异常 #654)与这种状态散落直接相关:不是没法修,是根本没有可诊断的信息; - 139 个文件直接引用
Dispatcher,线程归属靠约定而非结构保证; - 116 个辅助类平铺在 Helpers 目录下,没有按业务域划分。
带来的实际代价:修一个计时器问题要在一个 5 万行的类里干的昏天黑地;新贡献者很难安全地改代码;很多 bug 不是不能修,是不敢修。这次重构想解决的就是"不敢改"的问题。
期望设计 | Expected Design
阶段计划 | Plan
风险三档:🟢 机械操作、行为不变;🟡 结构移动、行为不变;🔴 涉及语义敏感区域的等价改写。
| 阶段 | 内容 | 风险 | PR 方式 |
|---|---|---|---|
| 1 | 重构规范文档 + 可复现的构建基线 | 🟢 | 随首个代码 PR 附带 |
| 2 | 文件名规范化(消灭文件名中的 &)与 MainWindow_cs 目录语义修正 |
🔴 blame 断裂 | 单独一个 PR,纯 git mv |
| 3 | csproj 语言版本对齐到 C# 12 | 🟢 | 可独立合入 |
| 4 | Helpers 按域分组(Ink / Ppt / Update / Security / UiShell) | 🟡 纯移动零改动 | 每域一个 PR |
| 5 | 从 MainWindow 提取低耦合服务:设置存储、托盘、通知、计时、截图、热键 | 🟡 | 每服务一个 PR |
| 6 | 工具模式从字符串比较改为强类型枚举(持久化格式原样不动) | 🟡 | 独立 PR |
| 7 | 323 处空 catch 分 5 批治理(记日志 / 重抛 / 注释说明为何吞) | 🟢 | 每批一个 PR,建议从这批开始审 |
| 8 | PPT 集成(MW_PPT.cs)逐步提取为独立服务 |
🔴 耦合最高 | 分段合入,先讨论 |
| 9 | ROTPPTManager(约 3,000 行)、AutoUpdateHelper(约 2,900 行)按职责拆 partial |
🟡 | 各一个 PR |
| 10 | 已提取服务中的 Dispatcher 直引收敛到统一调度入口 |
🔴 线程语义敏感 | 需讨论 |
| 11 | xUnit 测试项目 + 纯逻辑代码首批单元测试 | 🟢 | 一个 PR |
| 12 | 全量 diff 审计、Release 构建、冒烟清单、合入 | 🟢 | — |
完成后预期:MainWindow 体量下降 40% 以上,新增代码集中在 Services/ 下、与 UI 解耦、可单测。
三个高风险项,单独交代
这三处是改动最大、最容易出问题的地方,先说清楚做法和红线;任何一项如果不被认可,直接砍掉不影响其余阶段。
① 计时器服务化(阶段 5 的一部分)
把计时核心从 MW_Timer.cs(约 1,800 行)提取为独立的 TimerService:剩余时间、tick 递减、暂停语义收为不依赖 UI 的纯逻辑,窗口显隐留在主窗体。
红线:定时器类型原样搬移,不做 DispatcherTimer 与线程池 Timer 之间的互换(那是线程来源变化,不是等价改写);Tick 里碰 UI 的点统一收拢到入口方法,替换前后逐一核对。
预期收益:现在"暂停后 Tick 泄漏""停止后回调重入"这类隐患只能靠自觉避免,服务化后"任何时刻至多一个活跃 Tick"由结构保证。
验证:构建通过 + 服务内 Dispatcher/MainWindow 引用为零 + 新旧实现跑同一组计时场景(开始 → 运行 → 暂停 → 继续 → 结束)剩余时间序列逐秒一致,验证记录随 PR 附上。
② 文件改名(阶段 2)
代价是 git blame 在这些文件上断裂。补偿措施:纯 git mv,一个 commit 都不夹带逻辑改动,git log --follow 可以追历史;整个改名独立成一个 PR,方便一次性决定接受或拒绝。
③ Dispatcher 收敛(阶段 10)
只把已提取服务里直接引用 Dispatcher 的 UI 更新点改走统一调度入口——只换调用路径,不动线程模型;每一处替换都可以独立 revert。
测试承诺
严格遵守 CONTRIBUTING.md 中对大规模重构的全部要求:
- 每个 PR 附 Release 构建通过证明;
- 对重构涉及的功能做完整测试(UI 改动按三步法:样式、行为、i18n);
- 对所有变更点做回归可能性检查;
- 测试中发现的问题逐 commit 核对、针对性修复,不盲目改、不带病合入;
- 每个 PR 附人工冒烟清单(画板、墨迹、橡皮、PPT 模式、计时器、截图、热键等实际受影响的面)。
边界与取舍
- 主动不做:不碰 UI 视觉体系统一(那是 [Feature Request] UI界面风格统一 #644 的范围)、不碰设置页信息架构([Feature Request] 设置页面规范处理 #642)、不做任何行为修复——与这两条 issue 正交,留给他们各自的方案。
- 已知代价:目录结构变化会给在途 PR 制造合并冲突窗口,建议挑发版后的空窗期开始,或按维护者指定的节奏推进。
- 数字口径:上文行数基于 1.8.0.4–1.8.0.9 期间的测绘,动工前会对当时 net10 最新 commit 重新复核并在第一个 PR 中给出确切数字。
请维护者拍板
- 按上表的颗粒度逐阶段提 PR 是否合适?还是更希望压缩成少数几个大 PR?
- 阶段 2 的改名 PR,能否接受 blame 断裂的代价?
- 三个高风险项(计时器、PPT 拆分、Dispatcher 收敛)是否需要先做小范围试点再展开?
- 什么时间窗口开始比较合适(避开在途 PR 冲突)?
没有回复的话,我默认按"先提阶段 7 空 catch 治理的第一批 PR 试水"起步——它风险最低、收益最直接,也正好验证协作流程。
其他补充信息 | Additional Info
No response
上传有关文件 | Upload relevant files
No response
Activity
HAILVa1kyrie commentedon Oct 3, 2026
已按默认交付第一批(阶段 1–7),见 #692
wwiinnddyy commentedon Oct 10, 2026
mainwindows已经拆过一次,全部模块化会导致启动速度过慢与较大资源占用
HAILVa1kyrie commentedon Oct 11, 2026