Files
sorrow404null bc0b92bcdc docs: add agent handoff docs, verification guide, and repair evidence
Add docs/agent-handoff (backlog, execution state, verification, platform plan, per-task evidence), repo AGENTS.md, and architecture notes updated for the dual-renderer design.
2026-09-17 16:40:06 +08:00

49 lines
5.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# P2-02 证据:右侧 Bash 面板滚动条与横纵交汇角
完成日期:2026-07-21(无人值守轮次)
结论:**完成**。右侧任务面板的代码框(`#bl_code`)与两栏 section 滚动区(`#bl_scroll`)滚动条统一为 8px、无箭头、handle 可见且 hover;横纵交汇角用 `QPlainTextEdit::corner` 子控件染成代码框背景 `#fbfcfe`,原生亮色 corner 方块消除。所有选择器均限定在 `#bl_code`/`#bl_scroll`,未添加任何无作用域的 `QScrollBar`/`QAbstractScrollArea` 规则。
## 交付物
| 文件 | 改动 |
|---|---|
| `ui/views/main_window.py` | 主窗口全局 QSS 中 `#bl_code` 规则后插入一段**完全限定作用域**的滚动条 + corner 规则(`QPlainTextEdit#bl_code QScrollBar:*``QPlainTextEdit#bl_code::corner``QScrollArea#bl_scroll QScrollBar:*``QScrollArea#bl_scroll::corner`);`#bl_code` 原有背景/边框/圆角/文本样式一字未动 |
| `tests/diag_panel_scrollbar.py` | 新建:离屏测量 + 断言 + 局部截图(面板全貌、代码框 render 图、角落 4x 放大) |
截图(`docs/agent-handoff/evidence/`):`p2-02-panel.png``p2-02-outbox-render.png``p2-02-codebox-corner-4x.png`
## 关键设计决策
1. **作用域 = objectName 限定,零全局规则。** 主窗口全局 QSS 此前没有任何 `QScrollBar` 规则(各弹窗/附件区各自 `setStyleSheet`),右侧面板因此落到原生 Windows 滚动条(带箭头、17px、亮色 corner 方块)。新增规则全部写成 `QPlainTextEdit#bl_code …` / `QScrollArea#bl_scroll …` 形式,只可能匹配右面板内的对象名,结构上不可能泄漏到其他控件。
2. **corner 用 `QAbstractScrollArea::corner` 子控件语法**`QPlainTextEdit#bl_code::corner { background-color: #fbfcfe; }`)——Qt 文档支持的子控件,与代码框背景同色,即 backlog「corner 与代码框背景一致」;未使用不存在的 `QScrollBar::corner`。section 滚动区 `::corner` 置透明(其横向滚动条恒关,corner 本不显示,属保险)。
3. **口径与仓库既有风格一致**8px 厚、`add-line/sub-line` 置 0 隐藏箭头、`#d0d0d0` handle + `#a0a0a0` hover、圆角 4px——与 `modern_scrollbar_qss` 及附件预览区风格同源,只是作用域不同。
## 验证(全部显式 timeout
| 套件 | 结果 | 预算 |
|---|---|---|
| `tests/diag_panel_scrollbar.py`(新) | **18 项 ALL PASS EXIT=0** | 180s |
| `tests/smoke_bash_panel.py` | **140 项 ALL PASS EXIT=0** | 240s |
| 回归 `tests/smoke_offscreen.py` | ALL PASS 8/8 EXIT=0 | 240s |
| 回归 `tests/run_tests.py` | 41/41 EXIT=0 | 300s |
| 回归 `smoke_timeline` / `smoke_midswitch` / `test_main_window_event_filter` | 11/11、7/7、ALL PASS,均 EXIT=0 | 各 ≤300s |
诊断脚本断言要点(对应 backlog「完成证据」):
- **厚度**:代码框横/纵滚动条实际几何 = 8px 且 `sizeHint` = 8pxS1/S1b/S2/S2b);section 竖滚动条实际 = 8pxS3);
- **箭头 extent**`subControlRect(CC_ScrollBar, SC_ScrollBarSubLine)` 在样式代理下 = 0(S4 三项)——即箭头子控件零尺寸;
- **corner**:代码框 `render()` 图中,右下角 8×8 交汇块渲染出 `#fbfcfe`9 px)、无 `(255,255,255)` 亮白像素(S5c/S5d);
- **无泄漏**:未命名 `QPlainTextEdit` 横滚动条仍为原生口径(14px,S6);附件预览滚动条保持自身 6px `sizeHint`S7);
- 截图三张落盘 evidence 目录,含角落 4x 放大图。
Windows 真机截图(backlog「完成证据」第二条):**已完成(2026-09-17Windows 11 真桌面,非 offscreen**`diag_panel_scrollbar.py` 直接运行 → EXIT=0、ALL PASS;实测代码框 H=8px V=8px、section V=8px、corner #fbfcfe 9 像素(与 offscreen 测量一致);三张截图已用真机渲染覆盖:`p2-02-panel.png``p2-02-outbox-render.png``p2-02-codebox-corner-4x.png`(07:20 时间戳)。运行期间生产 app 以 WebView2 在前台,diag 实例经 instance-lock 守卫自动回落 QtWebEngine,未误杀对方 WebView2 进程(T0 守卫真机验证)。Linux 真机截图仍待对应环境。
## 测试中发现的问题与教训
1. **offscreen 下 `widget.grab()` 对 `QPlainTextEdit` 的文档区不填充(黑图)**`out_box.grab()` 整块 (0,0,0),但 `panel.grab()` 正常。改用 `ob.render(painter)`(渲染到透明 QPixmap)后:文本色 `#243043`、边框 `#e6eaf2`、handle `#d0d0d0`、corner `#fbfcfe` 全部出现——**样式子控件在 offscreen 下正常渲染,只有文档区背景填充缺失**(离屏渲染怪癖,非产品 bug)。像素断言一律走 `render()`,且必须先做健全性检查(文本色/handle 色像素计数 > 0)防黑图假通过。
2. **PyQt6 API 坑(三连)**
- `Qt.Vertical`/`Qt.Horizontal` 短名已移除 → `Qt.Orientation.*`
- `QStyleOptionSlider(widget)` 构造器未绑定(只收无参/拷贝)→ 用 `QStyleOptionSlider()`
- `subControlRect` 参数序是 `(ComplexControl, QStyleOption, SubControl, widget)`,且滚动条箭头子控件在 PyQt6 枚举里叫 `SC_ScrollBarSubLine`/`SC_ScrollBarAddLine`(不是 C++ 文档里的 `SC_DownArrowButton`);`CC_ScrollBar` 属于 `QStyle.ComplexControl` 而非 `ControlElement`
- 裸控件(无样式表祖先)的 `style()` 是基础风格且空 option 下 `subControlRect` 返回 0 矩形——「原生参照」只能靠 `sizeHint`/实际几何(如原生横条 14px)对照,不能靠 subControlRect。
3. **测试数据**`out_box` 要同时出横纵滚动条,必须「超宽单行(NoWrap 触发横条)+ 足够行数(触发纵条)」,只给长单行时纵条不可见。